Пример #1
0
        public void GenerateBlocksOn_PowNetwork_ReturnsSuccess()
        {
            var powNode = new Mock <IFullNode>();

            var consensusManager = new Mock <IConsensusManager>();

            var walletManager = new Mock <IWalletManager>();

            walletManager.Setup(f => f.GetWalletsNames()).Returns(new List <string> {
                wallet
            });
            walletManager.Setup(f => f.GetAccounts(wallet)).Returns(new List <HdAccount> {
                new HdAccount {
                    Name = account
                }
            });
            HdAddress address = WalletTestsHelpers.CreateAddress();

            walletManager.Setup(f => f.GetUnusedAddress(new WalletAccountReference(wallet, account))).Returns(address);

            var powMining = new Mock <IPowMining>();

            powMining.Setup(f => f.GenerateBlocks(It.Is <ReserveScript>(r => r.ReserveFullNodeScript == address.Pubkey), 1, int.MaxValue)).Returns(new List <uint256> {
                new uint256(1255632623)
            });
            powNode.Setup(f => f.NodeFeature <MiningFeature>(false)).Returns(new MiningFeature(new ConnectionManagerSettings(NodeSettings.Default(this.network)), KnownNetworks.RegTest, new MinerSettings(NodeSettings.Default(this.network)), NodeSettings.Default(this.network), this.loggerFactory, new Mock <ITimeSyncBehaviorState>().Object, powMining.Object, null));

            var controller = new MiningController(consensusManager.Object, powNode.Object, this.loggerFactory, KnownNetworks.RegTest, powMining.Object, walletManager.Object);

            IActionResult result = controller.Generate(new MiningRequest {
                BlockCount = 1
            });

            powMining.VerifyAll();
            walletManager.VerifyAll();

            Assert.NotNull(result);
            var viewResult  = Assert.IsType <JsonResult>(result);
            var resultValue = Assert.IsType <GenerateBlocksModel>(viewResult.Value);

            Assert.NotNull(resultValue);
        }
Пример #2
0
        public NodeControllerTest()
        {
            this.network = KnownNetworks.TestNet;

            this.chainIndexer      = WalletTestsHelpers.GenerateChainWithHeight(3, this.network);
            this.chainState        = new Mock <IChainState>();
            this.connectionManager = new Mock <IConnectionManager>();
            this.connectionManager.Setup(c => c.Network).Returns(this.network);
            this.dateTimeProvider          = new Mock <IDateTimeProvider>();
            this.fullNode                  = new Mock <IFullNode>();
            this.initialBlockDownloadState = new Mock <InitialBlockDownloadState>(this.chainState.Object, this.network, null, new Checkpoints(), DateTimeProvider.Default);
            this.nodeSettings              = new NodeSettings(networksSelector: Networks.Networks.Bitcoin);

            this.consensusManager            = new Mock <IConsensusManager>();
            this.blockStore                  = new Mock <IBlockStore>();
            this.getUnspentTransaction       = new Mock <IGetUnspentTransaction>();
            this.networkDifficulty           = new Mock <INetworkDifficulty>();
            this.pooledGetUnspentTransaction = new Mock <IPooledGetUnspentTransaction>();
            this.pooledTransaction           = new Mock <IPooledTransaction>();
            this.asyncProvider               = new Mock <IAsyncProvider>();
            this.selfEndpointTracker         = new Mock <ISelfEndpointTracker>();

            this.controller = new NodeController(
                this.chainIndexer,
                this.chainState.Object,
                this.connectionManager.Object,
                this.dateTimeProvider.Object,
                this.fullNode.Object,
                this.LoggerFactory.Object,
                this.nodeSettings,
                this.network,
                this.asyncProvider.Object,
                this.selfEndpointTracker.Object,
                this.consensusManager.Object,
                this.blockStore.Object,
                this.initialBlockDownloadState.Object,
                new Mock <ISignals>().Object,
                this.getUnspentTransaction.Object,
                this.networkDifficulty.Object,
                this.pooledGetUnspentTransaction.Object,
                this.pooledTransaction.Object);
        }
        public void ProcessBlock_NewBlock_PreviousHashSameAsWalletTip_PassesBlockToManagerWithoutReorg()
        {
            var result = WalletTestsHelpers.GenerateChainAndBlocksWithHeight(5, Network.StratisMain);

            this.chain = result.Chain;
            var blocks = result.Blocks;
            var lightWalletSyncManager = new LightWalletSyncManagerOverride(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                            this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object);

            lightWalletSyncManager.SetWalletTip(this.chain.GetBlock(3));

            var blockToProcess = blocks[3];

            lightWalletSyncManager.ProcessBlock(blockToProcess); //4th block in the list has same prevhash as which is loaded

            var expectedBlockHash = this.chain.GetBlock(4).Header.GetHash();

            Assert.Equal(expectedBlockHash, lightWalletSyncManager.WalletTip.Header.GetHash());
            this.walletManager.Verify(w => w.ProcessBlock(It.Is <Block>(b => b.GetHash() == blockToProcess.GetHash()), It.Is <ChainedBlock>(c => c.Header.GetHash() == expectedBlockHash)));
        }
Пример #4
0
        public FullNodeControllerTest()
        {
            this.initialBlockSignature = Block.BlockSignature;

            Block.BlockSignature = false;

            this.fullNode                    = new Mock <IFullNode>();
            this.chainState                  = new Mock <IChainState>();
            this.connectionManager           = new Mock <IConnectionManager>();
            this.network                     = Network.TestNet;
            this.chain                       = WalletTestsHelpers.GenerateChainWithHeight(3, this.network);
            this.nodeSettings                = new NodeSettings();
            this.pooledTransaction           = new Mock <IPooledTransaction>();
            this.pooledGetUnspentTransaction = new Mock <IPooledGetUnspentTransaction>();
            this.getUnspentTransaction       = new Mock <IGetUnspentTransaction>();
            this.consensusLoop               = new Mock <IConsensusLoop>();
            this.networkDifficulty           = new Mock <INetworkDifficulty>();
            this.controller                  = new FullNodeController(this.LoggerFactory.Object, this.pooledTransaction.Object, this.pooledGetUnspentTransaction.Object, this.getUnspentTransaction.Object, this.networkDifficulty.Object,
                                                                      this.consensusLoop.Object, this.fullNode.Object, this.nodeSettings, this.network, this.chain, this.chainState.Object, this.connectionManager.Object);
        }
