From f7107ea7331bbf9c025e63c236d78cdd862e9817 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Wed, 19 Aug 2020 15:36:47 +0100 Subject: [PATCH 01/16] WIP --- .../ColdStakingControllerTest.cs | 15 +++-- .../TransactionAddedToMemoryPool.cs | 2 +- .../SmartContractTransactionServiceTests.cs | 66 +++++++++++++------ .../Wallet/SmartContractTransactionService.cs | 45 +++++++++---- .../SmartContractWalletTransactionHandler.cs | 6 +- .../WalletTransactionHandlerTest.cs | 38 ++++++++--- .../Services/IWalletService.cs | 3 +- .../Services/ReserveUtxoService.cs | 55 ++++++++++++++++ .../Services/WalletService.cs | 27 ++++---- .../WalletFeature.cs | 34 +++++----- .../WalletSyncManager.cs | 5 +- .../WalletTransactionHandler.cs | 26 ++++---- 12 files changed, 220 insertions(+), 102 deletions(-) create mode 100644 src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs diff --git a/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs b/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs index 0c1b69e9cc..a9bd027285 100644 --- a/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs +++ b/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs @@ -28,6 +28,7 @@ using Stratis.Bitcoin.Features.MemoryPool.Rules; using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Features.Wallet.Interfaces; +using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.Bitcoin.Signals; using Stratis.Bitcoin.Tests.Common; using Stratis.Bitcoin.Utilities; @@ -217,15 +218,18 @@ private void Initialize([System.Runtime.CompilerServices.CallerMemberName] strin var scriptDestinationReader = new ColdStakingDestinationReader(new ScriptAddressReader()); - IWalletRepository walletRepository = new SQLiteWalletRepository(this.loggerFactory, this.nodeSettings.DataFolder, this.Network, DateTimeProvider.Default, scriptDestinationReader); - walletRepository.TestMode = true; + IWalletRepository walletRepository = new SQLiteWalletRepository(this.loggerFactory, this.nodeSettings.DataFolder, this.Network, DateTimeProvider.Default, scriptDestinationReader) + { + TestMode = true + }; this.coldStakingManager = new ColdStakingManager(this.Network, new ChainIndexer(this.Network), walletSettings, this.nodeSettings.DataFolder, new Mock().Object, new Mock().Object, new NodeLifetime(), scriptDestinationReader, this.loggerFactory, DateTimeProvider.Default, walletRepository); - var walletTransactionHandler = new WalletTransactionHandler(this.loggerFactory, this.coldStakingManager, - new Mock().Object, this.Network, new StandardTransactionPolicy(this.Network)); + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.loggerFactory, this.coldStakingManager, new Mock().Object, this.Network, new StandardTransactionPolicy(this.Network), reserveUtxoService); this.coldStakingController = new ColdStakingController(this.loggerFactory, this.coldStakingManager, walletTransactionHandler); @@ -281,9 +285,6 @@ public void ColdStakingVerifyWalletAddresses() this.coldStakingManager.GetOrCreateColdStakingAccount(walletName2, true, walletPassword); this.coldStakingManager.GetOrCreateColdStakingAccount(walletName2, false, walletPassword); - var wallet1 = this.coldStakingManager.GetWallet(walletName1); - var wallet2 = this.coldStakingManager.GetWallet(walletName2); - HdAddress coldAddress1 = this.coldStakingManager.GetFirstUnusedColdStakingAddress(walletName1, true); HdAddress hotAddress1 = this.coldStakingManager.GetFirstUnusedColdStakingAddress(walletName1, false); HdAddress coldAddress2 = this.coldStakingManager.GetFirstUnusedColdStakingAddress(walletName2, true); diff --git a/src/Stratis.Bitcoin.Features.MemoryPool/TransactionAddedToMemoryPool.cs b/src/Stratis.Bitcoin.Features.MemoryPool/TransactionAddedToMemoryPool.cs index ccbcd95985..7421b3c497 100644 --- a/src/Stratis.Bitcoin.Features.MemoryPool/TransactionAddedToMemoryPool.cs +++ b/src/Stratis.Bitcoin.Features.MemoryPool/TransactionAddedToMemoryPool.cs @@ -6,7 +6,7 @@ namespace Stratis.Bitcoin.Features.MemoryPool /// /// Event that is executed when a transaction is removed from the mempool. /// - /// + /// public class TransactionAddedToMemoryPool : EventBase { public Transaction AddedTransaction { get; } diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs index 251eda7ed9..52019a4631 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using CSharpFunctionalExtensions; +using Microsoft.Extensions.Logging; using Moq; using NBitcoin; using Stratis.Bitcoin.Features.SmartContracts.Models; @@ -8,7 +9,8 @@ using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Features.Wallet.Interfaces; using Stratis.Bitcoin.Features.Wallet.Models; -using Stratis.Sidechains.Networks; +using Stratis.Bitcoin.Features.Wallet.Services; +using Stratis.Bitcoin.Signals; using Stratis.SmartContracts.CLR; using Stratis.SmartContracts.CLR.Serialization; using Stratis.SmartContracts.Core.State; @@ -113,18 +115,21 @@ public void CanChooseInputsForCall() this.walletManager.Setup(x => x.GetWallet(request.WalletName)) .Returns(wallet); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); BuildCallContractTransactionResponse result = service.BuildCallTx(request); - this.walletTransactionHandler.Verify(x=>x.BuildTransaction(It.Is(y =>y.SelectedInputs.Count == 1))); + this.walletTransactionHandler.Verify(x => x.BuildTransaction(It.Is(y => y.SelectedInputs.Count == 1))); } [Fact] @@ -193,14 +198,17 @@ public void ChoosingInvalidInputFails() } }); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); BuildCallContractTransactionResponse result = service.BuildCallTx(request); Assert.False(result.Success); @@ -274,23 +282,26 @@ public void CanChooseInputsForCreate() var wallet = new Features.Wallet.Wallet(); wallet.AccountsRoot.Add(new AccountRoot(wallet)); - var account0 = new HdAccount(wallet.AccountsRoot.First().Accounts) { Name = request.AccountName };; + var account0 = new HdAccount(wallet.AccountsRoot.First().Accounts) { Name = request.AccountName }; ; account0.ExternalAddresses.Add(new HdAddress() { Address = senderAddress }); this.walletManager.Setup(x => x.GetWallet(request.WalletName)) .Returns(wallet); this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny())) - .Returns(Result.Ok(new ContractTxData(1, 100, (Gas) 100_000, new byte[0]))); + .Returns(Result.Ok(new ContractTxData(1, 100, (Gas)100_000, new byte[0]))); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); BuildCreateContractTransactionResponse result = service.BuildCreateTx(request); @@ -302,14 +313,17 @@ public void BuildTransferContext_SenderNotInWallet_Fails() { string senderAddress = uint160.Zero.ToBase58Address(this.network); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); var request = new BuildContractTransactionRequest { @@ -339,14 +353,17 @@ public void BuildTransferContext_AccountNotInWallet_Fails() { string senderAddress = uint160.Zero.ToBase58Address(this.network); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); var request = new BuildContractTransactionRequest { @@ -376,14 +393,17 @@ public void BuildTransferContext_SenderHasNoBalance_Fails() { string senderAddress = uint160.Zero.ToBase58Address(this.network); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); var request = new BuildContractTransactionRequest { @@ -420,14 +440,17 @@ public void BuildTransferContext_RecipientIsKnownContract_Fails() string senderAddress = uint160.Zero.ToBase58Address(this.network); string recipientAddress = uint160.One.ToBase58Address(this.network); - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); var request = new BuildContractTransactionRequest { @@ -635,14 +658,17 @@ public void BuildTransferContextCorrectly() } }; - SmartContractTransactionService service = new SmartContractTransactionService( + var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + + var service = new SmartContractTransactionService( this.network, this.walletManager.Object, this.walletTransactionHandler.Object, this.stringSerializer.Object, this.callDataSerializer.Object, this.addressGenerator.Object, - this.stateRepository.Object); + this.stateRepository.Object, + reserveUtxoService); var senderHdAddress = new HdAddress { Address = senderAddress }; diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 7d21cb360f..a0eb3ed4ea 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -7,6 +7,7 @@ using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Features.Wallet.Interfaces; using Stratis.Bitcoin.Features.Wallet.Models; +using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.SmartContracts.CLR; using Stratis.SmartContracts.CLR.Serialization; using Stratis.SmartContracts.Core; @@ -35,6 +36,7 @@ public class SmartContractTransactionService : ISmartContractTransactionService private readonly ICallDataSerializer callDataSerializer; private readonly IAddressGenerator addressGenerator; private readonly IStateRepositoryRoot stateRoot; + private readonly IReserveUtxoService reserveUtxoService; public SmartContractTransactionService( Network network, @@ -43,7 +45,9 @@ public SmartContractTransactionService( IMethodParameterStringSerializer methodParameterStringSerializer, ICallDataSerializer callDataSerializer, IAddressGenerator addressGenerator, - IStateRepositoryRoot stateRoot) + IStateRepositoryRoot stateRoot, + IReserveUtxoService reserveUtxoService + ) { this.network = network; this.walletManager = walletManager; @@ -52,6 +56,7 @@ public SmartContractTransactionService( this.callDataSerializer = callDataSerializer; this.addressGenerator = addressGenerator; this.stateRoot = stateRoot; + this.reserveUtxoService = reserveUtxoService; } public EstimateFeeResult EstimateFee(ScTxFeeEstimateRequest request) @@ -81,7 +86,7 @@ public EstimateFeeResult EstimateFee(ScTxFeeEstimateRequest request) var recipients = new List(); foreach (RecipientModel recipientModel in request.Recipients) { - BitcoinAddress bitcoinAddress = BitcoinAddress.Create(recipientModel.DestinationAddress, this.network); + var bitcoinAddress = BitcoinAddress.Create(recipientModel.DestinationAddress, this.network); // If it's a potential SC address, check if it's a contract. if (bitcoinAddress is BitcoinPubKeyAddress bitcoinPubKeyAddress) @@ -359,11 +364,28 @@ private bool CheckBalance(string address) return !(addressBalance.AmountConfirmed == 0 && addressBalance.AmountUnconfirmed == 0); } - private List SelectInputs(string walletName, string sender, List outpoints) + private List SelectInputs(string walletName, string sender, List requestedOutpoints) { List selectedInputs = this.walletManager.GetSpendableInputsForAddress(walletName, sender); - return this.ReduceToRequestedInputs(outpoints, selectedInputs); + if (requestedOutpoints != null && requestedOutpoints.Any()) + selectedInputs = this.ReduceToRequestedInputs(requestedOutpoints, selectedInputs); + + FilterReservedInputs(selectedInputs); + + return selectedInputs; + } + + private List FilterReservedInputs(List selectedInputs) + { + var result = new List(); + foreach (OutPoint input in selectedInputs) + { + if (!this.reserveUtxoService.IsUtxoReserved(input)) + result.Add(input); + } + + return result; } /// @@ -374,16 +396,13 @@ private List ReduceToRequestedInputs(IReadOnlyList re { var result = new List(selectedInputs); - if (requestedOutpoints != null && requestedOutpoints.Any()) - { - //Convert outpointRequest to OutPoint - IEnumerable requestedOutPoints = requestedOutpoints.Select(outPointRequest => new OutPoint(new uint256(outPointRequest.TransactionId), outPointRequest.Index)); + //Convert outpointRequest to OutPoint + IEnumerable requestedOutPoints = requestedOutpoints.Select(outPointRequest => new OutPoint(new uint256(outPointRequest.TransactionId), outPointRequest.Index)); - for (int i = result.Count - 1; i >= 0; i--) - { - if (!requestedOutPoints.Contains(result[i])) - result.RemoveAt(i); - } + for (int i = result.Count - 1; i >= 0; i--) + { + if (!requestedOutPoints.Contains(result[i])) + result.RemoveAt(i); } return result; diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletTransactionHandler.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletTransactionHandler.cs index 6400b52675..fee317ffd6 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletTransactionHandler.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletTransactionHandler.cs @@ -5,6 +5,7 @@ using NBitcoin.Policy; using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Features.Wallet.Interfaces; +using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.Bitcoin.Utilities; using Stratis.SmartContracts.Core; @@ -17,8 +18,9 @@ public SmartContractWalletTransactionHandler( IWalletManager walletManager, IWalletFeePolicy walletFeePolicy, Network network, - StandardTransactionPolicy transactionPolicy) : - base(loggerFactory, walletManager, walletFeePolicy, network, transactionPolicy) + StandardTransactionPolicy transactionPolicy, + IReserveUtxoService utxoReservedService) : + base(loggerFactory, walletManager, walletFeePolicy, network, transactionPolicy, utxoReservedService) { } diff --git a/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs b/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs index 7a99285091..50dd485d64 100644 --- a/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs +++ b/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs @@ -11,7 +11,9 @@ using Stratis.Bitcoin.Configuration; using Stratis.Bitcoin.Consensus; using Stratis.Bitcoin.Features.Wallet.Interfaces; +using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.Bitcoin.Interfaces; +using Stratis.Bitcoin.Signals; using Stratis.Bitcoin.Tests.Common.Logging; using Stratis.Bitcoin.Tests.Wallet.Common; using Stratis.Bitcoin.Utilities; @@ -44,7 +46,9 @@ public void BuildTransactionThrowsWalletExceptionWhenMoneyIsZero() { Assert.Throws(() => { - var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, new Mock().Object, new Mock().Object, this.Network, this.standardTransactionPolicy); + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, new Mock().Object, new Mock().Object, this.Network, this.standardTransactionPolicy, reserveUtxoService); Transaction result = walletTransactionHandler.BuildTransaction(CreateContext(this.Network, new WalletAccountReference(), "password", new Script(), Money.Zero, FeeType.Medium, 2)); }); @@ -300,7 +304,9 @@ public void Given_AnInvalidAccountIsUsed_When_GetMaximumSpendableAmountIsCalled_ walletManager.Start(); - var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy); + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1", walletRepository); HdAccount account = wallet.AddNewAccount((ExtPubKey)null, accountName: "account 1"); @@ -324,7 +330,9 @@ public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoSpendableFoun walletManager.Start(); - var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy); + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1", walletRepository); HdAccount account = wallet.AddNewAccount((ExtPubKey)null, accountName: "account 1"); @@ -355,7 +363,9 @@ public void GetMaximumSpendableAmountReturnsAsZeroIfNoConfirmedTransactions() var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, new ChainIndexer(this.Network), new WalletSettings(NodeSettings.Default(this.Network)), dataFolder, new Mock().Object, new Mock().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader, walletRepository); - var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy); + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); walletManager.Start(); @@ -393,7 +403,9 @@ public void GetMaximumSpendableAmountReturnsSumOfUnconfirmedWhenNoConfirmedSpend walletManager.Start(); - var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy); + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy, reserveUtxoService); Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1", walletRepository); HdAccount account = wallet.AddNewAccount((ExtPubKey)null, accountName: "account 1"); @@ -425,7 +437,9 @@ public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoTransactions_ walletManager.Start(); - var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy); + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1", walletRepository); HdAccount account = wallet.AddNewAccount((ExtPubKey)null, accountName: "account 1"); @@ -541,8 +555,10 @@ private WalletTransactionHandlerTestContext SetupWallet(FeeRate feeRate = null, { DataFolder dataFolder = CreateDataFolder(this); - IWalletRepository walletRepository = new SQLiteWalletRepository(this.LoggerFactory.Object, dataFolder, this.Network, DateTimeProvider.Default, new ScriptAddressReader()); - walletRepository.TestMode = true; + IWalletRepository walletRepository = new SQLiteWalletRepository(this.LoggerFactory.Object, dataFolder, this.Network, DateTimeProvider.Default, new ScriptAddressReader()) + { + TestMode = true + }; var walletFeePolicy = new Mock(); walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations())) @@ -553,8 +569,10 @@ private WalletTransactionHandlerTestContext SetupWallet(FeeRate feeRate = null, var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain, new WalletSettings(NodeSettings.Default(this.Network)), dataFolder, walletFeePolicy.Object, new Mock().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader, walletRepository); - var walletTransactionHandler = - new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy); + + var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + + var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy, reserveUtxoService); walletManager.Start(); diff --git a/src/Stratis.Bitcoin.Features.Wallet/Services/IWalletService.cs b/src/Stratis.Bitcoin.Features.Wallet/Services/IWalletService.cs index aedfbedc37..b8d3e1d273 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/Services/IWalletService.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/Services/IWalletService.cs @@ -32,8 +32,7 @@ Task> RemoveTransactions(RemoveTransactions Task GetAllAddresses(GetAllAddressesModel request, CancellationToken cancellationToken); - Task BuildTransaction(BuildTransactionRequest request, - CancellationToken cancellationToken); + Task BuildTransaction(BuildTransactionRequest request, CancellationToken cancellationToken); Task GetTransactionFeeEstimate(TxFeeEstimateRequest request, CancellationToken cancellationToken); diff --git a/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs b/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs new file mode 100644 index 0000000000..73a58b8863 --- /dev/null +++ b/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using Microsoft.Extensions.Logging; +using NBitcoin; +using Stratis.Bitcoin.Features.MemoryPool; +using Stratis.Bitcoin.Signals; + +namespace Stratis.Bitcoin.Features.Wallet.Services +{ + public interface IReserveUtxoService + { + void ReserveUtxos(IEnumerable outPoint); + bool IsUtxoReserved(OutPoint outPoint); + } + + public sealed class ReserveUtxoService : IReserveUtxoService + { + private readonly ILogger logger; + private readonly HashSet reservedCoins = new HashSet(); + + public ReserveUtxoService(ILoggerFactory loggerFactory, ISignals signals) + { + this.logger = loggerFactory.CreateLogger(this.GetType().FullName); + signals.Subscribe(this.OnTransactionAdded); + } + + private void OnTransactionAdded(TransactionAddedToMemoryPool tx) + { + this.logger.LogDebug("Unreserving UTXOs for transaction '{0}'", tx.AddedTransaction.GetHash()); + + foreach (var input in tx.AddedTransaction.Inputs) + { + this.reservedCoins.Remove(input.PrevOut); + } + } + + public bool IsUtxoReserved(OutPoint outPoint) + { + var result = this.reservedCoins.Contains(outPoint); + this.logger.LogDebug("Outpoint '{0}' reserved = {1}", outPoint.Hash, result); + return result; + } + + public void ReserveUtxos(IEnumerable outPoints) + { + foreach (var outPoint in outPoints) + { + if (!this.reservedCoins.Contains(outPoint)) + { + this.reservedCoins.Add(outPoint); + this.logger.LogDebug("Reserving UTXO '{0}'", outPoint.Hash); + } + } + } + } +} \ No newline at end of file diff --git a/src/Stratis.Bitcoin.Features.Wallet/Services/WalletService.cs b/src/Stratis.Bitcoin.Features.Wallet/Services/WalletService.cs index a7ad3ed508..dd644c88ea 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/Services/WalletService.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/Services/WalletService.cs @@ -56,7 +56,7 @@ public WalletService(ILoggerFactory loggerFactory, this.chainIndexer = chainIndexer; this.broadcasterManager = broadcasterManager; this.dateTimeProvider = dateTimeProvider; - this.coinType = (CoinType) network.Consensus.CoinType; + this.coinType = (CoinType)network.Consensus.CoinType; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); } @@ -434,7 +434,7 @@ public async Task GetWalletStats(WalletStatsRequest request, .GroupBy(s => s.Transaction.Amount) .OrderByDescending(sg => sg.Count()) .Select(sg => new UtxoAmountModel - {Amount = sg.Key.ToDecimal(MoneyUnit.BTC), Count = sg.Count()}) + { Amount = sg.Key.ToDecimal(MoneyUnit.BTC), Count = sg.Count() }) .ToList(); // This is number of UTXO originating from the same transaction @@ -444,14 +444,14 @@ public async Task GetWalletStats(WalletStatsRequest request, .GroupBy(sg => sg.Count()) .OrderByDescending(sgg => sgg.Count()) .Select(utxo => new UtxoPerTransactionModel - {WalletInputsPerTransaction = utxo.Key, Count = utxo.Count()}) + { WalletInputsPerTransaction = utxo.Key, Count = utxo.Count() }) .ToList(); model.UtxoPerBlock = spendableTransactions .GroupBy(s => s.Transaction.BlockHeight) .GroupBy(sg => sg.Count()) .OrderByDescending(sgg => sgg.Count()) - .Select(utxo => new UtxoPerBlockModel {WalletInputsPerBlock = utxo.Key, Count = utxo.Count()}) + .Select(utxo => new UtxoPerBlockModel { WalletInputsPerBlock = utxo.Key, Count = utxo.Count() }) .ToList(); return model; @@ -471,7 +471,7 @@ public async Task SplitCoins(SplitCoinsRequest reque var recipients = new List(request.UtxosCount); for (int i = 0; i < request.UtxosCount; i++) - recipients.Add(new Recipient {ScriptPubKey = address.ScriptPubKey, Amount = singleUtxoAmount}); + recipients.Add(new Recipient { ScriptPubKey = address.ScriptPubKey, Amount = singleUtxoAmount }); var context = new TransactionBuildContext(this.network) { @@ -480,7 +480,7 @@ public async Task SplitCoins(SplitCoinsRequest reque Shuffle = true, WalletPassword = request.WalletPassword, Recipients = recipients, - Time = (uint) this.dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() + Time = (uint)this.dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() }; Transaction transactionResult = this.walletTransactionHandler.BuildTransaction(context); @@ -629,8 +629,7 @@ public async Task GetAllAddresses(GetAllAddressesModel request, }, cancellationToken); } - public async Task BuildTransaction(BuildTransactionRequest request, - CancellationToken cancellationToken = default(CancellationToken)) + public async Task BuildTransaction(BuildTransactionRequest request, CancellationToken cancellationToken = default(CancellationToken)) { return await Task.Run(() => { @@ -921,7 +920,7 @@ public async Task DistributeUtxos(DistributeUtxosRequest re for (int i = 0; i < request.UtxosCount; i++) { - recipients.Add(new Recipient {ScriptPubKey = addresses[addressIndex].ScriptPubKey}); + recipients.Add(new Recipient { ScriptPubKey = addresses[addressIndex].ScriptPubKey }); if (request.UseUniqueAddressPerUtxo) addressIndex++; @@ -961,8 +960,8 @@ public async Task DistributeUtxos(DistributeUtxosRequest re Shuffle = false, WalletPassword = request.WalletPassword, Recipients = recipients, - Time = (uint) this.dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() + - (uint) request.TimestampDifferenceBetweenTransactions, + Time = (uint)this.dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() + + (uint)request.TimestampDifferenceBetweenTransactions, AllowOtherInputs = false, SelectedInputs = inputs, FeeType = FeeType.Low @@ -981,7 +980,7 @@ public async Task DistributeUtxos(DistributeUtxosRequest re catch (NotEnoughFundsException ex) { // This remains the best approach for estimating transaction fees. - transactionFee = (Money) ex.Missing; + transactionFee = (Money)ex.Missing; } if (transactionFee < this.network.MinTxFee) @@ -996,8 +995,8 @@ public async Task DistributeUtxos(DistributeUtxosRequest re Shuffle = false, WalletPassword = request.WalletPassword, Recipients = recipients, - Time = (uint) this.dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() + - (uint) request.TimestampDifferenceBetweenTransactions, + Time = (uint)this.dateTimeProvider.GetAdjustedTimeAsUnixTimestamp() + + (uint)request.TimestampDifferenceBetweenTransactions, AllowOtherInputs = false, SelectedInputs = inputs, TransactionFee = transactionFee diff --git a/src/Stratis.Bitcoin.Features.Wallet/WalletFeature.cs b/src/Stratis.Bitcoin.Features.Wallet/WalletFeature.cs index 5401c45e35..a449a25389 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/WalletFeature.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/WalletFeature.cs @@ -16,9 +16,9 @@ using Stratis.Bitcoin.Features.RPC; using Stratis.Bitcoin.Features.Wallet.Broadcasting; using Stratis.Bitcoin.Features.Wallet.Interfaces; +using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.Bitcoin.Interfaces; using Stratis.Bitcoin.Utilities; -using Stratis.Bitcoin.Features.Wallet.Services; namespace Stratis.Bitcoin.Features.Wallet { @@ -32,15 +32,13 @@ public abstract class BaseWalletFeature : FullNodeFeature /// /// Wallet feature for the full node. /// - /// + /// public class WalletFeature : BaseWalletFeature { private readonly IWalletSyncManager walletSyncManager; private readonly IWalletManager walletManager; - private readonly Signals.ISignals signals; - private readonly IConnectionManager connectionManager; private readonly IAddressBookManager addressBookManager; @@ -55,14 +53,12 @@ public class WalletFeature : BaseWalletFeature /// The synchronization manager for the wallet, tasked with keeping the wallet synced with the network. /// The wallet manager. /// The address book manager. - /// The signals responsible for receiving blocks and transactions from the network. /// The connection manager. /// The broadcaster behavior. public WalletFeature( IWalletSyncManager walletSyncManager, IWalletManager walletManager, IAddressBookManager addressBookManager, - Signals.ISignals signals, IConnectionManager connectionManager, BroadcasterBehavior broadcasterBehavior, INodeStats nodeStats, @@ -71,7 +67,6 @@ public WalletFeature( this.walletSyncManager = walletSyncManager; this.walletManager = walletManager; this.addressBookManager = addressBookManager; - this.signals = signals; this.connectionManager = connectionManager; this.broadcasterBehavior = broadcasterBehavior; this.walletRepository = walletRepository; @@ -170,18 +165,19 @@ public static IFullNodeBuilder UseWallet(this IFullNodeBuilder fullNodeBuilder) .DependOn() .FeatureServices(services => { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(new ScriptAddressReader()); - services.AddSingleton(); - services.AddSingleton(); - }); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(new ScriptAddressReader()); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + }); }); return fullNodeBuilder; diff --git a/src/Stratis.Bitcoin.Features.Wallet/WalletSyncManager.cs b/src/Stratis.Bitcoin.Features.Wallet/WalletSyncManager.cs index e6f6213b1e..6a9c491e83 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/WalletSyncManager.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/WalletSyncManager.cs @@ -25,14 +25,13 @@ public class WalletSyncManager : IWalletSyncManager, IDisposable private readonly StoreSettings storeSettings; private readonly ISignals signals; private readonly IAsyncProvider asyncProvider; - private List<(string name, ChainedHeader tipHeader)> wallets = new List<(string name, ChainedHeader tipHeader)>(); private readonly INodeLifetime nodeLifetime; private IAsyncLoop walletSynchronisationLoop; private SubscriptionToken transactionAddedSubscription; private SubscriptionToken transactionRemovedSubscription; private SubscriptionToken blockConnectedSubscription; private CancellationTokenSource syncCancellationToken; - private object lockObject; + private readonly object lockObject; private readonly MempoolManager mempoolManager; public ChainedHeader WalletTip => this.walletManager.WalletCommonTip(this.chainIndexer.Tip); @@ -111,7 +110,7 @@ private void OnTransactionAdded(TransactionAddedToMemoryPool transactionAddedToM private void OnTransactionRemoved(TransactionRemovedFromMemoryPool transactionRemovedFromMempool) { - this.logger.LogDebug("Transaction '{0}' was removed from the mempool. RemovedForBlock={1}", + this.logger.LogDebug("Transaction '{0}' was removed from the mempool. RemovedForBlock={1}", transactionRemovedFromMempool.RemovedTransaction.GetHash(), transactionRemovedFromMempool.RemovedForBlock); // If the transaction was removed from the mempool because it's part of a block, we don't want to remove it. diff --git a/src/Stratis.Bitcoin.Features.Wallet/WalletTransactionHandler.cs b/src/Stratis.Bitcoin.Features.Wallet/WalletTransactionHandler.cs index ac3885643e..903dd4620d 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/WalletTransactionHandler.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/WalletTransactionHandler.cs @@ -6,6 +6,7 @@ using NBitcoin; using NBitcoin.Policy; using Stratis.Bitcoin.Features.Wallet.Interfaces; +using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.Bitcoin.Utilities; namespace Stratis.Bitcoin.Features.Wallet @@ -13,7 +14,7 @@ namespace Stratis.Bitcoin.Features.Wallet /// /// A handler that has various functionalities related to transaction operations. /// - /// + /// /// /// This will uses the and the . /// TODO: Move also the broadcast transaction to this class @@ -28,28 +29,26 @@ public class WalletTransactionHandler : IWalletTransactionHandler private static readonly Money PretendMaxFee = Money.Coins(1); private readonly ILogger logger; - private readonly Network network; - + private readonly IReserveUtxoService reserveUtxoService; protected readonly StandardTransactionPolicy TransactionPolicy; - - private readonly IWalletManager walletManager; - private readonly IWalletFeePolicy walletFeePolicy; + private readonly IWalletManager walletManager; public WalletTransactionHandler( ILoggerFactory loggerFactory, IWalletManager walletManager, IWalletFeePolicy walletFeePolicy, Network network, - StandardTransactionPolicy transactionPolicy) + StandardTransactionPolicy transactionPolicy, + IReserveUtxoService reservedUtxoService) { this.network = network; this.walletManager = walletManager; this.walletFeePolicy = walletFeePolicy; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); - this.TransactionPolicy = transactionPolicy; + this.reserveUtxoService = reservedUtxoService; } /// @@ -67,11 +66,16 @@ public Transaction BuildTransaction(TransactionBuildContext context) context.TransactionBuilder.Shuffle(); Transaction transaction = context.TransactionBuilder.BuildTransaction(false); + ICoin[] spentCoins = context.TransactionBuilder.FindSpentCoins(transaction); + + // Here we reserve the UTXO OutPoint so that it cant be selected again. + if (spentCoins.Any()) + this.reserveUtxoService.ReserveUtxos(spentCoins.Select(c => c.Outpoint)); + if (context.Sign) { - ICoin[] coinsSpent = context.TransactionBuilder.FindSpentCoins(transaction); // TODO: Improve this as we already have secrets when running a retry iteration. - this.AddSecrets(context, coinsSpent); + this.AddSecrets(context, spentCoins); context.TransactionBuilder.SignTransactionInPlace(transaction); } @@ -243,7 +247,7 @@ protected void AddSecrets(TransactionBuildContext context, IEnumerable co ExtKey seedExtKey = this.walletManager.GetExtKey(context.AccountReference, context.WalletPassword); var signingKeys = new HashSet(); - Dictionary outpointLookup = context.UnspentOutputs.ToDictionary(o => o.ToOutPoint(), o => o); + Dictionary outpointLookup = context.UnspentOutputs.ToDictionary(o => o.ToOutPoint(), o => o); IEnumerable uniqueHdPaths = coinsSpent.Select(s => s.Outpoint).Select(o => outpointLookup[o].Address.HdPath).Distinct(); foreach (string hdPath in uniqueHdPaths) From 1cce59f7f9e21a107289dd514f3a755c1c692447 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Thu, 20 Aug 2020 07:59:23 +0100 Subject: [PATCH 02/16] Add Locks --- .../Services/ReserveUtxoService.cs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs b/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs index 73a58b8863..ed46a30429 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs @@ -14,6 +14,8 @@ public interface IReserveUtxoService public sealed class ReserveUtxoService : IReserveUtxoService { + private readonly object lockObject = new object(); + private readonly ILogger logger; private readonly HashSet reservedCoins = new HashSet(); @@ -25,29 +27,38 @@ public ReserveUtxoService(ILoggerFactory loggerFactory, ISignals signals) private void OnTransactionAdded(TransactionAddedToMemoryPool tx) { - this.logger.LogDebug("Unreserving UTXOs for transaction '{0}'", tx.AddedTransaction.GetHash()); - - foreach (var input in tx.AddedTransaction.Inputs) + lock (this.lockObject) { - this.reservedCoins.Remove(input.PrevOut); + this.logger.LogDebug("Unreserving UTXOs for transaction '{0}'", tx.AddedTransaction.GetHash()); + + foreach (var input in tx.AddedTransaction.Inputs) + { + this.reservedCoins.Remove(input.PrevOut); + } } } public bool IsUtxoReserved(OutPoint outPoint) { - var result = this.reservedCoins.Contains(outPoint); - this.logger.LogDebug("Outpoint '{0}' reserved = {1}", outPoint.Hash, result); - return result; + lock (this.lockObject) + { + var result = this.reservedCoins.Contains(outPoint); + this.logger.LogDebug("Outpoint '{0}' reserved = {1}", outPoint.Hash, result); + return result; + } } public void ReserveUtxos(IEnumerable outPoints) { - foreach (var outPoint in outPoints) + lock (this.lockObject) { - if (!this.reservedCoins.Contains(outPoint)) + foreach (var outPoint in outPoints) { - this.reservedCoins.Add(outPoint); - this.logger.LogDebug("Reserving UTXO '{0}'", outPoint.Hash); + if (!this.reservedCoins.Contains(outPoint)) + { + this.reservedCoins.Add(outPoint); + this.logger.LogDebug("Reserving UTXO '{0}'", outPoint.Hash); + } } } } From 2c581ecf62a44f1cbfeeea80db61f7c2155d3cf1 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Thu, 20 Aug 2020 08:13:39 +0100 Subject: [PATCH 03/16] Update src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs Co-authored-by: zeptin --- .../Wallet/SmartContractTransactionService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index a0eb3ed4ea..8f87fd9867 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -396,7 +396,7 @@ private List ReduceToRequestedInputs(IReadOnlyList re { var result = new List(selectedInputs); - //Convert outpointRequest to OutPoint + // Convert outpointRequest to OutPoint IEnumerable requestedOutPoints = requestedOutpoints.Select(outPointRequest => new OutPoint(new uint256(outPointRequest.TransactionId), outPointRequest.Index)); for (int i = result.Count - 1; i >= 0; i--) From ac394ae219916fb861208a48963f7a0c5b1306ce Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Thu, 20 Aug 2020 08:38:09 +0100 Subject: [PATCH 04/16] Create ReserveUtxoServiceTests.cs --- .../ReserveUtxoServiceTests.cs | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs diff --git a/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs b/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs new file mode 100644 index 0000000000..68f6149324 --- /dev/null +++ b/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs @@ -0,0 +1,48 @@ +using Microsoft.Extensions.Logging; +using NBitcoin; +using Stratis.Bitcoin.Configuration.Logging; +using Stratis.Bitcoin.Features.MemoryPool; +using Stratis.Bitcoin.Features.Wallet.Services; +using Stratis.Bitcoin.Networks; +using Xunit; + +namespace Stratis.Bitcoin.Features.Wallet.Tests +{ + public sealed class ReserveUtxoServiceTests + { + private readonly ILoggerFactory loggerFactory; + private readonly Signals.Signals signals; + private readonly Network network; + + public ReserveUtxoServiceTests() + { + this.loggerFactory = new ExtendedLoggerFactory(); + this.signals = new Signals.Signals(this.loggerFactory, null); + this.network = new StratisTest(); + } + + [Fact] + public void CanReserveUtxo() + { + var service = new ReserveUtxoService(this.loggerFactory, this.signals); + var outpoint = new OutPoint(new uint256(0), 1); + service.ReserveUtxos(new[] { outpoint }); + Assert.True(service.IsUtxoReserved(outpoint)); + } + + [Fact] + public void CanUnReserveUtxo() + { + var transaction = this.network.CreateTransaction(); + var outpoint = new OutPoint(new uint256(0), 1); + transaction.AddInput(new TxIn(outpoint)); + + var service = new ReserveUtxoService(this.loggerFactory, this.signals); + service.ReserveUtxos(new[] { outpoint }); + Assert.True(service.IsUtxoReserved(outpoint)); + + this.signals.Publish(new TransactionAddedToMemoryPool(transaction)); + Assert.False(service.IsUtxoReserved(outpoint)); + } + } +} \ No newline at end of file From 4b5ccb581aa7fdffebb1a182428fbaff9dc3492b Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 09:00:34 +0100 Subject: [PATCH 05/16] Add integration test --- .../TxMemPool.cs | 2 - .../BlockDefinition.cs | 1 - .../Wallet/SmartContractTransactionService.cs | 4 +- .../Wallet/SmartContractWalletFeature.cs | 1 + .../ReserveUtxoServiceTests.cs | 7 +++- .../Services/ReserveUtxoService.cs | 12 +++--- .../CoreEvents/TransactionReceived.cs | 2 +- .../ReserveUtxoServiceIntegrationTests.cs | 40 +++++++++++++++++++ .../MockChain/MockChainNode.cs | 16 +++++++- 9 files changed, 68 insertions(+), 17 deletions(-) create mode 100644 src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs diff --git a/src/Stratis.Bitcoin.Features.MemoryPool/TxMemPool.cs b/src/Stratis.Bitcoin.Features.MemoryPool/TxMemPool.cs index 0367b1fce4..c770a821b9 100644 --- a/src/Stratis.Bitcoin.Features.MemoryPool/TxMemPool.cs +++ b/src/Stratis.Bitcoin.Features.MemoryPool/TxMemPool.cs @@ -30,8 +30,6 @@ public class TxMempoolInfo public long FeeDelta { get; set; } } -; - /// /// Memory pool of pending transactions. /// diff --git a/src/Stratis.Bitcoin.Features.Miner/BlockDefinition.cs b/src/Stratis.Bitcoin.Features.Miner/BlockDefinition.cs index e90a7c3ebe..dc49e84d62 100644 --- a/src/Stratis.Bitcoin.Features.Miner/BlockDefinition.cs +++ b/src/Stratis.Bitcoin.Features.Miner/BlockDefinition.cs @@ -180,7 +180,6 @@ private void Configure() /// /// Tip of the chain that this instance will work with without touching any shared chain resources. /// Script that explains what conditions must be met to claim ownership of a coin. - /// The contructed . protected void OnBuild(ChainedHeader chainTip, Script scriptPubKey) { this.Configure(); diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 8f87fd9867..d4e3db742c 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -371,9 +371,7 @@ private List SelectInputs(string walletName, string sender, List FilterReservedInputs(List selectedInputs) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletFeature.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletFeature.cs index 2db987136c..c2d5998638 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletFeature.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractWalletFeature.cs @@ -136,6 +136,7 @@ public static IFullNodeBuilder UseSmartContractWallet(this IFullNodeBuilder full services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddTransient(); }); diff --git a/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs b/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs index 68f6149324..03c16722f2 100644 --- a/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs +++ b/src/Stratis.Bitcoin.Features.Wallet.Tests/ReserveUtxoServiceTests.cs @@ -1,7 +1,7 @@ using Microsoft.Extensions.Logging; using NBitcoin; using Stratis.Bitcoin.Configuration.Logging; -using Stratis.Bitcoin.Features.MemoryPool; +using Stratis.Bitcoin.EventBus.CoreEvents; using Stratis.Bitcoin.Features.Wallet.Services; using Stratis.Bitcoin.Networks; using Xunit; @@ -37,11 +37,14 @@ public void CanUnReserveUtxo() var outpoint = new OutPoint(new uint256(0), 1); transaction.AddInput(new TxIn(outpoint)); + var block = this.network.CreateBlock(); + block.AddTransaction(transaction); + var service = new ReserveUtxoService(this.loggerFactory, this.signals); service.ReserveUtxos(new[] { outpoint }); Assert.True(service.IsUtxoReserved(outpoint)); - this.signals.Publish(new TransactionAddedToMemoryPool(transaction)); + this.signals.Publish(new BlockConnected(new Primitives.ChainedHeaderBlock(block, new ChainedHeader(block.Header, block.Header.GetHash(), 1)))); Assert.False(service.IsUtxoReserved(outpoint)); } } diff --git a/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs b/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs index ed46a30429..7af3ad5852 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs +++ b/src/Stratis.Bitcoin.Features.Wallet/Services/ReserveUtxoService.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; +using System.Linq; using Microsoft.Extensions.Logging; using NBitcoin; -using Stratis.Bitcoin.Features.MemoryPool; +using Stratis.Bitcoin.EventBus.CoreEvents; using Stratis.Bitcoin.Signals; namespace Stratis.Bitcoin.Features.Wallet.Services @@ -22,17 +23,16 @@ public sealed class ReserveUtxoService : IReserveUtxoService public ReserveUtxoService(ILoggerFactory loggerFactory, ISignals signals) { this.logger = loggerFactory.CreateLogger(this.GetType().FullName); - signals.Subscribe(this.OnTransactionAdded); + signals.Subscribe(this.OnTransactionAdded); } - private void OnTransactionAdded(TransactionAddedToMemoryPool tx) + private void OnTransactionAdded(BlockConnected tx) { lock (this.lockObject) { - this.logger.LogDebug("Unreserving UTXOs for transaction '{0}'", tx.AddedTransaction.GetHash()); - - foreach (var input in tx.AddedTransaction.Inputs) + foreach (var input in tx.ConnectedBlock.Block.Transactions.SelectMany(t => t.Inputs)) { + this.logger.LogDebug("Unreserving UTXOs for transaction '{0}'", input.PrevOut.Hash); this.reservedCoins.Remove(input.PrevOut); } } diff --git a/src/Stratis.Bitcoin/EventBus/CoreEvents/TransactionReceived.cs b/src/Stratis.Bitcoin/EventBus/CoreEvents/TransactionReceived.cs index f6273f08b6..054f838298 100644 --- a/src/Stratis.Bitcoin/EventBus/CoreEvents/TransactionReceived.cs +++ b/src/Stratis.Bitcoin/EventBus/CoreEvents/TransactionReceived.cs @@ -5,7 +5,7 @@ namespace Stratis.Bitcoin.EventBus.CoreEvents /// /// Event that is executed when a transaction is received from another peer. /// - /// + /// public class TransactionReceived : EventBase { public Transaction ReceivedTransaction { get; } diff --git a/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs b/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs new file mode 100644 index 0000000000..815f72b440 --- /dev/null +++ b/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs @@ -0,0 +1,40 @@ +using Stratis.Bitcoin.Features.SmartContracts; +using Stratis.Bitcoin.Features.SmartContracts.ReflectionExecutor.Consensus.Rules; +using Stratis.Bitcoin.Features.Wallet.Interfaces; +using Stratis.SmartContracts.CLR.Compilation; +using Stratis.SmartContracts.Tests.Common.MockChain; +using Xunit; + +namespace Stratis.SmartContracts.IntegrationTests +{ + public sealed class ReserveUtxoServiceIntegrationTests + { + [Fact] + public void CanReserveAndUnreserveUtxosAsync() + { + using (var chain = new PoWMockChain(2)) + { + MockChainNode sender = chain.Nodes[0]; + + // Mine some coins so we have balance + int maturity = (int)sender.CoreNode.FullNode.Network.Consensus.CoinbaseMaturity; + sender.MineBlocks(maturity + 1); + + // Compile the Smart Contract + ContractCompilationResult compilationResult = ContractCompiler.CompileFile("SmartContracts/StorageDemo.cs"); + Assert.True(compilationResult.Success); + + // Stop the wallet sync manager so that wallet's spendable inputs does not get updated. + sender.CoreNode.FullNode.NodeService().Stop(); + + // Send the first transaction + var responseOne = sender.SendCreateContractTransaction(compilationResult.Compilation, 0, feeAmount: 0.001M, gasPrice: SmartContractMempoolValidator.MinGasPrice, gasLimit: SmartContractFormatLogic.GasLimitMaximum / 2); + Assert.True(responseOne.Success); + + // Send the second transaction, which should fail as the utxo was already reserved with transaction one. + var responseTwo = sender.SendCreateContractTransaction(compilationResult.Compilation, 0, feeAmount: 0.001M, gasPrice: SmartContractMempoolValidator.MinGasPrice, gasLimit: SmartContractFormatLogic.GasLimitMaximum / 2); + Assert.False(responseTwo.Success); + } + } + } +} diff --git a/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs b/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs index 0960e0d6b2..0005bccf99 100644 --- a/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs +++ b/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs @@ -23,6 +23,7 @@ using Stratis.SmartContracts.CLR.Local; using Stratis.SmartContracts.Core; using Stratis.SmartContracts.Core.State; +using Xunit; namespace Stratis.SmartContracts.Tests.Common.MockChain { @@ -106,6 +107,17 @@ public void MineBlocks(int amountOfBlocks) { TestHelper.MineBlocks(this.CoreNode, amountOfBlocks); this.chain.WaitForAllNodesToSync(); + + int spendable = GetSpendableBlocks(amountOfBlocks, this.CoreNode.FullNode.Network.Consensus.CoinbaseMaturity); + Assert.Equal(Money.COIN * spendable * 50, (long)this.WalletSpendableBalance); + } + + /// + /// Given an amount of blocks and a maturity, how many blocks have spendable coinbase / coinstakes. + /// + private static int GetSpendableBlocks(int mined, long maturity) + { + return mined - (int)maturity; } public ulong GetWalletAddressBalance(string walletAddress) @@ -272,10 +284,10 @@ public BuildCallContractTransactionResponse SendCallContractTransaction( string[] parameters = null, ulong gasLimit = SmartContractFormatLogic.GasLimitMaximum / 2, // half of maximum ulong gasPrice = SmartContractMempoolValidator.MinGasPrice, - decimal feeAmount = 0.01M, + decimal feeAmount = 0.01M, string sender = null, List outpoints = null) - { + { var request = new BuildCallContractTransactionRequest { AccountName = this.AccountName, From 029d0b01e756a97b917b28ffcb1504567d506c92 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 10:52:02 +0100 Subject: [PATCH 06/16] Run Tests --- .../Controllers/SmartContractsController.cs | 1 - .../Wallet/SmartContractTransactionService.cs | 50 ++++++++++--------- .../Utilities/JsonErrors/ErrorHelpers.cs | 6 +-- .../ReserveUtxoServiceIntegrationTests.cs | 2 +- .../MockChain/MockChainNode.cs | 2 - 5 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/ReflectionExecutor/Controllers/SmartContractsController.cs b/src/Stratis.Bitcoin.Features.SmartContracts/ReflectionExecutor/Controllers/SmartContractsController.cs index ec7f685f86..47338dca2f 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/ReflectionExecutor/Controllers/SmartContractsController.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/ReflectionExecutor/Controllers/SmartContractsController.cs @@ -18,7 +18,6 @@ using Stratis.Bitcoin.Features.Wallet.Broadcasting; using Stratis.Bitcoin.Features.Wallet.Interfaces; using Stratis.Bitcoin.Interfaces; -using Stratis.Bitcoin.Utilities; using Stratis.Bitcoin.Utilities.JsonErrors; using Stratis.Bitcoin.Utilities.ModelStateErrors; using Stratis.SmartContracts; diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index d4e3db742c..5188f66aba 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -69,19 +69,15 @@ public EstimateFeeResult EstimateFee(ScTxFeeEstimateRequest request) return EstimateFeeResult.Failure(AccountNotInWalletError, $"No account with the name '{request.AccountName}' could be found."); HdAddress senderAddress = account.GetCombinedAddresses().FirstOrDefault(x => x.Address == request.Sender); - if (senderAddress == null) - { return EstimateFeeResult.Failure(SenderNotInWalletError, $"The given address {request.Sender} was not found in the wallet."); - } if (!this.CheckBalance(senderAddress.Address)) return EstimateFeeResult.Failure(InsufficientBalanceError, SenderNoBalanceError); - List selectedInputs = this.SelectInputs(request.WalletName, request.Sender, request.Outpoints); - - if (!selectedInputs.Any()) - return EstimateFeeResult.Failure(InvalidOutpointsError, "Invalid list of request outpoints have been passed to the method. Please ensure that the outpoints are spendable by the sender address."); + (List selectedInputs, string message) = SelectInputs(request.WalletName, request.Sender, request.Outpoints); + if (!string.IsNullOrEmpty(message)) + return EstimateFeeResult.Failure(InvalidOutpointsError, message); var recipients = new List(); foreach (RecipientModel recipientModel in request.Recipients) @@ -141,24 +137,20 @@ public BuildContractTransactionResult BuildTx(BuildContractTransactionRequest re return BuildContractTransactionResult.Failure(AccountNotInWalletError, $"No account with the name '{request.AccountName}' could be found."); HdAddress senderAddress = account.GetCombinedAddresses().FirstOrDefault(x => x.Address == request.Sender); - if (senderAddress == null) - { return BuildContractTransactionResult.Failure(SenderNotInWalletError, $"The given address {request.Sender} was not found in the wallet."); - } if (!this.CheckBalance(senderAddress.Address)) return BuildContractTransactionResult.Failure(InsufficientBalanceError, SenderNoBalanceError); - List selectedInputs = this.SelectInputs(request.WalletName, request.Sender, request.Outpoints); - - if (!selectedInputs.Any()) - return BuildContractTransactionResult.Failure(InvalidOutpointsError, "Invalid list of request outpoints have been passed to the method. Please ensure that the outpoints are spendable by the sender address."); + (List selectedInputs, string message) = SelectInputs(request.WalletName, request.Sender, request.Outpoints); + if (!string.IsNullOrEmpty(message)) + return BuildContractTransactionResult.Failure(InvalidOutpointsError, message); var recipients = new List(); foreach (RecipientModel recipientModel in request.Recipients) { - BitcoinAddress bitcoinAddress = BitcoinAddress.Create(recipientModel.DestinationAddress, this.network); + var bitcoinAddress = BitcoinAddress.Create(recipientModel.DestinationAddress, this.network); // If it's a potential SC address, check if it's a contract. if (bitcoinAddress is BitcoinPubKeyAddress bitcoinPubKeyAddress) @@ -211,9 +203,9 @@ public BuildCallContractTransactionResponse BuildCallTx(BuildCallContractTransac if (!this.CheckBalance(request.Sender)) return BuildCallContractTransactionResponse.Failed(SenderNoBalanceError); - List selectedInputs = this.SelectInputs(request.WalletName, request.Sender, request.Outpoints); - if (!selectedInputs.Any()) - return BuildCallContractTransactionResponse.Failed("Invalid list of request outpoints have been passed to the method. Please ensure that the outpoints are spendable by the sender address"); + (List selectedInputs, string message) = SelectInputs(request.WalletName, request.Sender, request.Outpoints); + if (!string.IsNullOrEmpty(message)) + return BuildCallContractTransactionResponse.Failed(message); uint160 addressNumeric = request.ContractAddress.ToUint160(this.network); @@ -274,9 +266,9 @@ public BuildCreateContractTransactionResponse BuildCreateTx(BuildCreateContractT if (!this.CheckBalance(request.Sender)) return BuildCreateContractTransactionResponse.Failed(SenderNoBalanceError); - List selectedInputs = this.SelectInputs(request.WalletName, request.Sender, request.Outpoints); - if (!selectedInputs.Any()) - return BuildCreateContractTransactionResponse.Failed("Invalid list of request outpoints have been passed to the method. Please ensure that the outpoints are spendable by the sender address"); + (List selectedInputs, string message) = this.SelectInputs(request.WalletName, request.Sender, request.Outpoints); + if (!string.IsNullOrEmpty(message)) + return BuildCreateContractTransactionResponse.Failed(message); ContractTxData txData; if (request.Parameters != null && request.Parameters.Any()) @@ -364,14 +356,24 @@ private bool CheckBalance(string address) return !(addressBalance.AmountConfirmed == 0 && addressBalance.AmountUnconfirmed == 0); } - private List SelectInputs(string walletName, string sender, List requestedOutpoints) + private (List seletedInputs, string message) SelectInputs(string walletName, string sender, List requestedOutpoints) { List selectedInputs = this.walletManager.GetSpendableInputsForAddress(walletName, sender); + if (!selectedInputs.Any()) + return (selectedInputs, "The wallet does not contain any spendable inputs."); if (requestedOutpoints != null && requestedOutpoints.Any()) + { selectedInputs = this.ReduceToRequestedInputs(requestedOutpoints, selectedInputs); + if (!selectedInputs.Any()) + return (selectedInputs, "And invalid list of request outpoints have been passed to the method, please ensure that the outpoints are spendable by the sender address."); + } + + selectedInputs = FilterReservedInputs(selectedInputs); + if (!selectedInputs.Any()) + return (selectedInputs, "All of the selected inputs are currently reserved, please try again in 60 seconds."); - return FilterReservedInputs(selectedInputs); + return (selectedInputs, null); } private List FilterReservedInputs(List selectedInputs) @@ -406,4 +408,4 @@ private List ReduceToRequestedInputs(IReadOnlyList re return result; } } -} +} \ No newline at end of file diff --git a/src/Stratis.Bitcoin/Utilities/JsonErrors/ErrorHelpers.cs b/src/Stratis.Bitcoin/Utilities/JsonErrors/ErrorHelpers.cs index bb12c1a899..8a73cdc024 100644 --- a/src/Stratis.Bitcoin/Utilities/JsonErrors/ErrorHelpers.cs +++ b/src/Stratis.Bitcoin/Utilities/JsonErrors/ErrorHelpers.cs @@ -21,10 +21,10 @@ public static ErrorResult BuildErrorResponse(HttpStatusCode statusCode, string m } }; - return new ErrorResult((int) statusCode, errorResponse); + return new ErrorResult((int)statusCode, errorResponse); } - public static ErrorResult MapToErrorResponse(this FeatureException featureException ) + public static ErrorResult MapToErrorResponse(this FeatureException featureException) { var errorResponse = new ErrorResponse { @@ -39,7 +39,7 @@ public static ErrorResult MapToErrorResponse(this FeatureException featureExcept } }; - return new ErrorResult((int) featureException.HttpStatusCode, errorResponse); + return new ErrorResult((int)featureException.HttpStatusCode, errorResponse); } } } \ No newline at end of file diff --git a/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs b/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs index 815f72b440..d60630c52b 100644 --- a/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs +++ b/src/Stratis.SmartContracts.IntegrationTests/ReserveUtxoServiceIntegrationTests.cs @@ -33,7 +33,7 @@ public void CanReserveAndUnreserveUtxosAsync() // Send the second transaction, which should fail as the utxo was already reserved with transaction one. var responseTwo = sender.SendCreateContractTransaction(compilationResult.Compilation, 0, feeAmount: 0.001M, gasPrice: SmartContractMempoolValidator.MinGasPrice, gasLimit: SmartContractFormatLogic.GasLimitMaximum / 2); - Assert.False(responseTwo.Success); + Assert.Null(responseTwo); // This needs to be done better so that we can check the actual message. } } } diff --git a/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs b/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs index 0005bccf99..e6be24a4fc 100644 --- a/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs +++ b/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs @@ -221,9 +221,7 @@ public BuildCreateContractTransactionResponse SendCreateContractTransaction( IActionResult result = this.smartContractsController.BuildAndSendCreateSmartContractTransactionAsync(request).GetAwaiter().GetResult(); if (result is JsonResult response) - { return (BuildCreateContractTransactionResponse)response.Value; - } return null; } From 3d443b899b41b8abe8377f2bf984ee20f1cc6729 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:06:45 +0100 Subject: [PATCH 07/16] Upgrade .NET Standard to .Net Core 3.1 --- src/FodyNlogAdapter/FodyNlogAdapter.csproj | 4 ++-- src/NBitcoin/NBitcoin.csproj | 2 +- .../Stratis.Bitcoin.Features.BlockStore.csproj | 2 +- .../Stratis.Bitcoin.Features.Consensus.csproj | 2 +- .../Stratis.Bitcoin.Features.Dns.csproj | 2 +- .../Stratis.Bitcoin.Features.MemoryPool.csproj | 2 +- .../Stratis.Bitcoin.Features.Notifications.csproj | 2 +- .../Stratis.Bitcoin.Features.SmartContracts.csproj | 3 +-- .../Stratis.Bitcoin.Networks.csproj | 4 ++-- src/Stratis.Bitcoin/FullNode.cs | 3 ++- src/Stratis.Bitcoin/Stratis.Bitcoin.csproj | 7 ++++--- .../Stratis.Features.Collateral.csproj | 3 +-- .../Stratis.Features.Diagnostic.csproj | 2 +- .../Stratis.Features.FederatedPeg.csproj | 3 +-- 14 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/FodyNlogAdapter/FodyNlogAdapter.csproj b/src/FodyNlogAdapter/FodyNlogAdapter.csproj index 0257b278f2..8db8fc16b8 100644 --- a/src/FodyNlogAdapter/FodyNlogAdapter.csproj +++ b/src/FodyNlogAdapter/FodyNlogAdapter.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.1 FodyNlogAdapter 3.0.8.0 False @@ -11,7 +11,7 @@ - + diff --git a/src/NBitcoin/NBitcoin.csproj b/src/NBitcoin/NBitcoin.csproj index b357b19dda..e38ba62739 100644 --- a/src/NBitcoin/NBitcoin.csproj +++ b/src/NBitcoin/NBitcoin.csproj @@ -11,7 +11,7 @@ - netstandard2.0 + netcoreapp3.1 NBitcoin NStratis NStratis diff --git a/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj b/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj index b7b075df91..d43fd33a79 100644 --- a/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj +++ b/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj @@ -3,7 +3,7 @@ Stratis Bitcoin Features BlockStore Stratis.Bitcoin.Features.BlockStore - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin.Features.BlockStore Stratis.Bitcoin.Features.BlockStore false diff --git a/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj b/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj index ac8e8661a9..3fd7df1f59 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj +++ b/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj @@ -3,7 +3,7 @@ Stratis Bitcoin Features Consensus Stratis.Bitcoin.Features.Consensus - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin.Features.Consensus Stratis.Bitcoin.Features.Consensus false diff --git a/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj b/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj index cdd9174aa2..69c66e015a 100644 --- a/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj +++ b/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj @@ -3,7 +3,7 @@ Stratis Bitcoin Features Dns Stratis.Bitcoin.Features.Dns - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin.Features.Dns Stratis.Bitcoin.Features.Dns false diff --git a/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj b/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj index 08cd0d6b76..29b593564a 100644 --- a/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj +++ b/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj @@ -3,7 +3,7 @@ Stratis Bitcoin Features MemoryPool Stratis.Bitcoin.Features.MemoryPool - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin.Features.MemoryPool Stratis.Bitcoin.Features.MemoryPool false diff --git a/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj b/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj index 7dc8cc5275..25d44eaa9d 100644 --- a/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj +++ b/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj @@ -3,7 +3,7 @@ Stratis Bitcoin Features Notifications Stratis.Bitcoin.Features.Notifications - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin.Features.Notifications Stratis.Bitcoin.Features.Notifications false diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj b/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj index 45a7d5beb6..f9d22ea2db 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj @@ -1,8 +1,7 @@  - netcoreapp3.1 - + netcoreapp3.1 3.0.8.0 Stratis Group Ltd. diff --git a/src/Stratis.Bitcoin.Networks/Stratis.Bitcoin.Networks.csproj b/src/Stratis.Bitcoin.Networks/Stratis.Bitcoin.Networks.csproj index d7b9e8f357..ad22c5ba50 100644 --- a/src/Stratis.Bitcoin.Networks/Stratis.Bitcoin.Networks.csproj +++ b/src/Stratis.Bitcoin.Networks/Stratis.Bitcoin.Networks.csproj @@ -1,9 +1,9 @@  - Stratis Bitcoin FullNode + Stratis FullNode Networks Stratis.Bitcoin.Networks - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin.Networks Stratis.Bitcoin.Networks false diff --git a/src/Stratis.Bitcoin/FullNode.cs b/src/Stratis.Bitcoin/FullNode.cs index 0a62b76623..0a090cd887 100644 --- a/src/Stratis.Bitcoin/FullNode.cs +++ b/src/Stratis.Bitcoin/FullNode.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.PlatformAbstractions; using NBitcoin; using Stratis.Bitcoin.AsyncWork; using Stratis.Bitcoin.Base; @@ -128,7 +129,7 @@ public Version Version get { string versionString = typeof(FullNode).GetTypeInfo().Assembly.GetCustomAttribute()?.Version ?? - Microsoft.Extensions.PlatformAbstractions.PlatformServices.Default.Application.ApplicationVersion; + PlatformServices.Default.Application.ApplicationVersion; if (!string.IsNullOrEmpty(versionString)) { diff --git a/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj b/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj index 05d84bfe1f..08ac585564 100644 --- a/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj +++ b/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj @@ -3,7 +3,7 @@ Stratis Bitcoin FullNode Stratis.Bitcoin - netstandard2.0 + netcoreapp3.1 Stratis.Bitcoin Stratis.Bitcoin false @@ -39,8 +39,9 @@ - - + + + diff --git a/src/Stratis.Features.Collateral/Stratis.Features.Collateral.csproj b/src/Stratis.Features.Collateral/Stratis.Features.Collateral.csproj index c8de7e3dc5..af2fdc2d39 100644 --- a/src/Stratis.Features.Collateral/Stratis.Features.Collateral.csproj +++ b/src/Stratis.Features.Collateral/Stratis.Features.Collateral.csproj @@ -1,8 +1,7 @@  - netcoreapp3.1 - + netcoreapp3.1 3.0.8.0 Stratis Group Ltd. diff --git a/src/Stratis.Features.Diagnostic/Stratis.Features.Diagnostic.csproj b/src/Stratis.Features.Diagnostic/Stratis.Features.Diagnostic.csproj index 8b33226e76..dddd6f9763 100644 --- a/src/Stratis.Features.Diagnostic/Stratis.Features.Diagnostic.csproj +++ b/src/Stratis.Features.Diagnostic/Stratis.Features.Diagnostic.csproj @@ -1,7 +1,7 @@  - netstandard2.0 + netcoreapp3.1 ..\None.ruleset true diff --git a/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj b/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj index f869dbc6e9..ced919b1c7 100644 --- a/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj +++ b/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj @@ -8,8 +8,7 @@ - netcoreapp3.1 - + netcoreapp3.1 Full ..\None.ruleset Stratis Group Ltd. From c718c3623102963313ba615bfd601a52055adef5 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:14:35 +0100 Subject: [PATCH 08/16] Upgrade Newtonsoft --- src/NBitcoin/NBitcoin.csproj | 2 +- .../Stratis.Bitcoin.Features.Dns.Tests.csproj | 2 +- .../Stratis.Bitcoin.Features.Dns.csproj | 2 +- .../Stratis.Bitcoin.Features.PoA.Tests.csproj | 2 +- .../Stratis.SmartContracts.Core.csproj | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NBitcoin/NBitcoin.csproj b/src/NBitcoin/NBitcoin.csproj index e38ba62739..7caef24279 100644 --- a/src/NBitcoin/NBitcoin.csproj +++ b/src/NBitcoin/NBitcoin.csproj @@ -42,7 +42,7 @@ - + diff --git a/src/Stratis.Bitcoin.Features.Dns.Tests/Stratis.Bitcoin.Features.Dns.Tests.csproj b/src/Stratis.Bitcoin.Features.Dns.Tests/Stratis.Bitcoin.Features.Dns.Tests.csproj index f612a5d169..370753fd46 100644 --- a/src/Stratis.Bitcoin.Features.Dns.Tests/Stratis.Bitcoin.Features.Dns.Tests.csproj +++ b/src/Stratis.Bitcoin.Features.Dns.Tests/Stratis.Bitcoin.Features.Dns.Tests.csproj @@ -32,7 +32,7 @@ all runtime; build; native; contentfiles; analyzers - + diff --git a/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj b/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj index 69c66e015a..c650c30c08 100644 --- a/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj +++ b/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj @@ -21,7 +21,7 @@ - + diff --git a/src/Stratis.Bitcoin.Features.PoA.Tests/Stratis.Bitcoin.Features.PoA.Tests.csproj b/src/Stratis.Bitcoin.Features.PoA.Tests/Stratis.Bitcoin.Features.PoA.Tests.csproj index 33b0046f08..b0ecb79f45 100644 --- a/src/Stratis.Bitcoin.Features.PoA.Tests/Stratis.Bitcoin.Features.PoA.Tests.csproj +++ b/src/Stratis.Bitcoin.Features.PoA.Tests/Stratis.Bitcoin.Features.PoA.Tests.csproj @@ -13,7 +13,7 @@ all runtime; build; native; contentfiles; analyzers - + diff --git a/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj b/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj index 2173674f75..d4d0546b7f 100644 --- a/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj +++ b/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj @@ -14,7 +14,7 @@ - + From 1b74af5013692c99f4e48faea5d4ac1fbbdffa64 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:24:22 +0100 Subject: [PATCH 09/16] Upgrade Tracer.Fody --- .../Stratis.Bitcoin.Features.Api.csproj | 5 ++++- .../Stratis.Bitcoin.Features.BlockStore.csproj | 5 ++++- .../Stratis.Bitcoin.Features.ColdStaking.csproj | 5 ++++- .../Stratis.Bitcoin.Features.Consensus.csproj | 5 ++++- .../Stratis.Bitcoin.Features.Dns.csproj | 5 ++++- .../Stratis.Bitcoin.Features.LightWallet.csproj | 5 ++++- .../Stratis.Bitcoin.Features.MemoryPool.csproj | 5 ++++- .../Stratis.Bitcoin.Features.Miner.csproj | 5 ++++- .../Stratis.Bitcoin.Features.Notifications.csproj | 5 ++++- .../Stratis.Bitcoin.Features.RPC.csproj | 5 ++++- .../Stratis.Bitcoin.Features.SmartContracts.csproj | 2 +- .../Stratis.Bitcoin.Features.Wallet.csproj | 5 ++++- .../Stratis.Bitcoin.Features.WatchOnlyWallet.csproj | 5 ++++- src/Stratis.Bitcoin/Stratis.Bitcoin.csproj | 5 ++++- .../Stratis.Features.FederatedPeg.csproj | 2 +- .../Stratis.Features.SQLiteWalletRepository.csproj | 2 +- .../Stratis.SmartContracts.CLR.Validation.csproj | 2 +- .../Stratis.SmartContracts.CLR.csproj | 2 +- .../Stratis.SmartContracts.Networks.csproj | 2 +- .../Stratis.SmartContracts.RuntimeObserver.csproj | 2 +- 20 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.Api/Stratis.Bitcoin.Features.Api.csproj b/src/Stratis.Bitcoin.Features.Api/Stratis.Bitcoin.Features.Api.csproj index 9384e870ce..9e1d43f8b2 100644 --- a/src/Stratis.Bitcoin.Features.Api/Stratis.Bitcoin.Features.Api.csproj +++ b/src/Stratis.Bitcoin.Features.Api/Stratis.Bitcoin.Features.Api.csproj @@ -26,7 +26,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj b/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj index d43fd33a79..75cfe12704 100644 --- a/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj +++ b/src/Stratis.Bitcoin.Features.BlockStore/Stratis.Bitcoin.Features.BlockStore.csproj @@ -25,7 +25,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.ColdStaking/Stratis.Bitcoin.Features.ColdStaking.csproj b/src/Stratis.Bitcoin.Features.ColdStaking/Stratis.Bitcoin.Features.ColdStaking.csproj index 69fe08e4dc..60e65b852a 100644 --- a/src/Stratis.Bitcoin.Features.ColdStaking/Stratis.Bitcoin.Features.ColdStaking.csproj +++ b/src/Stratis.Bitcoin.Features.ColdStaking/Stratis.Bitcoin.Features.ColdStaking.csproj @@ -21,7 +21,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj b/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj index 3fd7df1f59..f75beb6686 100644 --- a/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj +++ b/src/Stratis.Bitcoin.Features.Consensus/Stratis.Bitcoin.Features.Consensus.csproj @@ -28,7 +28,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj b/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj index c650c30c08..ec34b470e8 100644 --- a/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj +++ b/src/Stratis.Bitcoin.Features.Dns/Stratis.Bitcoin.Features.Dns.csproj @@ -22,7 +22,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.LightWallet/Stratis.Bitcoin.Features.LightWallet.csproj b/src/Stratis.Bitcoin.Features.LightWallet/Stratis.Bitcoin.Features.LightWallet.csproj index 672eb646b2..938edd7f15 100644 --- a/src/Stratis.Bitcoin.Features.LightWallet/Stratis.Bitcoin.Features.LightWallet.csproj +++ b/src/Stratis.Bitcoin.Features.LightWallet/Stratis.Bitcoin.Features.LightWallet.csproj @@ -18,7 +18,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj b/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj index 29b593564a..a6729efd58 100644 --- a/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj +++ b/src/Stratis.Bitcoin.Features.MemoryPool/Stratis.Bitcoin.Features.MemoryPool.csproj @@ -25,7 +25,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.Miner/Stratis.Bitcoin.Features.Miner.csproj b/src/Stratis.Bitcoin.Features.Miner/Stratis.Bitcoin.Features.Miner.csproj index 998fbad7a2..1aadd5a7ff 100644 --- a/src/Stratis.Bitcoin.Features.Miner/Stratis.Bitcoin.Features.Miner.csproj +++ b/src/Stratis.Bitcoin.Features.Miner/Stratis.Bitcoin.Features.Miner.csproj @@ -28,7 +28,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj b/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj index 25d44eaa9d..95e5549baa 100644 --- a/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj +++ b/src/Stratis.Bitcoin.Features.Notifications/Stratis.Bitcoin.Features.Notifications.csproj @@ -25,7 +25,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.RPC/Stratis.Bitcoin.Features.RPC.csproj b/src/Stratis.Bitcoin.Features.RPC/Stratis.Bitcoin.Features.RPC.csproj index 22a07fd065..23cd89e203 100644 --- a/src/Stratis.Bitcoin.Features.RPC/Stratis.Bitcoin.Features.RPC.csproj +++ b/src/Stratis.Bitcoin.Features.RPC/Stratis.Bitcoin.Features.RPC.csproj @@ -33,7 +33,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj b/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj index f9d22ea2db..c23e4e6507 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Stratis.Bitcoin.Features.SmartContracts.csproj @@ -13,7 +13,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.Bitcoin.Features.Wallet/Stratis.Bitcoin.Features.Wallet.csproj b/src/Stratis.Bitcoin.Features.Wallet/Stratis.Bitcoin.Features.Wallet.csproj index d1e965015b..96602869d6 100644 --- a/src/Stratis.Bitcoin.Features.Wallet/Stratis.Bitcoin.Features.Wallet.csproj +++ b/src/Stratis.Bitcoin.Features.Wallet/Stratis.Bitcoin.Features.Wallet.csproj @@ -32,7 +32,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin.Features.WatchOnlyWallet/Stratis.Bitcoin.Features.WatchOnlyWallet.csproj b/src/Stratis.Bitcoin.Features.WatchOnlyWallet/Stratis.Bitcoin.Features.WatchOnlyWallet.csproj index f45affe2ea..d3bd132679 100644 --- a/src/Stratis.Bitcoin.Features.WatchOnlyWallet/Stratis.Bitcoin.Features.WatchOnlyWallet.csproj +++ b/src/Stratis.Bitcoin.Features.WatchOnlyWallet/Stratis.Bitcoin.Features.WatchOnlyWallet.csproj @@ -26,7 +26,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj b/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj index 08ac585564..eab96a08d1 100644 --- a/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj +++ b/src/Stratis.Bitcoin/Stratis.Bitcoin.csproj @@ -47,7 +47,10 @@ - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj b/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj index ced919b1c7..da59dffd33 100644 --- a/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj +++ b/src/Stratis.Features.FederatedPeg/Stratis.Features.FederatedPeg.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.Features.SQLiteWalletRepository/Stratis.Features.SQLiteWalletRepository.csproj b/src/Stratis.Features.SQLiteWalletRepository/Stratis.Features.SQLiteWalletRepository.csproj index 3a6a9e08e3..8f771c0667 100644 --- a/src/Stratis.Features.SQLiteWalletRepository/Stratis.Features.SQLiteWalletRepository.csproj +++ b/src/Stratis.Features.SQLiteWalletRepository/Stratis.Features.SQLiteWalletRepository.csproj @@ -36,7 +36,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj index 5a57b5d946..1b1fa89c61 100644 --- a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj +++ b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj @@ -11,7 +11,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj index c756f2c930..e3c58b6b8e 100644 --- a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj +++ b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj @@ -14,7 +14,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.Networks/Stratis.SmartContracts.Networks.csproj b/src/Stratis.SmartContracts.Networks/Stratis.SmartContracts.Networks.csproj index ffbcec7ebf..e99c4bf188 100644 --- a/src/Stratis.SmartContracts.Networks/Stratis.SmartContracts.Networks.csproj +++ b/src/Stratis.SmartContracts.Networks/Stratis.SmartContracts.Networks.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj b/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj index 12f340073b..13f8b7a1d0 100644 --- a/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj +++ b/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers From 8798cb1cba1725b2b34e6872af9ccfa952c6a0e9 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:35:14 +0100 Subject: [PATCH 10/16] Private Assets --- .../Stratis.SmartContracts.CLR.Validation.csproj | 2 +- .../Stratis.SmartContracts.CLR.csproj | 2 +- .../Stratis.SmartContracts.Core.csproj | 4 ++-- .../Stratis.SmartContracts.RuntimeObserver.csproj | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj index 1b1fa89c61..ec6ab3d146 100644 --- a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj +++ b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj @@ -12,7 +12,7 @@ - all + All runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj index e3c58b6b8e..320752dbce 100644 --- a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj +++ b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj @@ -15,7 +15,7 @@ - all + All runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj b/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj index d4d0546b7f..bc8db4bd99 100644 --- a/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj +++ b/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj @@ -17,8 +17,8 @@ - - all + + All runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj b/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj index 13f8b7a1d0..773ce0f0a1 100644 --- a/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj +++ b/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj @@ -9,7 +9,7 @@ - all + All runtime; build; native; contentfiles; analyzers From 04f4d24fb5b4a41de5b2b9c53d9e5a12debd571d Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:48:57 +0100 Subject: [PATCH 11/16] Upgrade Mono.Cecil --- .../Stratis.Bitcoin.Features.SmartContracts.Tests.csproj | 2 +- .../Stratis.SmartContracts.CLR.Validation.csproj | 4 ++-- .../Stratis.SmartContracts.CLR.csproj | 2 +- .../Stratis.SmartContracts.Core.csproj | 2 +- .../Stratis.SmartContracts.RuntimeObserver.csproj | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj index cc81741d55..29da85fcde 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj @@ -23,7 +23,7 @@ all runtime; build; native; contentfiles; analyzers - + diff --git a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj index ec6ab3d146..7d3cc100be 100644 --- a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj +++ b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj @@ -8,11 +8,11 @@ - + - All + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj index 320752dbce..e3c58b6b8e 100644 --- a/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj +++ b/src/Stratis.SmartContracts.CLR/Stratis.SmartContracts.CLR.csproj @@ -15,7 +15,7 @@ - All + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj b/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj index bc8db4bd99..488ddf3d51 100644 --- a/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj +++ b/src/Stratis.SmartContracts.Core/Stratis.SmartContracts.Core.csproj @@ -18,7 +18,7 @@ - All + all runtime; build; native; contentfiles; analyzers diff --git a/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj b/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj index 773ce0f0a1..13f8b7a1d0 100644 --- a/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj +++ b/src/Stratis.SmartContracts.RuntimeObserver/Stratis.SmartContracts.RuntimeObserver.csproj @@ -9,7 +9,7 @@ - All + all runtime; build; native; contentfiles; analyzers From 3361a4a99d665bcac32da070ae2e19da50526c07 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:53:47 +0100 Subject: [PATCH 12/16] Cecil version --- .../Stratis.Bitcoin.Features.SmartContracts.Tests.csproj | 2 +- .../Stratis.SmartContracts.CLR.Validation.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj index 29da85fcde..51c5b2038a 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/Stratis.Bitcoin.Features.SmartContracts.Tests.csproj @@ -23,7 +23,7 @@ all runtime; build; native; contentfiles; analyzers - + diff --git a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj index 7d3cc100be..6c078e8bd4 100644 --- a/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj +++ b/src/Stratis.SmartContracts.CLR.Validation/Stratis.SmartContracts.CLR.Validation.csproj @@ -8,7 +8,7 @@ - + From 9284cda409082a88ca564439356d514e680d5935 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 12:57:21 +0100 Subject: [PATCH 13/16] CI --- src/Stratis.StratisD/Program.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Stratis.StratisD/Program.cs b/src/Stratis.StratisD/Program.cs index 58348154c5..b22b5eab60 100644 --- a/src/Stratis.StratisD/Program.cs +++ b/src/Stratis.StratisD/Program.cs @@ -6,15 +6,14 @@ using Stratis.Bitcoin.Configuration; using Stratis.Bitcoin.Features.Api; using Stratis.Bitcoin.Features.BlockStore; +using Stratis.Bitcoin.Features.ColdStaking; using Stratis.Bitcoin.Features.Consensus; using Stratis.Bitcoin.Features.MemoryPool; using Stratis.Bitcoin.Features.Miner; using Stratis.Bitcoin.Features.RPC; -using Stratis.Bitcoin.Features.ColdStaking; using Stratis.Bitcoin.Features.SignalR; using Stratis.Bitcoin.Features.SignalR.Broadcasters; using Stratis.Bitcoin.Features.SignalR.Events; -using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Networks; using Stratis.Bitcoin.Utilities; using Stratis.Features.Diagnostic; @@ -28,8 +27,7 @@ public static async Task Main(string[] args) { try { - var nodeSettings = new NodeSettings(networksSelector: Networks.Stratis, - protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, args: args) + var nodeSettings = new NodeSettings(networksSelector: Networks.Stratis, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, args: args) { MinProtocolVersion = ProtocolVersion.ALT_PROTOCOL_VERSION }; From b7000a681706e6d8bc6944b1484f108fc488194f Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Fri, 21 Aug 2020 13:24:59 +0100 Subject: [PATCH 14/16] Fix tests --- .../ColdStakingControllerTest.cs | 4 ++-- .../Controllers/ColdStakingController.cs | 10 ++++++++-- .../SmartContractTransactionServiceTests.cs | 18 +++++++++-------- .../WalletTransactionHandlerTest.cs | 20 +++++++++---------- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs b/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs index 672ef283ab..9cf830cbaf 100644 --- a/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs +++ b/src/Stratis.Bitcoin.Features.ColdStaking.Tests/ColdStakingControllerTest.cs @@ -27,8 +27,8 @@ using Stratis.Bitcoin.Features.MemoryPool.Rules; using Stratis.Bitcoin.Features.Wallet; using Stratis.Bitcoin.Features.Wallet.Interfaces; -using Stratis.Bitcoin.Networks.Policies; using Stratis.Bitcoin.Features.Wallet.Services; +using Stratis.Bitcoin.Networks.Policies; using Stratis.Bitcoin.Signals; using Stratis.Bitcoin.Tests.Common; using Stratis.Bitcoin.Utilities; @@ -234,7 +234,7 @@ private void Initialize([System.Runtime.CompilerServices.CallerMemberName] strin new Mock().Object, new Mock().Object, new NodeLifetime(), scriptDestinationReader, this.loggerFactory, DateTimeProvider.Default, walletRepository); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.loggerFactory, this.coldStakingManager, new Mock().Object, this.Network, new StandardTransactionPolicy(this.Network), reserveUtxoService); diff --git a/src/Stratis.Bitcoin.Features.ColdStaking/Controllers/ColdStakingController.cs b/src/Stratis.Bitcoin.Features.ColdStaking/Controllers/ColdStakingController.cs index 47fdc42da2..0d116d6031 100644 --- a/src/Stratis.Bitcoin.Features.ColdStaking/Controllers/ColdStakingController.cs +++ b/src/Stratis.Bitcoin.Features.ColdStaking/Controllers/ColdStakingController.cs @@ -209,8 +209,14 @@ public IActionResult SetupColdStaking([FromBody]SetupColdStakingRequest request) Money feeAmount = Money.Parse(request.Fees); Transaction transaction = this.ColdStakingManager.GetColdStakingSetupTransaction( - this.walletTransactionHandler, request.ColdWalletAddress, request.HotWalletAddress, - request.WalletName, request.WalletAccount, request.WalletPassword, amount, feeAmount); + this.walletTransactionHandler, + request.ColdWalletAddress, + request.HotWalletAddress, + request.WalletName, + request.WalletAccount, + request.WalletPassword, + amount, + feeAmount); var model = new SetupColdStakingResponse { diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs index 52019a4631..1cd6b95b2a 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using Moq; using NBitcoin; +using Stratis.Bitcoin.Configuration.Logging; using Stratis.Bitcoin.Features.SmartContracts.Models; using Stratis.Bitcoin.Features.SmartContracts.Wallet; using Stratis.Bitcoin.Features.Wallet; @@ -22,6 +23,7 @@ namespace Stratis.Bitcoin.Features.SmartContracts.Tests { public class SmartContractTransactionServiceTests { + private readonly ILoggerFactory loggerFactory = new ExtendedLoggerFactory(); private readonly Network network; private readonly Mock walletManager = new Mock(); private readonly Mock walletTransactionHandler; @@ -115,7 +117,7 @@ public void CanChooseInputsForCall() this.walletManager.Setup(x => x.GetWallet(request.WalletName)) .Returns(wallet); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -198,7 +200,7 @@ public void ChoosingInvalidInputFails() } }); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -291,7 +293,7 @@ public void CanChooseInputsForCreate() this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny())) .Returns(Result.Ok(new ContractTxData(1, 100, (Gas)100_000, new byte[0]))); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -313,7 +315,7 @@ public void BuildTransferContext_SenderNotInWallet_Fails() { string senderAddress = uint160.Zero.ToBase58Address(this.network); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -353,7 +355,7 @@ public void BuildTransferContext_AccountNotInWallet_Fails() { string senderAddress = uint160.Zero.ToBase58Address(this.network); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -393,7 +395,7 @@ public void BuildTransferContext_SenderHasNoBalance_Fails() { string senderAddress = uint160.Zero.ToBase58Address(this.network); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -440,7 +442,7 @@ public void BuildTransferContext_RecipientIsKnownContract_Fails() string senderAddress = uint160.Zero.ToBase58Address(this.network); string recipientAddress = uint160.One.ToBase58Address(this.network); - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, @@ -658,7 +660,7 @@ public void BuildTransferContextCorrectly() } }; - var reserveUtxoService = new ReserveUtxoService(new Mock().Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var service = new SmartContractTransactionService( this.network, diff --git a/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs b/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs index 50dd485d64..ef023bf4e8 100644 --- a/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs +++ b/src/Stratis.Bitcoin.Features.Wallet.Tests/WalletTransactionHandlerTest.cs @@ -4,11 +4,13 @@ using System.Text; using DBreeze.Utils; using FluentAssertions; +using Microsoft.Extensions.Logging; using Moq; using NBitcoin; using NBitcoin.Policy; using Stratis.Bitcoin.AsyncWork; using Stratis.Bitcoin.Configuration; +using Stratis.Bitcoin.Configuration.Logging; using Stratis.Bitcoin.Consensus; using Stratis.Bitcoin.Features.Wallet.Interfaces; using Stratis.Bitcoin.Features.Wallet.Services; @@ -24,8 +26,8 @@ namespace Stratis.Bitcoin.Features.Wallet.Tests { public class WalletTransactionHandlerTest : LogsTestBase { - private readonly IBlockStore blockStore; private readonly string costlyOpReturnData; + private readonly ILoggerFactory loggerFactory = new ExtendedLoggerFactory(); private readonly IScriptAddressReader scriptAddressReader; private readonly StandardTransactionPolicy standardTransactionPolicy; @@ -35,8 +37,6 @@ public WalletTransactionHandlerTest() // 83 is the max size for the OP_RETURN script => 80 is the max for the content of the script byte[] maxQuantityOfBytes = Enumerable.Range(0, 80).Select(Convert.ToByte).ToArray(); this.costlyOpReturnData = Encoding.UTF8.GetString(maxQuantityOfBytes); - - this.blockStore = new Mock().Object; this.standardTransactionPolicy = new StandardTransactionPolicy(this.Network); this.scriptAddressReader = new ScriptAddressReader(); } @@ -46,7 +46,7 @@ public void BuildTransactionThrowsWalletExceptionWhenMoneyIsZero() { Assert.Throws(() => { - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, new Mock().Object, new Mock().Object, this.Network, this.standardTransactionPolicy, reserveUtxoService); @@ -304,7 +304,7 @@ public void Given_AnInvalidAccountIsUsed_When_GetMaximumSpendableAmountIsCalled_ walletManager.Start(); - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); @@ -330,7 +330,7 @@ public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoSpendableFoun walletManager.Start(); - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); @@ -363,7 +363,7 @@ public void GetMaximumSpendableAmountReturnsAsZeroIfNoConfirmedTransactions() var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, new ChainIndexer(this.Network), new WalletSettings(NodeSettings.Default(this.Network)), dataFolder, new Mock().Object, new Mock().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader, walletRepository); - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); @@ -403,7 +403,7 @@ public void GetMaximumSpendableAmountReturnsSumOfUnconfirmedWhenNoConfirmedSpend walletManager.Start(); - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy, reserveUtxoService); @@ -437,7 +437,7 @@ public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoTransactions_ walletManager.Start(); - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny(), this.Network, this.standardTransactionPolicy, reserveUtxoService); @@ -570,7 +570,7 @@ private WalletTransactionHandlerTestContext SetupWallet(FeeRate feeRate = null, new WalletSettings(NodeSettings.Default(this.Network)), dataFolder, walletFeePolicy.Object, new Mock().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader, walletRepository); - var reserveUtxoService = new ReserveUtxoService(this.LoggerFactory.Object, new Mock().Object); + var reserveUtxoService = new ReserveUtxoService(this.loggerFactory, new Mock().Object); var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy, reserveUtxoService); From 5c25caac7524f79c35d8b41641c7b3ce5a978435 Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Sat, 22 Aug 2020 07:12:04 +0100 Subject: [PATCH 15/16] Fix Tests --- .../TestPoAMiner.cs | 3 - .../SmartContractTransactionServiceTests.cs | 2 +- .../Wallet/SmartContractTransactionService.cs | 2 +- .../Compatibility/StratisXTests.cs | 529 ------------------ .../ContractUpgradeabilityTests.cs | 14 +- .../Stratis.SmartContracts.CLR.Tests.csproj | 3 + .../MockChain/MockChainNode.cs | 12 - 7 files changed, 12 insertions(+), 553 deletions(-) delete mode 100644 src/Stratis.Bitcoin.IntegrationTests/Compatibility/StratisXTests.cs diff --git a/src/Stratis.Bitcoin.Features.PoA.IntegrationTests.Common/TestPoAMiner.cs b/src/Stratis.Bitcoin.Features.PoA.IntegrationTests.Common/TestPoAMiner.cs index 71c73f0a1d..ecaada28d3 100644 --- a/src/Stratis.Bitcoin.Features.PoA.IntegrationTests.Common/TestPoAMiner.cs +++ b/src/Stratis.Bitcoin.Features.PoA.IntegrationTests.Common/TestPoAMiner.cs @@ -24,8 +24,6 @@ public class TestPoAMiner : PoAMiner private readonly ISlotsManager slotsManager; - private readonly IConsensusManager consensusManager; - public TestPoAMiner( IConsensusManager consensusManager, IDateTimeProvider dateTimeProvider, @@ -50,7 +48,6 @@ public TestPoAMiner( this.cancellation = new CancellationTokenSource(); this.slotsManager = slotsManager; - this.consensusManager = consensusManager; } public override void InitializeMining() diff --git a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs index 1cd6b95b2a..f43221a48b 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts.Tests/SmartContractTransactionServiceTests.cs @@ -214,7 +214,7 @@ public void ChoosingInvalidInputFails() BuildCallContractTransactionResponse result = service.BuildCallTx(request); Assert.False(result.Success); - Assert.StartsWith("Invalid list of request outpoints", result.Message); + Assert.StartsWith("An invalid list of request outpoints", result.Message); } [Fact] diff --git a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs index 5188f66aba..81b008a0c4 100644 --- a/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs +++ b/src/Stratis.Bitcoin.Features.SmartContracts/Wallet/SmartContractTransactionService.cs @@ -366,7 +366,7 @@ private bool CheckBalance(string address) { selectedInputs = this.ReduceToRequestedInputs(requestedOutpoints, selectedInputs); if (!selectedInputs.Any()) - return (selectedInputs, "And invalid list of request outpoints have been passed to the method, please ensure that the outpoints are spendable by the sender address."); + return (selectedInputs, "An invalid list of request outpoints have been passed to the method, please ensure that the outpoints are spendable by the sender address."); } selectedInputs = FilterReservedInputs(selectedInputs); diff --git a/src/Stratis.Bitcoin.IntegrationTests/Compatibility/StratisXTests.cs b/src/Stratis.Bitcoin.IntegrationTests/Compatibility/StratisXTests.cs deleted file mode 100644 index a486614513..0000000000 --- a/src/Stratis.Bitcoin.IntegrationTests/Compatibility/StratisXTests.cs +++ /dev/null @@ -1,529 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Threading; -using NBitcoin; -using NBitcoin.Protocol; -using Stratis.Bitcoin.Builder; -using Stratis.Bitcoin.Features.BlockStore; -using Stratis.Bitcoin.Features.Consensus; -using Stratis.Bitcoin.Features.MemoryPool; -using Stratis.Bitcoin.Features.Miner; -using Stratis.Bitcoin.Features.RPC; -using Stratis.Bitcoin.Features.Wallet; -using Stratis.Bitcoin.Features.Wallet.Controllers; -using Stratis.Bitcoin.Features.Wallet.Models; -using Stratis.Bitcoin.IntegrationTests.Common; -using Stratis.Bitcoin.IntegrationTests.Common.EnvironmentMockUpHelpers; -using Stratis.Bitcoin.IntegrationTests.Common.ReadyData; -using Stratis.Bitcoin.IntegrationTests.Common.TestNetworks; -using Stratis.Bitcoin.Networks; -using Stratis.Bitcoin.Tests.Common; -using Stratis.Features.SQLiteWalletRepository; -using Xunit; - -namespace Stratis.Bitcoin.IntegrationTests.Compatibility -{ - public class StratisXTests - { - /// - /// Tests whether a quantity of blocks mined on SBFN are - /// correctly synced to a stratisX node. - /// - [Fact(Skip = "Takes a long time to run with SBFN making blocks. Need to investigate why.")] - public void SBFNMinesBlocks_XSyncs() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this)) - { - var network = new StratisRegTest(); - - CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - CoreNode stratisNode = builder.CreateStratisPosNode(network).WithWallet().Start(); - - RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); - RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); - - // TODO: Need to troubleshoot why TestHelper.Connect() does not work here, possibly unsupported RPC method (it seems that addnode does not work for X). - stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); - - // TODO: Similarly, the 'generate' RPC call is problematic on X. Possibly returning an unexpected JSON format. - TestHelper.MineBlocks(stratisNode, 10); - - // As we are not actually sending transactions, it does not matter that the datetime provider is substituted - // for this test. The blocks get accepted by X despite getting generated very rapidly. - var cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; - - TestBase.WaitLoop(() => stratisNodeRpc.GetBlockCount() >= 10, cancellationToken: cancellationToken); - TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: cancellationToken); - } - } - - /// - /// Tests whether a quantity of blocks mined on X are - /// correctly synced to an SBFN node. - /// - [Fact] - public void XMinesBlocks_SBFNSyncs() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this).WithLogsEnabled()) - { - var network = new StratisRegTest(); - - CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - var callback = new Action(build => build - .UseBlockStore() - .UsePosConsensus() - .UseMempool() - .UseWallet() - .AddSQLiteWalletRepository() - .AddPowPosMining() - .AddRPC()); - - var config = new NodeConfigParameters(); - config.Add("whitelist", stratisXNode.Endpoint.ToString()); - config.Add("gateway", "1"); - - CoreNode stratisNode = builder - .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION, configParameters: config) - .WithWallet().Start(); - - RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); - RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); - - stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); - - stratisXRpc.SendCommand(RPCOperations.generate, 10); - - var cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; - - TestBase.WaitLoop(() => stratisXRpc.GetBlockCount() >= 10, cancellationToken: cancellationToken); - TestBase.WaitLoop(() => stratisXRpc.GetBestBlockHash() == stratisNodeRpc.GetBestBlockHash(), cancellationToken: cancellationToken); - } - } - - /// - /// Tests whether a transaction relayed by SBFN appears in the - /// stratisX mempool. The transaction is then mined into a - /// block by SBFN, and the block must be accepted by stratisX. - /// - /// Takes a while to run as block generation cannot - /// be sped up for this test. - [Fact(Skip = "Awaiting fix for issue #2468")] - public void SBFNMinesTransaction_XSyncs() - { - // TODO: Currently fails due to issue #2468 (coinbase - // reward on stratisX cannot be >4. No fees are allowed) - - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this)) - { - var network = new StratisRegTest(); - - CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - // We do not want the datetime provider to be substituted, - // so a custom builder callback has to be used. - var callback = new Action(build => build - .UseBlockStore() - .UsePosConsensus() - .UseMempool() - .UseWallet() - .AddSQLiteWalletRepository() - .AddPowPosMining() - .AddRPC() - .UseTestChainedHeaderTree() - .MockIBD()); - - CoreNode stratisNode = builder.CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION).WithWallet().Start(); - - RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); - RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); - - stratisXRpc.AddNode(stratisNode.Endpoint, false); - stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); - - TestHelper.MineBlocks(stratisNode, 11); - - // It takes a reasonable amount of time for blocks to be generated without - // the datetime provider substitution. - var longCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(15)).Token; - var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; - - TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: longCancellationToken); - - // Send transaction to arbitrary address from SBFN side. - var alice = new Key().GetBitcoinSecret(network); - var aliceAddress = alice.GetAddress(); - stratisNodeRpc.WalletPassphrase("password", 60); - stratisNodeRpc.SendToAddress(aliceAddress, Money.Coins(1.0m)); - - TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - - // Transaction should percolate through to X's mempool. - TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - - // Now SBFN must mine the block. - TestHelper.MineBlocks(stratisNode, 1); - - // We expect that X will sync correctly. - TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: shortCancellationToken); - - // Sanity check - mempools should both become empty. - TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - } - } - - /// - /// This test is necessary because X regards nulldata transactions as non-standard if they have a value of zero assigned. - /// - [Fact] - public void SBFNCreatesOpReturnTransaction_XSyncs() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this)) - { - var network = new StratisRegTest(); - - CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - // We do not want the datetime provider to be substituted, - // so a custom builder callback has to be used. - var callback = new Action(build => build - .UseBlockStore() - .UsePosConsensus() - .UseMempool() - .UseWallet() - .AddSQLiteWalletRepository() - .AddPowPosMining() - .AddRPC() - .UseTestChainedHeaderTree() - .MockIBD()); - - CoreNode stratisNode = builder.CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION, minProtocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION).WithWallet().Start(); - - RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); - RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); - - stratisXRpc.AddNode(stratisNode.Endpoint, false); - stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); - - TestHelper.MineBlocks(stratisNode, 11); - - // It takes a reasonable amount of time for blocks to be generated without - // the datetime provider substitution. - var longCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(15)).Token; - var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; - - TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: longCancellationToken); - - // Send transaction to arbitrary address from SBFN side. - var alice = new Key().GetBitcoinSecret(network); - var aliceAddress = alice.GetAddress(); - //stratisNodeRpc.WalletPassphrase("password", 60); - - var transactionBuildContext = new TransactionBuildContext(stratisNode.FullNode.Network) - { - AccountReference = new WalletAccountReference("mywallet", "account 0"), - MinConfirmations = 1, - OpReturnData = "test", - OpReturnAmount = Money.Coins(0.01m), - WalletPassword = "password", - Recipients = new List() { new Recipient() { Amount = Money.Coins(1), ScriptPubKey = aliceAddress.ScriptPubKey } } - }; - - var transaction = stratisNode.FullNode.WalletTransactionHandler().BuildTransaction(transactionBuildContext); - - stratisNode.FullNode.NodeController().SendTransaction(new SendTransactionRequest(transaction.ToHex())); - - TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - - // Transaction should percolate through to X's mempool. - TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - } - } - - [Fact] - public void XMinesTransaction_SBFNSyncs() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this)) - { - var network = new StratisRegTest(); - - CoreNode stratisXNode = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - var callback = new Action(build => build - .UseBlockStore() - .UsePosConsensus() - .UseMempool() - .UseWallet() - .AddSQLiteWalletRepository() - .AddPowPosMining() - .AddRPC()); - - var config = new NodeConfigParameters(); - config.Add("whitelist", stratisXNode.Endpoint.ToString()); - config.Add("gateway", "1"); - - CoreNode stratisNode = builder - .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION, configParameters: config) - .WithWallet().Start(); - - RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); - RPCClient stratisNodeRpc = stratisNode.CreateRPCClient(); - - stratisXRpc.AddNode(stratisNode.Endpoint, false); - stratisNodeRpc.AddNode(stratisXNode.Endpoint, false); - - stratisXRpc.SendCommand(RPCOperations.generate, 11); - - var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token; - - // Without this there seems to be a race condition between the blocks all getting generated and SBFN syncing high enough to fall through the getbestblockhash check. - TestBase.WaitLoop(() => stratisXRpc.GetBlockCount() >= 11, cancellationToken: shortCancellationToken); - - TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: shortCancellationToken); - - // Send transaction to arbitrary address from X side. - var alice = new Key().GetBitcoinSecret(network); - var aliceAddress = alice.GetAddress(); - stratisXRpc.SendCommand(RPCOperations.sendtoaddress, aliceAddress.ToString(), 1); - - TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - - // Transaction should percolate through to SBFN's mempool. - TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - - // Now X must mine the block. - stratisXRpc.SendCommand(RPCOperations.generate, 1); - TestBase.WaitLoop(() => stratisXRpc.GetBlockCount() >= 12, cancellationToken: shortCancellationToken); - - // We expect that SBFN will sync correctly. - TestBase.WaitLoop(() => stratisNodeRpc.GetBestBlockHash() == stratisXRpc.GetBestBlockHash(), cancellationToken: shortCancellationToken); - - // Sanity check - mempools should both become empty. - TestBase.WaitLoop(() => stratisNodeRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => stratisXRpc.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - } - } - - /// - /// Construct a small network of 3 nodes, X1 - S2 -X3. - /// X1 generates sufficient blocks to get spendable coins. - /// X1 creates a transaction sending a coin to an arbitrary address. - /// S2 and X3 should get the transaction in their mempools. - /// - [Fact] - [Trait("Unstable", "True")] - public void Transaction_CreatedByXNode_TraversesSBFN_ReachesSecondXNode() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this)) - { - var network = new StratisRegTest(); - - CoreNode xNode1 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - var callback = new Action(build => build - .UseBlockStore() - .UsePosConsensus() - .UseMempool() - .UseWallet() - .AddSQLiteWalletRepository() - .AddPowPosMining() - .AddRPC()); - - var config = new NodeConfigParameters(); - config.Add("whitelist", xNode1.Endpoint.ToString()); - config.Add("gateway", "1"); - - CoreNode sbfnNode2 = builder - .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION, configParameters: config) - .WithWallet().Start(); - - CoreNode xNode3 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - RPCClient xRpc1 = xNode1.CreateRPCClient(); - RPCClient sbfnRpc2 = sbfnNode2.CreateRPCClient(); - RPCClient xRpc3 = xNode3.CreateRPCClient(); - - // Connect the nodes linearly. X does not appear to respond properly to the addnode RPC so SBFN needs to initiate. - sbfnRpc2.AddNode(xNode1.Endpoint, false); - sbfnRpc2.AddNode(xNode3.Endpoint, false); - - xRpc1.SendCommand(RPCOperations.generate, 11); - - var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; - - TestBase.WaitLoop(() => xRpc1.GetBlockCount() >= 11, cancellationToken: shortCancellationToken); - - TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == sbfnRpc2.GetBestBlockHash(), cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == xRpc3.GetBestBlockHash(), cancellationToken: shortCancellationToken); - - // Send transaction to arbitrary address. - var alice = new Key().GetBitcoinSecret(network); - var aliceAddress = alice.GetAddress(); - xRpc1.SendCommand(RPCOperations.sendtoaddress, aliceAddress.ToString(), 1); - - TestBase.WaitLoop(() => xRpc1.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => sbfnRpc2.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => xRpc3.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - } - } - - [Fact] - public void GatewayNodeCanSyncBeforeAndAfterLastCheckpointPowAndPoS() - { - Network network = new StratisMain10KCheckpoint(); - - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this).WithLogsEnabled()) - { - CoreNode stratisXNode = builder.CreateMainnetStratisXNode() - .WithReadyBlockchainData(ReadyBlockchain.StratisXMainnet15K); - - var gatewayParameters = new NodeConfigParameters(); - gatewayParameters.Add("regtest", "0"); - gatewayParameters.Add("gateway", "1"); - gatewayParameters.Add("txindex", "0"); - gatewayParameters.Add("whitelist", stratisXNode.Endpoint.ToString()); - CoreNode gatewayNode = - builder.CreateStratisPosNode(network, configParameters: gatewayParameters, isGateway: true) - .WithReadyBlockchainData(ReadyBlockchain.StratisMainnet9500); - - gatewayNode.Start(); - stratisXNode.Start(); - - RPCClient stratisXRpc = stratisXNode.CreateRPCClient(); - RPCClient gatewayNodeRpc = gatewayNode.CreateRPCClient(); - - gatewayNodeRpc.AddNode(stratisXNode.Endpoint); - - TestBase.WaitLoop(() => gatewayNode.FullNode.ChainIndexer.Height >= 13_000, waitTimeSeconds: 600); - } - } - - /// - /// Construct a small network of 3 nodes, X1 - S2 -X3. - /// X1 generates sufficient blocks to get spendable coins. - /// X1 creates a transaction sending a coin to an arbitrary address. - /// S2 and X3 should get the transaction in their mempools. - /// Now X1 mines a block. - /// S2 and X3 should sync to the new block height. - /// All mempools should be empty at the end. - /// - [Fact] - [Trait("Unstable", "True")] - public void Transaction_TraversesNodes_AndIsMined_AndNodesSync() - { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // TODO: Add the necessary executables for Linux & OSX - return; - } - - using (NodeBuilder builder = NodeBuilder.Create(this)) - { - var network = new StratisRegTest(); - - CoreNode xNode1 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - var callback = new Action(build => build - .UseBlockStore() - .UsePosConsensus() - .UseMempool() - .UseWallet() - .AddSQLiteWalletRepository() - .AddPowPosMining() - .AddRPC()); - - var config = new NodeConfigParameters(); - config.Add("whitelist", xNode1.Endpoint.ToString()); - config.Add("gateway", "1"); - - CoreNode sbfnNode2 = builder - .CreateCustomNode(callback, network, protocolVersion: ProtocolVersion.PROVEN_HEADER_VERSION, minProtocolVersion: ProtocolVersion.ALT_PROTOCOL_VERSION, configParameters: config) - .WithWallet().Start(); - - CoreNode xNode3 = builder.CreateStratisXNode(version: "2.0.0.5").Start(); - - RPCClient xRpc1 = xNode1.CreateRPCClient(); - RPCClient sbfnRpc2 = sbfnNode2.CreateRPCClient(); - RPCClient xRpc3 = xNode3.CreateRPCClient(); - - sbfnRpc2.AddNode(xNode1.Endpoint, false); - sbfnRpc2.AddNode(xNode3.Endpoint, false); - - xRpc1.SendCommand(RPCOperations.generate, 11); - - var shortCancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(1)).Token; - - TestBase.WaitLoop(() => xRpc1.GetBlockCount() >= 11, cancellationToken: shortCancellationToken); - - TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == sbfnRpc2.GetBestBlockHash(), cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => xRpc1.GetBestBlockHash() == xRpc3.GetBestBlockHash(), cancellationToken: shortCancellationToken); - - // Send transaction to arbitrary address. - var alice = new Key().GetBitcoinSecret(network); - var aliceAddress = alice.GetAddress(); - xRpc1.SendCommand(RPCOperations.sendtoaddress, aliceAddress.ToString(), 1); - - TestBase.WaitLoop(() => xRpc1.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => sbfnRpc2.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => xRpc3.GetRawMempool().Length == 1, cancellationToken: shortCancellationToken); - - // TODO: Until #2468 is fixed we need an X node to mine the block so it doesn't get rejected. - xRpc1.SendCommand(RPCOperations.generate, 1); - TestBase.WaitLoop(() => xRpc1.GetBlockCount() >= 12, cancellationToken: shortCancellationToken); - - // We expect that SBFN and the other X node will sync correctly. - TestBase.WaitLoop(() => sbfnRpc2.GetBestBlockHash() == xRpc1.GetBestBlockHash(), cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => xRpc3.GetBestBlockHash() == xRpc1.GetBestBlockHash(), cancellationToken: shortCancellationToken); - - // Sanity check - mempools should all become empty. - TestBase.WaitLoop(() => xRpc1.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => sbfnRpc2.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - TestBase.WaitLoop(() => xRpc3.GetRawMempool().Length == 0, cancellationToken: shortCancellationToken); - } - } - } -} \ No newline at end of file diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs index 4ee2aa4574..4d40d5f84d 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs @@ -64,7 +64,7 @@ public static bool Load(Assembly assembly) var references = new List { - MetadataReference.CreateFromFile(Path.Combine(basePath, "Packages", "netcoreapp3.0", "System.Runtime.dll")), + MetadataReference.CreateFromFile(Path.Combine(basePath, "Packages", "netcoreapp2.1", "System.Runtime.dll")), }; // Stratis.SmartContracts.SmartContract with the constructor removed @@ -73,7 +73,7 @@ public static bool Load(Assembly assembly) // Version 2.0.0-TEST adds string TestMethod() to Stratis.SmartContracts.SmartContract // and GetString() to Stratis.SmartContracts.ISmartContractState var version2DllPath = Path.Combine(basePath, "Packages", "4.0.0-TEST", "Stratis.SmartContracts.dll"); - + references.Add(MetadataReference.CreateFromFile(version1DllPath)); SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(source); @@ -91,7 +91,7 @@ public static bool Load(Assembly assembly) using (var dllStream = new MemoryStream()) { EmitResult emitResult = compilation.Emit(dllStream); - + Assert.True(emitResult.Success); version1CompiledContract = dllStream.ToArray(); @@ -112,9 +112,9 @@ public static bool Load(Assembly assembly) var version2Assembly = alc.LoadFromAssemblyPath(version2DllPath); Assert.Equal(Version.Parse("4.0.0.0"), version2Assembly.GetName().Version); - + Assembly loaderAssembly; - + using (var dllStream = new MemoryStream()) { EmitResult emitResult = loaderCompilation.Emit(dllStream); @@ -125,7 +125,7 @@ public static bool Load(Assembly assembly) loaderAssembly = alc.LoadFromStream(dllStream); } - var version1ContractMemoryStream = new MemoryStream(version1CompiledContract); + var version1ContractMemoryStream = new MemoryStream(version1CompiledContract); var version1ContractAssembly = alc.LoadFromStream(version1ContractMemoryStream); version1ContractMemoryStream.Dispose(); @@ -133,7 +133,7 @@ public static bool Load(Assembly assembly) var loaderMethod = loaderType.GetMethod("Load"); - var version2MethodInvocationResult = (bool) loaderMethod.Invoke(null, new [] { version1ContractAssembly }); + var version2MethodInvocationResult = (bool)loaderMethod.Invoke(null, new[] { version1ContractAssembly }); // If this condition is not null, we have a v1 contract referencing a v2 assembly and a successful // invocation of a method that only exists on v2 diff --git a/src/Stratis.SmartContracts.CLR.Tests/Stratis.SmartContracts.CLR.Tests.csproj b/src/Stratis.SmartContracts.CLR.Tests/Stratis.SmartContracts.CLR.Tests.csproj index 4d45a07bf2..27e2752acb 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/Stratis.SmartContracts.CLR.Tests.csproj +++ b/src/Stratis.SmartContracts.CLR.Tests/Stratis.SmartContracts.CLR.Tests.csproj @@ -146,6 +146,9 @@ Always + + Always + Always diff --git a/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs b/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs index e6be24a4fc..2292c12db8 100644 --- a/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs +++ b/src/Stratis.SmartContracts.Tests.Common/MockChain/MockChainNode.cs @@ -23,7 +23,6 @@ using Stratis.SmartContracts.CLR.Local; using Stratis.SmartContracts.Core; using Stratis.SmartContracts.Core.State; -using Xunit; namespace Stratis.SmartContracts.Tests.Common.MockChain { @@ -107,17 +106,6 @@ public void MineBlocks(int amountOfBlocks) { TestHelper.MineBlocks(this.CoreNode, amountOfBlocks); this.chain.WaitForAllNodesToSync(); - - int spendable = GetSpendableBlocks(amountOfBlocks, this.CoreNode.FullNode.Network.Consensus.CoinbaseMaturity); - Assert.Equal(Money.COIN * spendable * 50, (long)this.WalletSpendableBalance); - } - - /// - /// Given an amount of blocks and a maturity, how many blocks have spendable coinbase / coinstakes. - /// - private static int GetSpendableBlocks(int mined, long maturity) - { - return mined - (int)maturity; } public ulong GetWalletAddressBalance(string walletAddress) From 9c009c151f24ddbad9d16bd61af2645d2dd5792b Mon Sep 17 00:00:00 2001 From: Francois de la Rouviere Date: Mon, 24 Aug 2020 07:57:57 +0100 Subject: [PATCH 16/16] Update ContractUpgradeabilityTests.cs --- .../ContractUpgradeabilityTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs b/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs index 3b64af1d6c..03d359e561 100644 --- a/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs +++ b/src/Stratis.SmartContracts.CLR.Tests/ContractUpgradeabilityTests.cs @@ -78,7 +78,7 @@ public static bool Load(Assembly assembly) SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(source); - CSharpCompilation compilation = CSharpCompilation.Create( + var compilation = CSharpCompilation.Create( "smartContract", new[] { syntaxTree }, references, @@ -99,7 +99,7 @@ public static bool Load(Assembly assembly) SyntaxTree syntaxTreeLoader = CSharpSyntaxTree.ParseText(loader); - CSharpCompilation loaderCompilation = CSharpCompilation.Create( + var loaderCompilation = CSharpCompilation.Create( "loader", new[] { syntaxTreeLoader }, references, @@ -109,7 +109,7 @@ public static bool Load(Assembly assembly) var alc = new TestAssemblyLoadContext(); - var version2Assembly = alc.LoadFromAssemblyPath(version2DllPath); + Assembly version2Assembly = alc.LoadFromAssemblyPath(version2DllPath); Assert.Equal(Version.Parse("4.0.0.0"), version2Assembly.GetName().Version); @@ -126,12 +126,12 @@ public static bool Load(Assembly assembly) } var version1ContractMemoryStream = new MemoryStream(version1CompiledContract); - var version1ContractAssembly = alc.LoadFromStream(version1ContractMemoryStream); + Assembly version1ContractAssembly = alc.LoadFromStream(version1ContractMemoryStream); version1ContractMemoryStream.Dispose(); - var loaderType = loaderAssembly.ExportedTypes.First(t => t.Name == "TestLoader"); + Type loaderType = loaderAssembly.ExportedTypes.First(t => t.Name == "TestLoader"); - var loaderMethod = loaderType.GetMethod("Load"); + MethodInfo loaderMethod = loaderType.GetMethod("Load"); var version2MethodInvocationResult = (bool)loaderMethod.Invoke(null, new[] { version1ContractAssembly });