From db30f920cc87e994abee9af7e96553ff51549681 Mon Sep 17 00:00:00 2001 From: SondreB Date: Fri, 15 May 2020 18:22:07 +0200 Subject: [PATCH] Update Blockcore Features to latest packages - The API for BlockExplorer might not properly render or will be included with the others, since versioning support has been removed from the new NodeHost. --- .github/workflows/build.yml | 2 +- .../Blockcore.Features.Airdrop.csproj | 8 +- Blockcore.Features.Airdrop/Distribute.cs | 359 +++++++++--------- .../Blockcore.Features.BlockExplorer.csproj | 4 +- .../Controllers/TransactionStoreController.cs | 67 ---- .../Blockcore.Features.WalletNotify.csproj | 4 +- CHANGELOG.md | 19 + Directory.Build.props | 2 +- package-lock.json | 4 + package.json | 51 ++- 10 files changed, 238 insertions(+), 282 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 package-lock.json diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ec07b95..0fd9a95 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -56,5 +56,5 @@ jobs: draft: true prerelease: false body: '' - name: "Blockcore ${{env.VERSION}}" + name: "Blockcore Features ${{env.VERSION}}" tag: ${{env.VERSION}} \ No newline at end of file diff --git a/Blockcore.Features.Airdrop/Blockcore.Features.Airdrop.csproj b/Blockcore.Features.Airdrop/Blockcore.Features.Airdrop.csproj index 4d17840..6ab98da 100644 --- a/Blockcore.Features.Airdrop/Blockcore.Features.Airdrop.csproj +++ b/Blockcore.Features.Airdrop/Blockcore.Features.Airdrop.csproj @@ -10,11 +10,11 @@ - + - - - + + + diff --git a/Blockcore.Features.Airdrop/Distribute.cs b/Blockcore.Features.Airdrop/Distribute.cs index cbeff5b..58bd30c 100644 --- a/Blockcore.Features.Airdrop/Distribute.cs +++ b/Blockcore.Features.Airdrop/Distribute.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Threading; @@ -20,204 +20,207 @@ using Blockcore.Features.Wallet.Interfaces; using Blockcore.Interfaces; using Blockcore.Features.Wallet; +using Blockcore.Features.Wallet.Types; namespace Blockcore.Features.Airdrop { - public class Distribute - { - private readonly Network network; - private readonly INodeLifetime nodeLifetime; - private readonly AirdropSettings airdropSettings; - private readonly NodeSettings nodeSettings; - private readonly IWalletManager walletManager; - private readonly IWalletTransactionHandler walletTransactionHandler; - private readonly IBroadcasterManager broadcasterManager; - private readonly IBlockStore blockStore; - private readonly ILogger logger; - - private UtxoContext utxoContext; - - public Distribute(Network network, INodeLifetime nodeLifetime, ILoggerFactory loggerFactory, AirdropSettings airdropSettings, NodeSettings nodeSettings, IWalletManager walletManager, IWalletTransactionHandler walletTransactionHandler, IBroadcasterManager broadcasterManager, IBlockStore blockStore) - { - this.network = network; - this.nodeLifetime = nodeLifetime; - this.airdropSettings = airdropSettings; - this.nodeSettings = nodeSettings; - this.walletManager = walletManager; - this.walletTransactionHandler = walletTransactionHandler; - this.broadcasterManager = broadcasterManager; - this.blockStore = blockStore; - - this.logger = loggerFactory.CreateLogger(this.GetType().FullName); - } - - public void Initialize() - { - this.utxoContext = new UtxoContext(this.nodeSettings.DataDir, this.airdropSettings.SnapshotHeight.Value); - this.utxoContext.Database.EnsureCreated(); - } - - public Task DistributeCoins(CancellationToken arg) - { - // Check for invalid db states - if (this.utxoContext.DistributeOutputs.Any(d => - d.Status == DistributeStatus.Started || - d.Status == DistributeStatus.Failed)) - { - this.logger.LogError("database is in an invalid state"); - return Task.CompletedTask; - } + public class Distribute + { + private readonly Network network; + private readonly INodeLifetime nodeLifetime; + private readonly AirdropSettings airdropSettings; + private readonly NodeSettings nodeSettings; + private readonly IWalletManager walletManager; + private readonly IWalletTransactionHandler walletTransactionHandler; + private readonly IBroadcasterManager broadcasterManager; + private readonly IBlockStore blockStore; + private readonly ILogger logger; + + private UtxoContext utxoContext; + + public Distribute(Network network, INodeLifetime nodeLifetime, ILoggerFactory loggerFactory, AirdropSettings airdropSettings, NodeSettings nodeSettings, IWalletManager walletManager, IWalletTransactionHandler walletTransactionHandler, IBroadcasterManager broadcasterManager, IBlockStore blockStore) + { + this.network = network; + this.nodeLifetime = nodeLifetime; + this.airdropSettings = airdropSettings; + this.nodeSettings = nodeSettings; + this.walletManager = walletManager; + this.walletTransactionHandler = walletTransactionHandler; + this.broadcasterManager = broadcasterManager; + this.blockStore = blockStore; + + logger = loggerFactory.CreateLogger(GetType().FullName); + } + + public void Initialize() + { + utxoContext = new UtxoContext(nodeSettings.DataDir, airdropSettings.SnapshotHeight.Value); + utxoContext.Database.EnsureCreated(); + } + + public Task DistributeCoins(CancellationToken arg) + { + // Check for invalid db states + if (utxoContext.DistributeOutputs.Any(d => + d.Status == DistributeStatus.Started || + d.Status == DistributeStatus.Failed)) + { + logger.LogError("database is in an invalid state"); + return Task.CompletedTask; + } - // Check for distributed trx still in progress (unconfirmed yet) - var inProgress = this.utxoContext.DistributeOutputs.Where(d => d.Status == DistributeStatus.InProgress); + // Check for distributed trx still in progress (unconfirmed yet) + IQueryable inProgress = utxoContext.DistributeOutputs.Where(d => d.Status == DistributeStatus.InProgress); - if (inProgress.Any()) + if (inProgress.Any()) + { + bool foundTrxNotInBlock = false; + foreach (UTXODistribute utxoDistribute in inProgress) { - bool foundTrxNotInBlock = false; - foreach (var utxoDistribute in inProgress) - { - var trx = this.blockStore?.GetTransactionById(new uint256(utxoDistribute.Trxid)); - - if (trx == null) - { - foundTrxNotInBlock = true; - } - else - { - utxoDistribute.Status = DistributeStatus.Complete; - } - } - - this.utxoContext.SaveChanges(true); - - if(foundTrxNotInBlock) - return Task.CompletedTask; + Transaction trx = blockStore?.GetTransactionById(new uint256(utxoDistribute.Trxid)); + + if (trx == null) + { + foundTrxNotInBlock = true; + } + else + { + utxoDistribute.Status = DistributeStatus.Complete; + } } - // MANUAL: this part must be manually changed - var walletName = "wal"; - var accountName = "account 0"; - var password = "123456"; + utxoContext.SaveChanges(true); - var accountReference = new WalletAccountReference(walletName, accountName); + if (foundTrxNotInBlock) + return Task.CompletedTask; + } - var progress = this.utxoContext.DistributeOutputs.Any(d => - d.Status == DistributeStatus.Started || - d.Status == DistributeStatus.InProgress || - d.Status == DistributeStatus.Failed); - - if (progress) - { - this.logger.LogError("database is in an invalid state"); - return Task.CompletedTask; - } + // MANUAL: this part must be manually changed + string walletName = "wal"; + string accountName = "account 0"; + string password = "123456"; + + var accountReference = new WalletAccountReference(walletName, accountName); + + bool progress = utxoContext.DistributeOutputs.Any(d => + d.Status == DistributeStatus.Started || + d.Status == DistributeStatus.InProgress || + d.Status == DistributeStatus.Failed); + + if (progress) + { + logger.LogError("database is in an invalid state"); + return Task.CompletedTask; + } + + IQueryable outputs = utxoContext.DistributeOutputs.Where(d => d.Status == null || d.Status == DistributeStatus.NoStarted).Take(100); + + if (!outputs.Any()) + return Task.CompletedTask; - var outputs = this.utxoContext.DistributeOutputs.Where(d => d.Status == null || d.Status == DistributeStatus.NoStarted).Take(100); + List dbOutputs = new List(); - if(!outputs.Any()) - return Task.CompletedTask; + // mark the database items as started + foreach (UTXODistribute utxoDistribute in outputs) + { + utxoDistribute.Status = DistributeStatus.Started; + dbOutputs.Add(utxoDistribute); + } - List dbOutputs = new List(); + utxoContext.SaveChanges(true); - // mark the database items as started - foreach (UTXODistribute utxoDistribute in outputs) + try + { + var recipients = new List(); + foreach (UTXODistribute utxoDistribute in dbOutputs) { - utxoDistribute.Status = DistributeStatus.Started; - dbOutputs.Add(utxoDistribute); + try + { + // MANUAL: this part must be manually changed + + if (string.IsNullOrEmpty(utxoDistribute.Address)) + continue; + + // convert the script to the target address + Script script = BitcoinAddress.Create(utxoDistribute.Address, network).ScriptPubKey; + Script target = null; + + TxDestination destination = script.GetDestination(network); + if (destination != null) + { + var wit = new BitcoinWitPubKeyAddress(new WitKeyId(destination.ToBytes()), network); + + target = PayToWitPubKeyHashTemplate.Instance.GenerateScriptPubKey(wit); + } + else + { + PubKey[] pubkeys = script.GetDestinationPublicKeys(network); + + target = pubkeys[0].GetSegwitAddress(network).ScriptPubKey; + } + + // Apply any ratio to the value. + long amount = utxoDistribute.Value; + + amount = amount / 10; + + recipients.Add(new Recipient + { + ScriptPubKey = target, + Amount = amount + }); + } + catch (Exception e) + { + utxoDistribute.Error = e.Message; + utxoDistribute.Status = DistributeStatus.Failed; + utxoContext.SaveChanges(true); + return Task.CompletedTask; + } } - this.utxoContext.SaveChanges(true); + HdAddress change = walletManager.GetUnusedChangeAddress(accountReference); - try + var context = new TransactionBuildContext(network) { - var recipients = new List(); - foreach (UTXODistribute utxoDistribute in dbOutputs) - { - try - { - // MANUAL: this part must be manually changed - - if(string.IsNullOrEmpty(utxoDistribute.Address)) - continue; - - // convert the script to the target address - Script script = BitcoinAddress.Create(utxoDistribute.Address, this.network).ScriptPubKey; - Script target = null; - - TxDestination destination = script.GetDestination(this.network); - if (destination != null) - { - var wit = new BitcoinWitPubKeyAddress(new WitKeyId(destination.ToBytes()), this.network); - - target = PayToWitPubKeyHashTemplate.Instance.GenerateScriptPubKey(wit); - } - else - { - var pubkeys = script.GetDestinationPublicKeys(this.network); - - target = pubkeys[0].GetSegwitAddress(this.network).ScriptPubKey; - } - - // Apply any ratio to the value. - var amount = utxoDistribute.Value; - - amount = amount / 10; - - recipients.Add(new Recipient - { - ScriptPubKey = target, - Amount = amount - }); - } - catch (Exception e) - { - utxoDistribute.Error = e.Message; - utxoDistribute.Status = DistributeStatus.Failed; - this.utxoContext.SaveChanges(true); - return Task.CompletedTask; - } - } - - HdAddress change = this.walletManager.GetUnusedChangeAddress(accountReference); - - var context = new TransactionBuildContext(this.network) - { - AccountReference = accountReference, - MinConfirmations = 0, - WalletPassword = password, - Recipients = recipients, - ChangeAddress = change, - UseSegwitChangeAddress = true, - FeeType = FeeType.Low - }; - - Transaction transactionResult = this.walletTransactionHandler.BuildTransaction(context); - uint256 trxHash = transactionResult.GetHash(); - - // broadcast to the network - this.broadcasterManager.BroadcastTransactionAsync(transactionResult); - - // mark the database items as in progress - foreach (UTXODistribute utxoDistribute in dbOutputs) - { - utxoDistribute.Status = DistributeStatus.InProgress; - utxoDistribute.Trxid = trxHash.ToString(); - } - - this.utxoContext.SaveChanges(true); + AccountReference = accountReference, + MinConfirmations = 0, + WalletPassword = password, + Recipients = recipients, + ChangeAddress = change, + UseSegwitChangeAddress = true, + FeeType = FeeType.Low + }; + + Transaction transactionResult = walletTransactionHandler.BuildTransaction(context); + uint256 trxHash = transactionResult.GetHash(); + + // broadcast to the network + broadcasterManager.BroadcastTransactionAsync(transactionResult); + + // mark the database items as in progress + foreach (UTXODistribute utxoDistribute in dbOutputs) + { + utxoDistribute.Status = DistributeStatus.InProgress; + utxoDistribute.Trxid = trxHash.ToString(); } - catch (Exception e) + + utxoContext.SaveChanges(true); + } + catch (Exception e) + { + foreach (UTXODistribute utxoDistribute in dbOutputs) { - foreach (UTXODistribute utxoDistribute in dbOutputs) - { - utxoDistribute.Error = e.Message; - utxoDistribute.Status = DistributeStatus.Failed; - } - this.utxoContext.SaveChanges(true); - return Task.CompletedTask; + utxoDistribute.Error = e.Message; + utxoDistribute.Status = DistributeStatus.Failed; } + utxoContext.SaveChanges(true); + return Task.CompletedTask; - } - } -} \ No newline at end of file + } + + return Task.CompletedTask; + } + } +} diff --git a/Blockcore.Features.BlockExplorer/Blockcore.Features.BlockExplorer.csproj b/Blockcore.Features.BlockExplorer/Blockcore.Features.BlockExplorer.csproj index c33f928..78abba5 100644 --- a/Blockcore.Features.BlockExplorer/Blockcore.Features.BlockExplorer.csproj +++ b/Blockcore.Features.BlockExplorer/Blockcore.Features.BlockExplorer.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/Blockcore.Features.BlockExplorer/Controllers/TransactionStoreController.cs b/Blockcore.Features.BlockExplorer/Controllers/TransactionStoreController.cs index bcde153..077e15e 100644 --- a/Blockcore.Features.BlockExplorer/Controllers/TransactionStoreController.cs +++ b/Blockcore.Features.BlockExplorer/Controllers/TransactionStoreController.cs @@ -13,9 +13,7 @@ using Blockcore.Controllers.Models; using Blockcore.Features.BlockStore; using Blockcore.Features.BlockStore.Models; -using Blockcore.Features.Wallet.Broadcasting; using Blockcore.Features.Wallet.Interfaces; -using Blockcore.Features.Wallet.Models; using Blockcore.Interfaces; using Blockcore.Utilities; using Blockcore.Utilities.JsonErrors; @@ -160,70 +158,5 @@ public async Task GetTransactionAsync(string id) return ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()); } } - - ///// - ///// Sends a transaction. - ///// - ///// The hex representing the transaction. - ///// - //[Route("retry-transaction")] - //[HttpPost] - //public IActionResult RetryTransaction([FromBody] BroadcastTransactionModel request) - //{ - // //Guard.NotNull(request, nameof(request)); - - // //// checks the request is valid - // //if (!this.ModelState.IsValid) - // //{ - // // return ModelStateErrors.BuildErrorResponse(this.ModelState); - // //} - - // //if (!this.connectionManager.ConnectedPeers.Any()) - // //{ - // // this.logger.LogTrace("(-)[NO_CONNECTED_PEERS]"); - // // return ErrorHelpers.BuildErrorResponse(HttpStatusCode.Forbidden, "Can't send transaction: sending transaction requires at least one connection!", string.Empty); - // //} - - // //try - // //{ - // // IEnumerable accountsHistory = this.walletManager.GetHistory(request.WalletName, request.AccountName); - - // // Transaction transaction = this.network.CreateTransaction(request.Hex); - - // // var model = new WalletSendTransactionModel - // // { - // // TransactionId = transaction.GetHash(), - // // Outputs = new List() - // // }; - - // // foreach (TxOut output in transaction.Outputs) - // // { - // // bool isUnspendable = output.ScriptPubKey.IsUnspendable; - // // model.Outputs.Add(new TransactionOutputModel - // // { - // // Address = isUnspendable ? null : output.ScriptPubKey.GetDestinationAddress(this.network).ToString(), - // // Amount = output.Value, - // // OpReturnData = isUnspendable ? Encoding.UTF8.GetString(output.ScriptPubKey.ToOps().Last().PushData) : null - // // }); - // // } - - // // this.broadcasterManager.BroadcastTransactionAsync(transaction).GetAwaiter().GetResult(); - - // // TransactionBroadcastEntry transactionBroadCastEntry = this.broadcasterManager.GetTransaction(transaction.GetHash()); - - // // if (!string.IsNullOrEmpty(transactionBroadCastEntry?.ErrorMessage)) - // // { - // // this.logger.LogError("Exception occurred: {0}", transactionBroadCastEntry.ErrorMessage); - // // return ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, transactionBroadCastEntry.ErrorMessage, "Transaction Exception"); - // // } - - // // return this.Json(model); - // //} - // //catch (Exception e) - // //{ - // // this.logger.LogError("Exception occurred: {0}", e.ToString()); - // // return ErrorHelpers.BuildErrorResponse(HttpStatusCode.BadRequest, e.Message, e.ToString()); - // //} - //} } } diff --git a/Blockcore.Features.WalletNotify/Blockcore.Features.WalletNotify.csproj b/Blockcore.Features.WalletNotify/Blockcore.Features.WalletNotify.csproj index 14baedc..e3ac462 100644 --- a/Blockcore.Features.WalletNotify/Blockcore.Features.WalletNotify.csproj +++ b/Blockcore.Features.WalletNotify/Blockcore.Features.WalletNotify.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..82bcd8c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +## (2020-05-15) + + + + +## 1.0.0 (2020-04-24) + +* Add action workflows and update features ([5d1b217](https://github.com/block-core/blockcore-features/commit/5d1b217)) +* Add description for WalletNotify feature ([f37e77c](https://github.com/block-core/blockcore-features/commit/f37e77c)) +* Add WalletNotify Feature ([a890310](https://github.com/block-core/blockcore-features/commit/a890310)) +* Adding the airdrop feature ([6d0854d](https://github.com/block-core/blockcore-features/commit/6d0854d)) +* Initial commit ([602f502](https://github.com/block-core/blockcore-features/commit/602f502)) +* Update Features to use released NuGet packages ([28db8c5](https://github.com/block-core/blockcore-features/commit/28db8c5)) +* Update readme.md ([1bca355](https://github.com/block-core/blockcore-features/commit/1bca355)) +* Update README.md ([f65193a](https://github.com/block-core/blockcore-features/commit/f65193a)) +* Update README.md ([5846734](https://github.com/block-core/blockcore-features/commit/5846734)) + + + diff --git a/Directory.Build.props b/Directory.Build.props index 03e622f..e1560e2 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - 1.0.0 + 1.0.1 3.1.0 netcoreapp3.1 true diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..4af9581 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4 @@ +{ + "name": "blockcorefeatures", + "lockfileVersion": 1 +} diff --git a/package.json b/package.json index f5e84aa..bdbc929 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,25 @@ { - "name": "blockcorefeatures", - "license": "MIT", - "author": { - "name": "Blockcore", - "email": "post@blockcore.net", - "url": "https://www.blockcore.net" - }, - "description": "", - "repository": { - "type": "git", - "url": "git+https://github.com/block-core/blockcore-features.git" - }, - "bugs": { - "url": "https://github.com/block-core/blockcore-features/issues" - }, - "homepage": "https://github.com/block-core/blockcore-features#readme", - "scripts": { - "version": "node version.js", - "changelog": "conventional-changelog -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md" - }, - "private": true, - "dependencies": { - "conventional-changelog-cli": "2.0.31" - }, - "devDependencies": {} - } - \ No newline at end of file + "name": "blockcorefeatures", + "license": "MIT", + "author": { + "name": "Blockcore", + "email": "post@blockcore.net", + "url": "https://www.blockcore.net" + }, + "description": "", + "repository": { + "type": "git", + "url": "git+https://github.com/block-core/blockcore-features.git" + }, + "bugs": { + "url": "https://github.com/block-core/blockcore-features/issues" + }, + "homepage": "https://github.com/block-core/blockcore-features#readme", + "scripts": { + "version": "node version.js", + "changelog": "conventional-changelog -i CHANGELOG.md -s -r 0 && git add CHANGELOG.md" + }, + "private": true, + "dependencies": {}, + "devDependencies": {} +}