Пример #5
0
        public void StartStaking_ValidWalletAndPassword_StartsStaking_ReturnsOk()
        {
            Wallet.Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet", "password1");
            this.walletManager.Setup(w => w.GetWallet("myWallet"))
            .Returns(wallet);

            this.fullNode.Setup(f => f.NodeService <IWalletManager>(false))
            .Returns(this.walletManager.Object);

            this.fullNode.Setup(f => f.NodeFeature <MiningFeature>(true))
            .Returns(new MiningFeature(KnownNetworks.Main, new MinerSettings(Configuration.NodeSettings.Default()), Configuration.NodeSettings.Default(), this.LoggerFactory.Object, this.timeSyncBehaviorState.Object, null, this.posMinting.Object));

            IActionResult result = this.controller.StartStaking(new StartStakingRequest()
            {
                Name = "myWallet", Password = "******"
            });

            Assert.IsType <OkResult>(result);
            this.posMinting.Verify(p => p.Stake(It.Is <WalletSecret>(s => s.WalletName == "myWallet" && s.WalletPassword == "password1")), Times.Exactly(1));
        }
        public void ProcessBlock_NewBlock_BlockOnBestChain_WalletTipAfterNewTip_StartsSyncFromNewTip()
        {
            (ConcurrentChain Chain, List <Block> Blocks)result = WalletTestsHelpers.GenerateChainAndBlocksWithHeight(5, KnownNetworks.StratisMain);
            this.chain = result.Chain;
            List <Block> blocks = result.Blocks;
            var          lightWalletSyncManager = new LightWalletSyncManagerOverride(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                                     this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object, this.consensusManager.Object);

            // set 2nd block as tip
            lightWalletSyncManager.SetWalletTip(this.chain.GetBlock(4));
            //process 4th block in the list does not have same prevhash as which is loaded
            Block blockToProcess = blocks[3];

            lightWalletSyncManager.ProcessBlock(blockToProcess);

            uint256 expectedBlockHash = this.chain.GetBlock(4).Header.GetHash();

            Assert.Equal(expectedBlockHash, lightWalletSyncManager.WalletTip.Header.GetHash());
            this.walletManager.Verify(w => w.ProcessBlock(ExpectBlock(blocks[3]), ExpectChainedBlock(this.chain.GetBlock(4))));
        }
        public void SyncFromDate_ChainTipBeforeGivenDate_StartsAsyncLoopToCatchupChain()
        {
            var asyncLoop = new Mock <IAsyncLoop>();

            this.chain = WalletTestsHelpers.GenerateChainWithHeight(2, this.network);
            var lightWalletSyncManager = new LightWalletSyncManager(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                    this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object, this.consensusManager.Object);

            lightWalletSyncManager.SyncFromDate(this.chain.Tip.Header.BlockTime.DateTime.AddDays(15));

            this.asyncLoopFactory.Verify(
                a => a.RunUntil(
                    "LightWalletSyncManager.SyncFromDate",
                    It.IsAny <CancellationToken>(),
                    It.IsAny <Func <bool> >(),
                    It.IsAny <Action>(),
                    It.IsAny <Action <Exception> >(),
                    TimeSpans.FiveSeconds));
            this.nodeLifetime.VerifyGet(n => n.ApplicationStopping);
        }
        public void Start_WalletTipOnChain_NotHavingEarliestWalletHeight_StartsSyncFromOldestWalletCreationTime()
        {
            this.chain = WalletTestsHelpers.GenerateChainWithHeight(3, this.network);
            this.walletManager.Setup(w => w.ContainsWallets)
            .Returns(true);
            this.walletManager.Setup(w => w.WalletTipHash)
            .Returns(this.chain.GetBlock(2).HashBlock);
            this.walletManager.Setup(w => w.GetEarliestWalletHeight())
            .Returns((int?)null);
            this.walletManager.Setup(w => w.GetOldestWalletCreationTime())
            .Returns(new DateTimeOffset(new DateTime(2017, 1, 2)));

            var lightWalletSyncManager = new LightWalletSyncManager(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                    this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object, this.consensusManager.Object);

            lightWalletSyncManager.Start();

            Assert.Equal(lightWalletSyncManager.WalletTip.HashBlock, this.chain.GetBlock(2).HashBlock);
            this.blockNotification.Verify(b => b.SyncFrom(this.chain.GetBlock(2).HashBlock));
        }
        public void Given_GetMaximumSpendableAmountIsCalled_When_ThereAreNoConfirmedSpendableFound_Then_MaxAmountReturnsAsTheSumOfUnconfirmedTxs()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations())).Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, new ChainIndexer(this.Network), new WalletSettings(NodeSettings.Default(this.Network)),
                                                  dataFolder, new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncProvider>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);

            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

            HdAccount account = WalletTestsHelpers.CreateAccount("account 1");

            HdAddress accountAddress1 = WalletTestsHelpers.CreateAddress();

            accountAddress1.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(15000), null, null, null, new Key().ScriptPubKey));
            accountAddress1.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(2), new Money(10000), null, null, null, new Key().ScriptPubKey));

            HdAddress accountAddress2 = WalletTestsHelpers.CreateAddress();

            accountAddress2.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(3), new Money(20000), null, null, null, new Key().ScriptPubKey));
            accountAddress2.Transactions.Add(WalletTestsHelpers.CreateTransaction(new uint256(4), new Money(120000), null, null, null, new Key().ScriptPubKey));

            account.ExternalAddresses.Add(accountAddress1);
            account.InternalAddresses.Add(accountAddress2);

            Types.Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1");
            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            walletManager.Wallets.Add(wallet);

            (Money max, Money fee)result = walletTransactionHandler.GetMaximumSpendableAmount(new WalletAccountReference("wallet1", "account 1"), FeeType.Low, true);
            Assert.Equal(new Money(165000), result.max + result.fee);
        }
        public void GetBlockCount_ReturnsHeightFromChainState()
        {
            var logger         = new Mock <ILoggerFactory>();
            var store          = new Mock <IBlockStore>();
            var chainState     = new Mock <IChainState>();
            var addressIndexer = new Mock <IAddressIndexer>();

            ChainIndexer chainIndexer = WalletTestsHelpers.GenerateChainWithHeight(3, KnownNetworks.StratisTest);

            logger.Setup(l => l.CreateLogger(It.IsAny <string>())).Returns(Mock.Of <ILogger>);

            chainState.Setup(c => c.ConsensusTip)
            .Returns(chainIndexer.GetHeader(2));

            var controller = new BlockStoreController(KnownNetworks.StratisTest, logger.Object, store.Object, chainState.Object, chainIndexer, addressIndexer.Object);

            var json   = (JsonResult)controller.GetBlockCount();
            int result = int.Parse(json.Value.ToString());

            Assert.Equal(2, result);
        }
        public NodeControllerTest()
        {
            this.fullNode          = new Mock <IFullNode>();
            this.blockStore        = new Mock <IBlockStore>();
            this.chainState        = new Mock <IChainState>();
            this.dateTimeProvider  = new Mock <IDateTimeProvider>();
            this.connectionManager = new Mock <IConnectionManager>();
            this.network           = KnownNetworks.TestNet;
            this.connectionManager.Setup(c => c.Network).Returns(this.network);
            this.chain                       = WalletTestsHelpers.GenerateChainWithHeight(3, this.network);
            this.nodeSettings                = new NodeSettings();
            this.pooledTransaction           = new Mock <IPooledTransaction>();
            this.pooledGetUnspentTransaction = new Mock <IPooledGetUnspentTransaction>();
            this.getUnspentTransaction       = new Mock <IGetUnspentTransaction>();
            this.networkDifficulty           = new Mock <INetworkDifficulty>();

            this.controller = new NodeController(this.fullNode.Object, this.LoggerFactory.Object,
                                                 this.dateTimeProvider.Object, this.chainState.Object, this.nodeSettings,
                                                 this.connectionManager.Object, this.chain, this.network, this.pooledTransaction.Object,
                                                 this.pooledGetUnspentTransaction.Object, this.getUnspentTransaction.Object, this.networkDifficulty.Object, this.blockStore.Object);
        }
Пример #12
0
        public void Given_GetMaximumSpendableAmountIsCalledForConfirmedTransactions_When_ThereAreNoConfirmedSpendableFound_Then_MaxAmountReturnsAsZero()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, new ChainIndexer(this.Network), new WalletSettings(NodeSettings.Default(this.Network)),
                                                  dataFolder, new Mock <IWalletFeePolicy>().Object, new Mock <IAsyncProvider>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);

            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, It.IsAny <WalletFeePolicy>(), this.Network, this.standardTransactionPolicy);

            HdAccount account = WalletTestsHelpers.CreateAccount("account 1");

            Types.Wallet wallet = WalletTestsHelpers.CreateWallet("wallet1");

            HdAddress accountAddress1 = WalletTestsHelpers.CreateAddress();

            wallet.walletStore.InsertOrUpdate(WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(15000), null, address: accountAddress1.Address));
            wallet.walletStore.InsertOrUpdate(WalletTestsHelpers.CreateTransaction(new uint256(2), new Money(10000), null, address: accountAddress1.Address));

            HdAddress accountAddress2 = WalletTestsHelpers.CreateAddress();

            wallet.walletStore.InsertOrUpdate(WalletTestsHelpers.CreateTransaction(new uint256(3), new Money(20000), null, address: accountAddress2.Address));
            wallet.walletStore.InsertOrUpdate(WalletTestsHelpers.CreateTransaction(new uint256(4), new Money(120000), null, address: accountAddress2.Address));

            account.ExternalAddresses.Add(accountAddress1);
            account.InternalAddresses.Add(accountAddress2);

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            walletManager.Wallets.Add(wallet);

            (Money max, Money fee)result = walletTransactionHandler.GetMaximumSpendableAmount(new WalletAccountReference("wallet1", "account 1"), FeeType.Low, false);
            Assert.Equal(Money.Zero, result.max);
            Assert.Equal(Money.Zero, result.fee);
        }
        public void ProcessBlock_NewBlock_PreviousHashSameAsWalletTip_PassesBlockToManagerWithoutReorg()
        {
            (ChainIndexer Chain, List <Block> Blocks)result = WalletTestsHelpers.GenerateChainAndBlocksWithHeight(5, KnownNetworks.StratisMain);
            this.chainIndexer = result.Chain;
            List <Block> blocks            = result.Blocks;
            var          walletSyncManager = new WalletSyncManagerOverride(this.LoggerFactory.Object, this.walletManager.Object, this.chainIndexer, KnownNetworks.StratisMain,
                                                                           this.blockStore.Object, this.storeSettings, this.signals, this.asyncProvider);

            walletSyncManager.SetWalletTip(this.chainIndexer.GetHeader(3));

            Block blockToProcess = blocks[3];

            blockToProcess.SetPrivatePropertyValue("BlockSize", 1L);

            walletSyncManager.ProcessBlock(blockToProcess); //4th block in the list has same prevhash as which is loaded

            uint256 expectedBlockHash = this.AssertTipBlockHash(walletSyncManager, 4);

            this.AssertTipBlockHash(walletSyncManager, 4);

            this.walletManager.Verify(w => w.ProcessBlock(It.Is <Block>(b => b.GetHash() == blockToProcess.GetHash()), It.Is <ChainedHeader>(c => c.Header.GetHash() == expectedBlockHash)));
        }
Пример #14
0
        public void ProcessBlock_NewBlock_BlockOnBestChain_WalletTipBeforeNewTip_StartsSyncFromWalletTipWithoutProcessingBlock()
        {
            (ConcurrentChain Chain, List <Block> Blocks)result = WalletTestsHelpers.GenerateChainAndBlocksWithHeight(5, Network.StratisMain);
            this.chain = result.Chain;
            List <Block> blocks = result.Blocks;
            var          lightWalletSyncManager = new LightWalletSyncManagerOverride(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                                     this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object);

            // set 2nd block as tip
            lightWalletSyncManager.SetWalletTip(this.chain.GetBlock(2));
            //process 4th block in the list does not have same prevhash as which is loaded
            Block blockToProcess = blocks[3];

            lightWalletSyncManager.ProcessBlock(blockToProcess);

            this.blockNotification.Verify(b => b.SyncFrom(this.chain.GetBlock(2).HashBlock));

            uint256 expectedBlockHash = this.chain.GetBlock(2).Header.GetHash();

            Assert.Equal(expectedBlockHash, lightWalletSyncManager.WalletTip.Header.GetHash());
            this.walletManager.Verify(w => w.ProcessBlock(It.IsAny <Block>(), It.IsAny <ChainedHeader>()), Times.Exactly(0));
        }
        public void Generate_Blocks_ReturnsSuccess()
        {
            const string wallet  = "wallet";
            const string account = "account";

            this.walletManager.Setup(w => w.GetWalletsNames()).Returns(new List <string> {
                wallet
            });
            this.walletManager.Setup(w => w.GetAccounts(wallet)).Returns(new List <HdAccount> {
                new HdAccount {
                    Name = account
                }
            });

            HdAddress address = WalletTestsHelpers.CreateAddress();

            this.walletManager.Setup(w => w.GetUnusedAddress(new WalletAccountReference(wallet, account))).Returns(address);

            this.powMining.Setup(p => p.GenerateBlocks(It.Is <ReserveScript>(r => r.ReserveFullNodeScript == address.Pubkey), 1, int.MaxValue))
            .Returns(new List <uint256> {
                new uint256(1255632623)
            });

            this.controller = new MiningController(this.powMining.Object, this.LoggerFactory.Object, this.walletManager.Object);

            IActionResult result = this.controller.Generate(new MiningRequest {
                BlockCount = 1
            });

            this.walletManager.VerifyAll();
            this.powMining.VerifyAll();

            Assert.NotNull(result);
            var viewResult  = Assert.IsType <JsonResult>(result);
            var resultValue = Assert.IsType <GenerateBlocksModel>(viewResult.Value);

            Assert.NotNull(resultValue);
        }
        /// <summary>
        /// Creates a new wallet.
        /// </summary>
        /// <remarks>
        /// If it's the first time this wallet is created within this class, it is added to a collection for use by other tests.
        /// If the same parameters have already been used to create a wallet, the wallet will be retrieved from the internal collection and a copy of this wallet will be returned.
        /// </remarks>
        /// <param name="name">The name.</param>
        /// <param name="password">The password.</param>
        /// <returns>The generated wallet.</returns>
        public Features.Wallet.Types.Wallet GenerateBlankWallet(string name, string password)
        {
            if (this.walletsGenerated.TryGetValue((name, password), out Features.Wallet.Types.Wallet existingWallet))
            {
                string serializedExistingWallet = JsonConvert.SerializeObject(existingWallet, Formatting.None);
                var    wal1 = JsonConvert.DeserializeObject <Features.Wallet.Types.Wallet>(serializedExistingWallet);
                wal1.BlockLocator = existingWallet.BlockLocator;
                wal1.AccountsRoot.Single().LastBlockSyncedHash   = existingWallet.AccountsRoot.Single().LastBlockSyncedHash;
                wal1.AccountsRoot.Single().LastBlockSyncedHeight = existingWallet.AccountsRoot.Single().LastBlockSyncedHeight;
                wal1.walletStore = new WalletMemoryStore();
                var data1 = wal1.walletStore.GetData();
                data1.BlockLocator = existingWallet.BlockLocator;
                data1.WalletName   = existingWallet.Name;
                data1.WalletTip    = new Utilities.HashHeightPair(existingWallet.AccountsRoot.Single().LastBlockSyncedHash, existingWallet.AccountsRoot.Single().LastBlockSyncedHeight.Value);
                wal1.walletStore.SetData(data1);

                return(wal1);
            }

            Features.Wallet.Types.Wallet newWallet = WalletTestsHelpers.GenerateBlankWallet(name, password);
            this.walletsGenerated.Add((name, password), newWallet);

            string serializedNewWallet = JsonConvert.SerializeObject(newWallet, Formatting.None);
            var    wal = JsonConvert.DeserializeObject <Features.Wallet.Types.Wallet>(serializedNewWallet);

            wal.walletStore  = new WalletMemoryStore();
            wal.BlockLocator = newWallet.BlockLocator;
            wal.AccountsRoot.Single().LastBlockSyncedHash   = newWallet.AccountsRoot.Single().LastBlockSyncedHash;
            wal.AccountsRoot.Single().LastBlockSyncedHeight = newWallet.AccountsRoot.Single().LastBlockSyncedHeight;

            var data = wal.walletStore.GetData();

            data.BlockLocator = wal.BlockLocator;
            data.WalletName   = wal.Name;
            data.WalletTip    = new Utilities.HashHeightPair(wal.AccountsRoot.Single().LastBlockSyncedHash, wal.AccountsRoot.Single().LastBlockSyncedHeight.Value);
            wal.walletStore.SetData(data);
            return(wal);
        }
        public void Stop_DisposesDependencies()
        {
            this.chain = WalletTestsHelpers.GenerateChainWithHeight(1, this.network);
            var blockSub = new Mock <IDisposable>();
            var transSub = new Mock <IDisposable>();

            this.signals.Setup(s => s.SubscribeForBlocksConnected(It.IsAny <BlockObserver>()))
            .Returns(blockSub.Object);
            this.signals.Setup(s => s.SubscribeForTransactions(It.IsAny <TransactionObserver>()))
            .Returns(transSub.Object);
            this.walletManager.SetupGet(w => w.ContainsWallets)
            .Returns(false);

            var asyncLoop = new Mock <IAsyncLoop>();

            this.asyncLoopFactory.Setup(
                a => a.RunUntil(
                    "LightWalletSyncManager.SyncFromHeight",
                    It.IsAny <CancellationToken>(),
                    It.IsAny <Func <bool> >(),
                    It.IsAny <Action>(),
                    It.IsAny <Action <Exception> >(),
                    TimeSpans.FiveSeconds))
            .Returns(asyncLoop.Object);

            var lightWalletSyncManager = new LightWalletSyncManager(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                    this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object, this.consensusManager.Object);

            lightWalletSyncManager.Start();
            lightWalletSyncManager.SyncFromHeight(3);
            lightWalletSyncManager.Stop();

            asyncLoop.Verify(b => b.Dispose());
            blockSub.Verify(b => b.Dispose());
            transSub.Verify(b => b.Dispose());
        }
Пример #18
0
        public NodeControllerTest()
        {
            this.network = KnownNetworks.TestNet;

            this.chainIndexer      = WalletTestsHelpers.GenerateChainWithHeight(3, this.network);
            this.chainState        = new Mock <IChainState>();
            this.connectionManager = new Mock <IConnectionManager>();
            this.connectionManager.Setup(c => c.Network).Returns(this.network);
            this.dateTimeProvider = new Mock <IDateTimeProvider>();
            this.fullNode         = new Mock <IFullNode>();
            this.nodeSettings     = new NodeSettings(networksSelector: Networks.Bitcoin.Networks.Bitcoin);
            this.peerBanning      = new Mock <IPeerBanning>();

            this.blockStore                  = new Mock <IBlockStore>();
            this.getUnspentTransaction       = new Mock <IGetUnspentTransaction>();
            this.networkDifficulty           = new Mock <INetworkDifficulty>();
            this.pooledGetUnspentTransaction = new Mock <IPooledGetUnspentTransaction>();
            this.pooledTransaction           = new Mock <IPooledTransaction>();
            this.asyncProvider               = new Mock <IAsyncProvider>();
            this.selfEndpointTracker         = new Mock <ISelfEndpointTracker>();
            this.consensusManager            = new Mock <IConsensusManager>();

            this.CreateNewController();
        }
Пример #19
0
        public void StartStaking_InvalidWalletPassword_ReturnsBadRequest()
        {
            Wallet.Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet", "password1");
            this.walletManager.Setup(w => w.GetWallet("myWallet"))
            .Returns(wallet);

            this.fullNode.Setup(f => f.NodeService <IWalletManager>(false))
            .Returns(this.walletManager.Object);

            IActionResult result = this.controller.StartStaking(new StartStakingRequest()
            {
                Name = "myWallet", Password = "******"
            });

            var errorResult   = Assert.IsType <ErrorResult>(result);
            var errorResponse = Assert.IsType <ErrorResponse>(errorResult.Value);

            Assert.Single(errorResponse.Errors);

            ErrorModel error = errorResponse.Errors[0];

            Assert.Equal(400, error.Status);
            Assert.Equal("Invalid password (or invalid Network)", error.Message);
        }
Пример #20
0
        public void BuildTransactionFeeTooLowDefaultsToMinimumFee()
        {
            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
            .Returns(new FeeRate(0));

            Types.Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");
            (PubKey PubKey, BitcoinPubKeyAddress Address)changeKeys      = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "1/0");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                //Transactions = new List<TransactionData>()
            };

            var chain = new ChainIndexer(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.walletStore as WalletMemoryStore, wallet.Network, chain, address);

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>
                {
                    new HdAddress {
                        Index        = 0,
                        HdPath       = $"m/44'/0'/0'/1/0",
                        Address      = changeKeys.Address.ToString(),
                        Pubkey       = changeKeys.PubKey.ScriptPubKey,
                        ScriptPubKey = changeKeys.Address.ScriptPubKey,
                        //Transactions = new List<TransactionData>()
                    }
                }
            });

            string dataDir       = "TestData/WalletTransactionHandlerTest/BuildTransactionFeeTooLowThrowsWalletException";
            var    nodeSettings  = new NodeSettings(network: this.Network, args: new string[] { $"-datadir={dataDir}" });
            var    walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain, new WalletSettings(nodeSettings),
                                                     new DataFolder(nodeSettings.DataDir), walletFeePolicy.Object, new Mock <IAsyncProvider>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            TransactionBuildContext context     = CreateContext(this.Network, walletReference, "password", destinationKeys.PubKey.ScriptPubKey, new Money(7500), FeeType.Low, 0);
            Transaction             transaction = walletTransactionHandler.BuildTransaction(context);

            Assert.Equal(new Money(this.Network.MinTxFee, MoneyUnit.Satoshi), context.TransactionFee);
        }
Пример #21
0
        private WalletTransactionHandlerTestContext SetupWallet()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            Types.Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys    = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                // Transactions = new List<TransactionData>()
            };

            var chain = new ChainIndexer(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.walletStore as WalletMemoryStore, wallet.Network, chain, address);
            TransactionOutputData addressTransaction = wallet.walletStore.GetForAddress(address.Address).First();

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations()))
            .Returns(new FeeRate(20000));

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain,
                                                  new WalletSettings(NodeSettings.Default(this.Network)), dataFolder,
                                                  walletFeePolicy.Object, new Mock <IAsyncProvider>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
            var walletTransactionHandler =
                new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            return(new WalletTransactionHandlerTestContext
            {
                Wallet = wallet,
                AccountKeys = accountKeys,
                DestinationKeys = destinationKeys,
                AddressTransaction = addressTransaction,
                WalletTransactionHandler = walletTransactionHandler,
                WalletReference = walletReference
            });
        }
Пример #22
0
        /// <summary>
        /// Creates a new wallet.
        /// </summary>
        /// <param name="name">The name.</param>
        /// <param name="password">The password.</param>
        /// <returns>The generated wallet.</returns>
        public (Features.Wallet.Wallet, ExtKey) GenerateBlankWallet(string name, string password, IWalletRepository walletRepository = null)
        {
            (Features.Wallet.Wallet newWallet, ExtKey extKey) = WalletTestsHelpers.GenerateBlankWalletWithExtKey(name, password, walletRepository);

            return(newWallet, extKey);
        }
Пример #23
0
        public void FundTransaction_Given__a_wallet_has_enough_inputs__When__adding_inputs_to_an_existing_transaction__Then__the_transaction_is_funded_successfully()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            Types.Wallet wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet1", "password");
            (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");
            (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys     = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys1 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/1");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys2 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/2");
            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationKeys3 = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/3");

            var address = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                // Transactions = new List<TransactionData>()
            };

            // wallet with 4 coinbase outputs of 50 = 200 Bitcoin
            var chain = new ChainIndexer(wallet.Network);

            WalletTestsHelpers.AddBlocksWithCoinbaseToChain(wallet.walletStore as WalletMemoryStore, wallet.Network, chain, address, 4);

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account1",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    address
                },
                InternalAddresses = new List <HdAddress>()
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetFeeRate(FeeType.Low.ToConfirmations())).Returns(new FeeRate(20000));
            var overrideFeeRate = new FeeRate(20000);

            var walletManager = new WalletManager(this.LoggerFactory.Object, this.Network, chain, new WalletSettings(NodeSettings.Default(this.Network)),
                                                  dataFolder, walletFeePolicy.Object, new Mock <IAsyncProvider>().Object, new NodeLifetime(), DateTimeProvider.Default, this.scriptAddressReader);
            var walletTransactionHandler = new WalletTransactionHandler(this.LoggerFactory.Object, walletManager, walletFeePolicy.Object, this.Network, this.standardTransactionPolicy);

            walletManager.Wallets.Add(wallet);

            var walletReference = new WalletAccountReference
            {
                AccountName = "account1",
                WalletName  = "myWallet1"
            };

            // create a trx with 3 outputs 50 + 50 + 50 = 150 BTC
            var context = new TransactionBuildContext(this.Network)
            {
                AccountReference = walletReference,
                MinConfirmations = 0,
                FeeType          = FeeType.Low,
                WalletPassword   = "******",
                Recipients       = new[]
                {
                    new Recipient {
                        Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys1.PubKey.ScriptPubKey
                    },
                    new Recipient {
                        Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys2.PubKey.ScriptPubKey
                    },
                    new Recipient {
                        Amount = new Money(50, MoneyUnit.BTC), ScriptPubKey = destinationKeys3.PubKey.ScriptPubKey
                    }
                }.ToList()
            };

            Transaction fundTransaction = walletTransactionHandler.BuildTransaction(context);

            Assert.Equal(4, fundTransaction.Inputs.Count);  // 4 inputs
            Assert.Equal(4, fundTransaction.Outputs.Count); // 3 outputs with change

            // remove the change output
            fundTransaction.Outputs.Remove(fundTransaction.Outputs.First(f => f.ScriptPubKey == context.ChangeAddress.ScriptPubKey));
            // remove 3 inputs they will be added back by fund transaction
            fundTransaction.Inputs.RemoveAt(3);
            fundTransaction.Inputs.RemoveAt(2);
            fundTransaction.Inputs.RemoveAt(1);
            Assert.Single(fundTransaction.Inputs); // 4 inputs

            Transaction fundTransactionClone = this.Network.CreateTransaction(fundTransaction.ToBytes());
            var         fundContext          = new TransactionBuildContext(this.Network)
            {
                AccountReference = walletReference,
                MinConfirmations = 0,
                FeeType          = FeeType.Low,
                WalletPassword   = "******",
                Recipients       = new List <Recipient>()
            };

            fundContext.OverrideFeeRate = overrideFeeRate;
            walletTransactionHandler.FundTransaction(fundContext, fundTransaction);

            foreach (TxIn input in fundTransactionClone.Inputs) // all original inputs are still in the trx
            {
                Assert.Contains(fundTransaction.Inputs, a => a.PrevOut == input.PrevOut);
            }

            Assert.Equal(4, fundTransaction.Inputs.Count);  // we expect 4 inputs
            Assert.Equal(4, fundTransaction.Outputs.Count); // we expect 4 outputs
            Assert.Equal(new Money(200, MoneyUnit.BTC) - fundContext.TransactionFee, fundTransaction.TotalOut);

            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys1.PubKey.ScriptPubKey);
            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys2.PubKey.ScriptPubKey);
            Assert.Contains(fundTransaction.Outputs, a => a.ScriptPubKey == destinationKeys3.PubKey.ScriptPubKey);
        }
Пример #24
0
        public void ProcessTransactionWithValidColdStakingSetupLoadsTransactionsIntoWalletIfMatching()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            Directory.CreateDirectory(dataFolder.WalletPath);

            Wallet.Wallet wallet = this.walletFixture.GenerateBlankWallet("myWallet", "password");
            (ExtKey ExtKey, string ExtPubKey)accountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");

            (PubKey PubKey, BitcoinPubKeyAddress Address)spendingKeys = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "0/0");
            (PubKey PubKey, BitcoinPubKeyAddress Address)changeKeys   = WalletTestsHelpers.GenerateAddressKeys(wallet, accountKeys.ExtPubKey, "1/0");

            Wallet.Wallet coldWallet = this.walletFixture.GenerateBlankWallet("myColdWallet", "password");
            (ExtKey ExtKey, string ExtPubKey)accountColdKeys = WalletTestsHelpers.GenerateAccountKeys(coldWallet, "password", $"m/44'/0'/{ColdStakingManager.ColdWalletAccountIndex}'");

            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationColdKeys = WalletTestsHelpers.GenerateAddressKeys(coldWallet, accountColdKeys.ExtPubKey, "0/0");

            Wallet.Wallet hotWallet = this.walletFixture.GenerateBlankWallet("myHotWallet", "password");
            (ExtKey ExtKey, string ExtPubKey)accountHotKeys = WalletTestsHelpers.GenerateAccountKeys(hotWallet, "password", $"m/44'/0'/{ColdStakingManager.HotWalletAccountIndex}'");

            (PubKey PubKey, BitcoinPubKeyAddress Address)destinationHotKeys = WalletTestsHelpers.GenerateAddressKeys(hotWallet, accountHotKeys.ExtPubKey, "0/0");

            var spendingAddress = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = spendingKeys.Address.ToString(),
                Pubkey       = spendingKeys.PubKey.ScriptPubKey,
                ScriptPubKey = spendingKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            var destinationColdAddress = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/{ColdStakingManager.ColdWalletAccountIndex}'/0/0",
                Address      = destinationColdKeys.Address.ToString(),
                Pubkey       = destinationColdKeys.PubKey.ScriptPubKey,
                ScriptPubKey = destinationColdKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            var destinationHotAddress = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/{ColdStakingManager.HotWalletAccountIndex}'/0/0",
                Address      = destinationHotKeys.Address.ToString(),
                Pubkey       = destinationHotKeys.PubKey.ScriptPubKey,
                ScriptPubKey = destinationHotKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            var changeAddress = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/1/0",
                Address      = changeKeys.Address.ToString(),
                Pubkey       = changeKeys.PubKey.ScriptPubKey,
                ScriptPubKey = changeKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            // Generate a spendable transaction
            (ChainIndexer chain, uint256 blockhash, Block block)chainInfo = WalletTestsHelpers.CreateChainAndCreateFirstBlockWithPaymentToAddress(wallet.Network, spendingAddress);
            TransactionData spendingTransaction = WalletTestsHelpers.CreateTransactionDataFromFirstBlock(chainInfo);

            spendingAddress.Transactions.Add(spendingTransaction);

            wallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account 0",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    spendingAddress
                },
                InternalAddresses = new List <HdAddress> {
                    changeAddress
                }
            });

            coldWallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = ColdStakingManager.ColdWalletAccountIndex,
                Name              = ColdStakingManager.ColdWalletAccountName,
                HdPath            = $"m/44'/0'/{ColdStakingManager.ColdWalletAccountIndex}'",
                ExtendedPubKey    = accountColdKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    destinationColdAddress
                },
                InternalAddresses = new List <HdAddress> {
                }
            });

            hotWallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = ColdStakingManager.HotWalletAccountIndex,
                Name              = ColdStakingManager.HotWalletAccountName,
                HdPath            = $"m/44'/0'/{ColdStakingManager.HotWalletAccountIndex}'",
                ExtendedPubKey    = accountHotKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    destinationHotAddress
                },
                InternalAddresses = new List <HdAddress> {
                }
            });

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetMinimumFee(258, 50))
            .Returns(new Money(5000));

            var walletSettings = new WalletSettings(new NodeSettings(network: this.Network));

            var coldWalletManager = new ColdStakingManager(this.Network, chainInfo.chain, walletSettings, dataFolder, walletFeePolicy.Object,
                                                           new Mock <IAsyncProvider>().Object, new NodeLifetime(), new ScriptAddressReader(), this.LoggerFactory.Object, DateTimeProvider.Default, new Mock <ISignals>().Object, new Mock <IBroadcasterManager>().Object);

            coldWalletManager.Wallets.Add(wallet);
            coldWalletManager.Wallets.Add(coldWallet);
            coldWalletManager.LoadKeysLookupLock();

            // Create another instance for the hot wallet as it is not allowed to have both wallets on the same instance.
            var hotWalletManager = new ColdStakingManager(this.Network, chainInfo.chain, walletSettings, dataFolder, walletFeePolicy.Object,
                                                          new Mock <IAsyncProvider>().Object, new NodeLifetime(), new ScriptAddressReader(), this.LoggerFactory.Object, DateTimeProvider.Default, new Mock <ISignals>().Object, new Mock <IBroadcasterManager>().Object);

            hotWalletManager.Wallets.Add(hotWallet);
            hotWalletManager.LoadKeysLookupLock();

            // Create a cold staking setup transaction.
            Transaction transaction = this.CreateColdStakingSetupTransaction(wallet, "password", spendingAddress, destinationColdKeys.PubKey, destinationHotKeys.PubKey,
                                                                             changeAddress, new Money(7500), new Money(5000));

            coldWalletManager.ProcessTransaction(transaction);
            hotWalletManager.ProcessTransaction(transaction);

            HdAddress spentAddressResult = wallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0);

            Assert.Equal(1, spendingAddress.Transactions.Count);
            Assert.Equal(transaction.GetHash(), spentAddressResult.Transactions.ElementAt(0).SpendingDetails.TransactionId);
            Assert.Equal(transaction.Outputs[1].Value, spentAddressResult.Transactions.ElementAt(0).SpendingDetails.Payments.ElementAt(0).Amount);
            Assert.Equal(transaction.Outputs[1].ScriptPubKey, spentAddressResult.Transactions.ElementAt(0).SpendingDetails.Payments.ElementAt(0).DestinationScriptPubKey);

            Assert.Equal(1, wallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).InternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData changeAddressResult = wallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).InternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(transaction.GetHash(), changeAddressResult.Id);
            Assert.Equal(transaction.Outputs[0].Value, changeAddressResult.Amount);
            Assert.Equal(transaction.Outputs[0].ScriptPubKey, changeAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the cold wallet.
            Assert.Equal(1, coldWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData destinationColdAddressResult = coldWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(transaction.GetHash(), destinationColdAddressResult.Id);
            Assert.Equal(transaction.Outputs[1].Value, destinationColdAddressResult.Amount);
            Assert.Equal(transaction.Outputs[1].ScriptPubKey, destinationColdAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the hot wallet.
            Assert.Equal(1, hotWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData destinationHotAddressResult = hotWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(transaction.GetHash(), destinationHotAddressResult.Id);
            Assert.Equal(transaction.Outputs[1].Value, destinationHotAddressResult.Amount);
            Assert.Equal(transaction.Outputs[1].ScriptPubKey, destinationHotAddressResult.ScriptPubKey);

            // Try withdrawing from the cold staking setup.
            Wallet.Wallet withdrawalWallet = this.walletFixture.GenerateBlankWallet("myWithDrawalWallet", "password");
            (ExtKey ExtKey, string ExtPubKey)withdrawalAccountKeys = WalletTestsHelpers.GenerateAccountKeys(wallet, "password", "m/44'/0'/0'");

            (PubKey PubKey, BitcoinPubKeyAddress Address)withdrawalKeys = WalletTestsHelpers.GenerateAddressKeys(withdrawalWallet, withdrawalAccountKeys.ExtPubKey, "0/0");

            // Withdrawing to this address.
            var withdrawalAddress = new HdAddress
            {
                Index        = 0,
                HdPath       = $"m/44'/0'/0'/0/0",
                Address      = withdrawalKeys.Address.ToString(),
                Pubkey       = withdrawalKeys.PubKey.ScriptPubKey,
                ScriptPubKey = withdrawalKeys.Address.ScriptPubKey,
                Transactions = new List <TransactionData>()
            };

            withdrawalWallet.AccountsRoot.ElementAt(0).Accounts.Add(new HdAccount
            {
                Index             = 0,
                Name              = "account 0",
                HdPath            = "m/44'/0'/0'",
                ExtendedPubKey    = accountKeys.ExtPubKey,
                ExternalAddresses = new List <HdAddress> {
                    withdrawalAddress
                },
                InternalAddresses = new List <HdAddress> {
                }
            });

            // Will spend from the cold stake address and send the change back to the same address.
            var         coldStakeAddress      = coldWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0);
            Transaction withdrawalTransaction = this.CreateColdStakingWithdrawalTransaction(coldWallet, "password", coldStakeAddress,
                                                                                            withdrawalKeys.PubKey, ColdStakingScriptTemplate.Instance.GenerateScriptPubKey(destinationColdKeys.PubKey.Hash, destinationHotKeys.PubKey.Hash),
                                                                                            new Money(750), new Money(262));

            // Wallet manager for the wallet receiving the funds.
            var receivingWalletManager = new ColdStakingManager(this.Network, chainInfo.chain, walletSettings, dataFolder, walletFeePolicy.Object,
                                                                new Mock <IAsyncProvider>().Object, new NodeLifetime(), new ScriptAddressReader(), this.LoggerFactory.Object, DateTimeProvider.Default, new Mock <ISignals>().Object, new Mock <IBroadcasterManager>().Object);

            receivingWalletManager.Wallets.Add(withdrawalWallet);
            receivingWalletManager.LoadKeysLookupLock();

            // Process the transaction in the cold wallet manager.
            coldWalletManager.ProcessTransaction(withdrawalTransaction);

            // Process the transaction in the hot wallet manager.
            hotWalletManager.ProcessTransaction(withdrawalTransaction);

            // Process the transaction in the receiving wallet manager.
            receivingWalletManager.ProcessTransaction(withdrawalTransaction);

            // Verify that the transaction has been recorded in the withdrawal wallet.
            Assert.Equal(1, withdrawalWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData withdrawalAddressResult = withdrawalWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(withdrawalTransaction.GetHash(), withdrawalAddressResult.Id);
            Assert.Equal(withdrawalTransaction.Outputs[1].Value, withdrawalAddressResult.Amount);
            Assert.Equal(withdrawalTransaction.Outputs[1].ScriptPubKey, withdrawalAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the cold wallet.
            Assert.Equal(2, coldWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData coldAddressResult = coldWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(1);

            Assert.Equal(withdrawalTransaction.GetHash(), coldAddressResult.Id);
            Assert.Equal(withdrawalTransaction.Outputs[0].Value, coldAddressResult.Amount);
            Assert.Equal(withdrawalTransaction.Outputs[0].ScriptPubKey, coldAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the hot wallet.
            Assert.Equal(2, hotWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData hotAddressResult = hotWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(1);

            Assert.Equal(withdrawalTransaction.GetHash(), hotAddressResult.Id);
            Assert.Equal(withdrawalTransaction.Outputs[0].Value, hotAddressResult.Amount);
            Assert.Equal(withdrawalTransaction.Outputs[0].ScriptPubKey, hotAddressResult.ScriptPubKey);

            // Verify the hot amount returned by GetBalances.
            AccountBalance hotBalance = hotWalletManager.GetBalances("myHotWallet", ColdStakingManager.HotWalletAccountName).FirstOrDefault();

            Assert.Equal(hotBalance.AmountUnconfirmed, hotAddressResult.Amount);

            // Verify the cold amount returned by GetBalances.
            AccountBalance coldBalance = coldWalletManager.GetBalances("myColdWallet", ColdStakingManager.ColdWalletAccountName).FirstOrDefault();

            Assert.Equal(coldBalance.AmountUnconfirmed, coldAddressResult.Amount);
        }
        public void ProcessBlock_NewBlock_BlockNotOnBestChain_ReOrgWalletManagerUsingBlockStoreCache()
        {
            (ChainIndexer LeftChain, ChainIndexer RightChain, List <Block> LeftForkBlocks, List <Block> RightForkBlocks)result = WalletTestsHelpers.GenerateForkedChainAndBlocksWithHeight(5, KnownNetworks.StratisMain, 2);
            // left side chain containing the 'old' fork.
            ChainIndexer leftChainIndexer = result.LeftChain;

            // right side chain containing the 'new' fork. Work on this.
            this.chainIndexer = result.RightChain;
            var walletSyncManager = new WalletSyncManagerOverride(this.LoggerFactory.Object, this.walletManager.Object, this.chainIndexer, KnownNetworks.StratisMain,
                                                                  this.blockStore.Object, this.storeSettings, this.signals, this.asyncProvider);

            // setup blockstore to return blocks on the chain.
            this.blockStore.Setup(b => b.GetBlock(It.IsAny <uint256>()))
            .Returns((uint256 hashblock) =>
            {
                return(result.LeftForkBlocks.Union(result.RightForkBlocks).Single(b => b.GetHash() == hashblock));
            });

            // set 4th block of the old chain as tip. 2 ahead of the fork thus not being on the right chain.
            walletSyncManager.SetWalletTip(leftChainIndexer.GetHeader(result.LeftForkBlocks[3].Header.GetHash()));
            //process 5th block from the right side of the fork in the list does not have same prevhash as which is loaded.
            Block blockToProcess = result.RightForkBlocks[4];

            blockToProcess.SetPrivatePropertyValue("BlockSize", 1L);

            walletSyncManager.ProcessBlock(blockToProcess);

            this.AssertTipBlockHash(walletSyncManager, 5);

            // walletmanager removes all blocks up to the fork.
            this.walletManager.Verify(w => w.RemoveBlocks(ExpectChainedBlock(this.chainIndexer.GetHeader(2))));

            //verify manager processes each missing block until caught up.
            // height 3
            this.walletManager.Verify(w => w.ProcessBlock(ExpectBlock(result.RightForkBlocks[2]), ExpectChainedBlock(this.chainIndexer.GetHeader(3))));
            // height 4
            this.walletManager.Verify(w => w.ProcessBlock(ExpectBlock(result.RightForkBlocks[3]), ExpectChainedBlock(this.chainIndexer.GetHeader(4))));
            // height 5
            this.walletManager.Verify(w => w.ProcessBlock(ExpectBlock(result.RightForkBlocks[4]), ExpectChainedBlock(this.chainIndexer.GetHeader(5))), Times.Exactly(2));
        }
Пример #26
0
        public void ProcessTransactionWithValidColdStakingSetupLoadsTransactionsIntoWalletIfMatching()
        {
            DataFolder dataFolder = CreateDataFolder(this);

            Directory.CreateDirectory(dataFolder.WalletPath);

            var chain = new ChainIndexer(this.Network);

            var walletFeePolicy = new Mock <IWalletFeePolicy>();

            walletFeePolicy.Setup(w => w.GetMinimumFee(258, 50))
            .Returns(new Money(5000));

            var walletSettings = new WalletSettings(new NodeSettings(network: this.Network));
            IScriptAddressReader scriptAddressReader = new ColdStakingDestinationReader(new ScriptAddressReader());
            var walletRepository = new SQLiteWalletRepository(this.LoggerFactory.Object, dataFolder, this.Network, DateTimeProvider.Default, scriptAddressReader);

            walletRepository.TestMode = true;
            var walletManager = new ColdStakingManager(this.Network, chain, walletSettings, dataFolder, walletFeePolicy.Object,
                                                       new Mock <IAsyncProvider>().Object, new NodeLifetime(), new ScriptAddressReader(), this.LoggerFactory.Object, DateTimeProvider.Default,
                                                       walletRepository, new Mock <IBroadcasterManager>().Object);

            walletManager.Start();

            (Wallet.Wallet wallet, ExtKey walletExtKey)                     = this.walletFixture.GenerateBlankWallet("myWallet", "password", walletRepository);
            (Wallet.Wallet coldWallet, ExtKey coldWalletExtKey)             = this.walletFixture.GenerateBlankWallet("myColdWallet", "password", walletRepository);
            (Wallet.Wallet hotWallet, ExtKey hotWalletExtKey)               = this.walletFixture.GenerateBlankWallet("myHotWallet", "password", walletRepository);
            (Wallet.Wallet withdrawalWallet, ExtKey withdrawalWalletExtKey) = this.walletFixture.GenerateBlankWallet("myWithDrawalWallet", "password", walletRepository);

            HdAccount withdrawalAccount = withdrawalWallet.AddNewAccount("password");
            HdAddress withdrawalAddress = withdrawalAccount.ExternalAddresses.ElementAt(0);
            PubKey    withdrawalPubKey  = withdrawalAddress.Pubkey.GetDestinationPublicKeys(this.Network)[0];

            HdAccount account         = wallet.AddNewAccount("password");
            HdAddress changeAddress   = account.InternalAddresses.ElementAt(0);
            HdAddress spendingAddress = account.ExternalAddresses.ElementAt(0);

            HdAccount coldWalletAccount      = coldWallet.AddNewAccount("password", ColdStakingManager.ColdWalletAccountIndex, ColdStakingManager.ColdWalletAccountName);
            HdAddress destinationColdAddress = coldWalletAccount.ExternalAddresses.ElementAt(0);
            PubKey    destinationColdPubKey  = destinationColdAddress.Pubkey.GetDestinationPublicKeys(this.Network)[0];

            HdAccount hotWalletAccount      = hotWallet.AddNewAccount("password", ColdStakingManager.HotWalletAccountIndex, ColdStakingManager.HotWalletAccountName);
            HdAddress destinationHotAddress = hotWalletAccount.ExternalAddresses.ElementAt(0);
            PubKey    destinationHotPubKey  = destinationHotAddress.Pubkey.GetDestinationPublicKeys(this.Network)[0];

            // Generate a spendable transaction
            (uint256 blockhash, Block block)chainInfo = WalletTestsHelpers.CreateFirstBlockWithPaymentToAddress(chain, wallet.Network, spendingAddress);

            walletManager.ProcessBlock(chainInfo.block);

            // Create a cold staking setup transaction.
            Transaction transaction = this.CreateColdStakingSetupTransaction(wallet, "password", spendingAddress, destinationColdPubKey, destinationHotPubKey,
                                                                             changeAddress, new Money(7500), new Money(5000));

            walletManager.ProcessBlock(WalletTestsHelpers.AppendTransactionInNewBlockToChain(chain, transaction));

            HdAddress spentAddressResult = wallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0);

            Assert.Single(spendingAddress.Transactions);
            Assert.Equal(transaction.GetHash(), spentAddressResult.Transactions.ElementAt(0).SpendingDetails.TransactionId);
            Assert.Equal(2, transaction.Outputs.Count);
            Assert.True(spentAddressResult.Transactions.ElementAt(0).SpendingDetails.Payments.Any(p => p.DestinationScriptPubKey == transaction.Outputs[1].ScriptPubKey && p.Amount == transaction.Outputs[1].Value));

            Assert.Single(wallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).InternalAddresses.ElementAt(0).Transactions);
            TransactionData changeAddressResult = wallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).InternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(transaction.GetHash(), changeAddressResult.Id);
            Assert.Equal(transaction.Outputs[0].Value, changeAddressResult.Amount);
            Assert.Equal(transaction.Outputs[0].ScriptPubKey, changeAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the cold wallet.
            var coldAccounts = coldWallet.GetAccounts(Wallet.Wallet.AllAccounts);

            Assert.Single(coldAccounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions);
            TransactionData destinationColdAddressResult = coldAccounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(transaction.GetHash(), destinationColdAddressResult.Id);
            Assert.Equal(transaction.Outputs[1].Value, destinationColdAddressResult.Amount);
            Assert.Equal(transaction.Outputs[1].ScriptPubKey, destinationColdAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the hot wallet.
            var hotAccounts = hotWallet.GetAccounts(Wallet.Wallet.AllAccounts);

            Assert.Single(hotAccounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions);
            TransactionData destinationHotAddressResult = hotAccounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.ElementAt(0);

            Assert.Equal(transaction.GetHash(), destinationHotAddressResult.Id);
            Assert.Equal(transaction.Outputs[1].Value, destinationHotAddressResult.Amount);
            Assert.Equal(transaction.Outputs[1].ScriptPubKey, destinationHotAddressResult.ScriptPubKey);

            // Will spend from the cold stake address and send the change back to the same address.
            Money       balance               = walletManager.GetSpendableTransactionsInAccount(new WalletAccountReference(coldWallet.Name, coldWalletAccount.Name), 0).Sum(x => x.Transaction.Amount);
            var         coldStakeAddress      = coldWallet.GetAccounts(Wallet.Wallet.AllAccounts).ElementAt(0).ExternalAddresses.ElementAt(0);
            Transaction withdrawalTransaction = this.CreateColdStakingWithdrawalTransaction(coldWallet, "password", coldStakeAddress,
                                                                                            withdrawalPubKey, ColdStakingScriptTemplate.Instance.GenerateScriptPubKey(destinationHotPubKey.Hash, destinationColdPubKey.Hash),
                                                                                            new Money(750), new Money(263));

            // Process the transaction.
            walletManager.ProcessBlock(WalletTestsHelpers.AppendTransactionInNewBlockToChain(chain, withdrawalTransaction));

            // Verify that the transaction has been recorded in the withdrawal wallet.
            Assert.Single(withdrawalWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions);
            TransactionData withdrawalAddressResult = withdrawalWallet.AccountsRoot.ElementAt(0).Accounts.ElementAt(0).ExternalAddresses.ElementAt(0).Transactions
                                                      .Where(t => t.Id == withdrawalTransaction.GetHash()).First();

            Assert.Equal(withdrawalTransaction.GetHash(), withdrawalAddressResult.Id);
            Assert.Equal(withdrawalTransaction.Outputs[1].Value, withdrawalAddressResult.Amount);
            Assert.Equal(withdrawalTransaction.Outputs[1].ScriptPubKey, withdrawalAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the cold wallet.
            Assert.Equal(2, coldWallet.GetAccounts(Wallet.Wallet.AllAccounts).ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData coldAddressResult = coldWallet.GetAccounts(Wallet.Wallet.AllAccounts).ElementAt(0).ExternalAddresses.ElementAt(0).Transactions
                                                .Where(t => t.Id == withdrawalTransaction.GetHash()).First();

            Assert.Equal(withdrawalTransaction.GetHash(), coldAddressResult.Id);
            Assert.Equal(withdrawalTransaction.Outputs[0].Value, coldAddressResult.Amount);
            Assert.Equal(withdrawalTransaction.Outputs[0].ScriptPubKey, coldAddressResult.ScriptPubKey);

            // Verify that the transaction has been recorded in the hot wallet.
            Assert.Equal(2, hotWallet.GetAccounts(Wallet.Wallet.AllAccounts).ElementAt(0).ExternalAddresses.ElementAt(0).Transactions.Count);
            TransactionData hotAddressResult = hotWallet.GetAccounts(Wallet.Wallet.AllAccounts).ElementAt(0).ExternalAddresses.ElementAt(0).Transactions
                                               .Where(t => t.Id == withdrawalTransaction.GetHash()).First();

            Assert.Equal(withdrawalTransaction.GetHash(), hotAddressResult.Id);
            Assert.Equal(withdrawalTransaction.Outputs[0].Value, hotAddressResult.Amount);
            Assert.Equal(withdrawalTransaction.Outputs[0].ScriptPubKey, hotAddressResult.ScriptPubKey);

            // Verify the hot amount returned by GetBalances.
            AccountBalance hotBalance = walletManager.GetBalances("myHotWallet", ColdStakingManager.HotWalletAccountName).FirstOrDefault();

            Assert.Equal(hotBalance.AmountConfirmed, hotAddressResult.Amount);

            // Verify the cold amount returned by GetBalances.
            AccountBalance coldBalance = walletManager.GetBalances("myColdWallet", ColdStakingManager.ColdWalletAccountName).FirstOrDefault();

            Assert.Equal(coldBalance.AmountConfirmed, coldAddressResult.Amount);
        }
 public MiningRPCControllerFixture()
 {
     this.wallet = WalletTestsHelpers.GenerateBlankWallet("myWallet", "password1");
 }
        public void GetHistoryWithValidModelWithSkipAndTakeReturnsWalletHistoryModel()
        {
            ulong gasPrice             = SmartContractMempoolValidator.MinGasPrice;
            int   vmVersion            = 1;
            var   gasLimit             = (Stratis.SmartContracts.RuntimeObserver.Gas)(SmartContractFormatLogic.GasLimitMaximum / 2);
            var   contractTxData       = new ContractTxData(vmVersion, gasPrice, gasLimit, new byte[] { 0, 1, 2, 3 });
            var   callDataSerializer   = new CallDataSerializer(new ContractPrimitiveSerializer(new SmartContractsRegTest()));
            var   contractCreateScript = new Script(callDataSerializer.Serialize(contractTxData));

            string    walletName = "myWallet";
            HdAddress address    = WalletTestsHelpers.CreateAddress();

            const int totalHistoryLength = 100;
            const int toSkip             = 10;
            const int toTake             = 10;

            for (int i = 0; i < totalHistoryLength; i++)
            {
                TransactionData createTransaction = WalletTestsHelpers.CreateTransaction(new uint256((ulong)i), new Money(500000), 100 + i);
                createTransaction.SpendingDetails = new SpendingDetails
                {
                    BlockHeight   = 100 + i,
                    CreationTime  = DateTimeOffset.Now,
                    TransactionId = new uint256((ulong)i),
                    Payments      = new List <PaymentDetails>
                    {
                        new PaymentDetails
                        {
                            Amount = new Money(100000),
                            DestinationScriptPubKey = contractCreateScript
                        }
                    }
                };

                address.Transactions.Add(createTransaction);
            }

            var addresses = new List <HdAddress> {
                address
            };

            Features.Wallet.Wallet wallet = WalletTestsHelpers.CreateWallet(walletName);
            var account = new HdAccount {
                ExternalAddresses = addresses
            };

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            List <FlatHistory> flat = addresses.SelectMany(s => s.Transactions.Select(t => new FlatHistory {
                Address = s, Transaction = t
            })).ToList();

            var accountsHistory = new List <AccountHistory> {
                new AccountHistory {
                    History = flat, Account = account
                }
            };

            this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny <string>())).Returns(accountsHistory);
            this.walletManager.Setup(w => w.GetWalletByName(walletName)).Returns(wallet);
            this.walletManager.Setup(w => w.GetAccounts(walletName)).Returns(new List <HdAccount> {
                account
            });

            var receipt     = new Receipt(null, 12345, new Log[0], null, null, null, uint160.Zero, true, null, null, 2, 100000);
            var receiptList = new List <Receipt>();

            for (int i = 0; i < totalHistoryLength; i++)
            {
                receiptList.Add(receipt);
            }

            this.receiptRepository.Setup(x => x.RetrieveMany(It.IsAny <IList <uint256> >()))
            .Returns(receiptList);
            this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny <byte[]>()))
            .Returns(Result.Ok(new ContractTxData(0, 0, (Stratis.SmartContracts.RuntimeObserver.Gas) 0, new uint160(0), null, null)));

            var controller = new SmartContractWalletController(
                this.broadcasterManager.Object,
                this.callDataSerializer.Object,
                this.connectionManager.Object,
                this.loggerFactory.Object,
                this.network,
                this.receiptRepository.Object,
                this.walletManager.Object,
                this.smartContractTransactionService.Object);

            var request = new GetHistoryRequest
            {
                Address    = address.Address,
                WalletName = walletName,
                Skip       = toSkip,
                Take       = toTake
            };

            IActionResult result = controller.GetHistory(request);

            JsonResult viewResult = Assert.IsType <JsonResult>(result);
            var        model      = viewResult.Value as IEnumerable <ContractTransactionItem>;

            Assert.NotNull(model);
            Assert.Equal(toTake, model.Count());
            Assert.Equal(new uint256(toSkip), model.ElementAt(toTake - 1).Hash);
            Assert.Equal(new uint256(toSkip + toTake - 1), model.ElementAt(0).Hash);
        }
        public void ProcessBlock_BlockNotOnBestChain_ReorgWalletTipAfterNewTip_StartProcessingFromFork()
        {
            (ConcurrentChain LeftChain, ConcurrentChain RightChain, List <Block> LeftForkBlocks, List <Block> RightForkBlocks)result = WalletTestsHelpers.GenerateForkedChainAndBlocksWithHeight(5, KnownNetworks.StratisMain, 2);
            // left side chain containing the 'old' fork.
            ConcurrentChain leftChain = result.LeftChain;

            // right side chain containing the 'new' fork. Work on this.
            this.chain = result.RightChain;

            var lightWalletSyncManager = new LightWalletSyncManagerOverride(this.LoggerFactory.Object, this.walletManager.Object, this.chain, this.network,
                                                                            this.blockNotification.Object, this.signals.Object, this.nodeLifetime.Object, this.asyncLoopFactory.Object, this.consensusManager.Object);

            // set 4th block of the old chain as tip. 2 ahead of the fork thus not being on the right chain.
            lightWalletSyncManager.SetWalletTip(leftChain.GetBlock(result.LeftForkBlocks[3].Header.GetHash()));
            //process 2nd block from the right side of the fork in the list does not have same prevhash as which is loaded.
            Block blockToProcess = result.RightForkBlocks[1];

            lightWalletSyncManager.ProcessBlock(blockToProcess);

            // walletmanager removes all blocks up to the fork.
            this.walletManager.Verify(w => w.RemoveBlocks(ExpectChainedBlock(this.chain.GetBlock(2))));

            //expect the wallet tip to be set to the fork and do not start the sync to be started from that block.
            Assert.Equal(this.chain.GetBlock(2).HashBlock, lightWalletSyncManager.WalletTip.HashBlock);
            this.blockNotification.Verify(w => w.SyncFrom(It.IsAny <uint256>()), Times.Exactly(0));
            // expect the block to be processed.
            this.walletManager.Verify(w => w.ProcessBlock(ExpectBlock(result.RightForkBlocks[1]), ExpectChainedBlock(this.chain.GetBlock(2))));
        }
Пример #30
0
        public void GetHistoryWithValidModelWithoutTransactionSpendingDetailsReturnsWalletHistoryModel()
        {
            ulong gasPrice             = SmartContractMempoolValidator.MinGasPrice;
            int   vmVersion            = 1;
            Gas   gasLimit             = (Gas)(SmartContractFormatRule.GasLimitMaximum / 2);
            var   contractTxData       = new ContractTxData(vmVersion, gasPrice, gasLimit, new byte[] { 0, 1, 2, 3 });
            var   callDataSerializer   = new CallDataSerializer(new ContractPrimitiveSerializer(new SmartContractsRegTest()));
            var   contractCreateScript = new Script(callDataSerializer.Serialize(contractTxData));

            string          walletName        = "myWallet";
            HdAddress       address           = WalletTestsHelpers.CreateAddress();
            TransactionData normalTransaction = WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(500000), 1);
            TransactionData createTransaction = WalletTestsHelpers.CreateTransaction(new uint256(1), new Money(500000), 1);

            createTransaction.SpendingDetails = new SpendingDetails
            {
                BlockHeight   = 100,
                CreationTime  = DateTimeOffset.Now,
                TransactionId = uint256.One,
                Payments      = new List <PaymentDetails>
                {
                    new PaymentDetails
                    {
                        Amount = new Money(100000),
                        DestinationScriptPubKey = contractCreateScript
                    }
                }
            };

            address.Transactions.Add(normalTransaction);
            address.Transactions.Add(createTransaction);

            var addresses = new List <HdAddress> {
                address
            };

            Features.Wallet.Wallet wallet = WalletTestsHelpers.CreateWallet(walletName);
            var account = new HdAccount {
                ExternalAddresses = addresses
            };

            wallet.AccountsRoot.Add(new AccountRoot()
            {
                Accounts = new List <HdAccount> {
                    account
                }
            });

            List <FlatHistory> flat = addresses.SelectMany(s => s.Transactions.Select(t => new FlatHistory {
                Address = s, Transaction = t
            })).ToList();

            var accountsHistory = new List <AccountHistory> {
                new AccountHistory {
                    History = flat, Account = account
                }
            };

            this.walletManager.Setup(w => w.GetHistory(walletName, It.IsAny <string>())).Returns(accountsHistory);
            this.walletManager.Setup(w => w.GetWalletByName(walletName)).Returns(wallet);
            this.walletManager.Setup(w => w.GetAccounts(walletName)).Returns(new List <HdAccount> {
                account
            });

            this.receiptRepository.Setup(x => x.Retrieve(It.IsAny <uint256>()))
            .Returns(new Receipt(null, 0, new Log[0], null, null, null, uint160.Zero, true, null));
            this.callDataSerializer.Setup(x => x.Deserialize(It.IsAny <byte[]>()))
            .Returns(Result.Ok(new ContractTxData(0, 0, (Gas)0, new uint160(0), null, null)));

            var controller = new SmartContractWalletController(
                this.broadcasterManager.Object,
                this.callDataSerializer.Object,
                this.connectionManager.Object,
                this.loggerFactory.Object,
                this.network,
                this.receiptRepository.Object,
                this.walletManager.Object);

            IActionResult result = controller.GetHistory(walletName, address.Address);

            var viewResult = Assert.IsType <JsonResult>(result);
            var model      = viewResult.Value as IEnumerable <ContractTransactionItem>;

            Assert.NotNull(model);
            Assert.Equal(3, model.Count());

            ContractTransactionItem resultingTransaction = model.ElementAt(2);

            ContractTransactionItem resultingCreate = model.ElementAt(0);

            Assert.Equal(ContractTransactionItemType.ContractCreate, resultingCreate.Type);
            Assert.Equal(createTransaction.SpendingDetails.TransactionId, resultingCreate.Hash);
            Assert.Equal(createTransaction.SpendingDetails.Payments.First().Amount.ToUnit(MoneyUnit.BTC), resultingCreate.Amount);
            Assert.Equal(uint160.Zero.ToBase58Address(this.network), resultingCreate.To);
            Assert.Equal((uint)createTransaction.SpendingDetails.BlockHeight, resultingCreate.BlockHeight);

            Assert.Equal(ContractTransactionItemType.Received, resultingTransaction.Type);
            Assert.Equal(address.Address, resultingTransaction.To);
            Assert.Equal(normalTransaction.Id, resultingTransaction.Hash);
            Assert.Equal(normalTransaction.Amount.ToUnit(MoneyUnit.BTC), resultingTransaction.Amount);
            Assert.Equal((uint)1, resultingTransaction.BlockHeight);
        }