public void BlockStoreIndexTx() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNode1 = builder.CreateStratisNode(); var stratisNode2 = builder.CreateStratisNode(); builder.StartAll(); stratisNode1.NotInIBD(); stratisNode2.NotInIBD(); // generate blocks and wait for the downloader to pickup stratisNode1.SetDummyMinerSecret(new BitcoinSecret(new Key(), stratisNode1.FullNode.Network)); stratisNode2.SetDummyMinerSecret(new BitcoinSecret(new Key(), stratisNode2.FullNode.Network)); // sync both nodes stratisNode1.CreateRPCClient().AddNode(stratisNode2.Endpoint, true); stratisNode1.GenerateStratis(10); Class1.Eventually(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.Height == 10); Class1.Eventually(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNode2.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock); var bestBlock1 = stratisNode1.FullNode.BlockStoreManager.BlockRepository.GetAsync(stratisNode1.FullNode.Chain.Tip.HashBlock).Result; Assert.NotNull(bestBlock1); // get the block coinbase trx var trx = stratisNode2.FullNode.BlockStoreManager.BlockRepository.GetTrxAsync(bestBlock1.Transactions.First().GetHash()).Result; Assert.NotNull(trx); Assert.Equal(bestBlock1.Transactions.First().GetHash(), trx.GetHash()); } }
public void WalletCanReceiveAndSendCorrectly() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisSender = builder.CreateStratisNode(); var stratisReceiver = builder.CreateStratisNode(); builder.StartAll(); stratisSender.NotInIBD(); stratisReceiver.NotInIBD(); // get a key from the wallet var mnemonic1 = stratisSender.FullNode.WalletManager.CreateWallet("123456", "mywallet"); var mnemonic2 = stratisReceiver.FullNode.WalletManager.CreateWallet("123456", "mywallet"); Assert.Equal(12, mnemonic1.Words.Length); Assert.Equal(12, mnemonic2.Words.Length); var addr = stratisSender.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var key = stratisSender.FullNode.WalletManager.GetKeyForAddress("123456", addr).PrivateKey; stratisSender.SetDummyMinerSecret(new BitcoinSecret(key, stratisSender.FullNode.Network)); var maturity = (int)stratisSender.FullNode.Network.Consensus.Option <PowConsensusOptions>().COINBASE_MATURITY; stratisSender.GenerateStratis(maturity + 5); // wait for block repo for block sync to work TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); // the mining should add coins to the wallet var total = stratisSender.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * 105 * 50, total); // sync both nodes stratisSender.CreateRPCClient().AddNode(stratisReceiver.Endpoint, true); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); // send coins to the receiver var sendto = stratisReceiver.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var trx = stratisSender.FullNode.WalletManager.BuildTransaction(new WalletAccountReference("mywallet", "account 0"), "123456", sendto.ScriptPubKey, Money.COIN * 100, FeeType.Medium, 101); // broadcast to the other node stratisSender.FullNode.WalletManager.SendTransaction(trx.hex); // wait for the trx to arrive TestHelper.WaitLoop(() => stratisReceiver.CreateRPCClient().GetRawMempool().Length > 0); TestHelper.WaitLoop(() => stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any()); var receivetotal = stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * 100, receivetotal); Assert.Null(stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); // generate two new blocks do the trx is confirmed stratisSender.GenerateStratis(1, new List <Transaction>(new[] { new Transaction(trx.hex) })); stratisSender.GenerateStratis(1); // wait for block repo for block sync to work TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); TestHelper.WaitLoop(() => maturity + 6 == stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); } }
public void CanStratisSyncFromStratis() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNode = builder.CreateStratisNode(); var stratisNodeSync = builder.CreateStratisNode(); var coreCreateNode = builder.CreateNode(); builder.StartAll(); // not in IBD stratisNode.FullNode.ChainBehaviorState.SetIsInitialBlockDownload(false, DateTime.UtcNow.AddMinutes(5)); stratisNodeSync.FullNode.ChainBehaviorState.SetIsInitialBlockDownload(false, DateTime.UtcNow.AddMinutes(5)); // first seed a core node with blocks and sync them to a stratis node // and wait till the stratis node is fully synced var tip = coreCreateNode.FindBlock(5).Last(); stratisNode.CreateRPCClient().AddNode(coreCreateNode.Endpoint, true); Eventually(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreCreateNode.CreateRPCClient().GetBestBlockHash()); var bestBlockHash = stratisNode.CreateRPCClient().GetBestBlockHash(); Assert.Equal(tip.GetHash(), bestBlockHash); // add a new stratis node which will download // the blocks using the GetData payload stratisNodeSync.CreateRPCClient().AddNode(stratisNode.Endpoint, true); // wait for download and assert Class1.Eventually(() => stratisNode.CreateRPCClient().GetBestBlockHash() == stratisNodeSync.CreateRPCClient().GetBestBlockHash()); bestBlockHash = stratisNodeSync.CreateRPCClient().GetBestBlockHash(); Assert.Equal(tip.GetHash(), bestBlockHash); } }
public void BlockStoreCanReorg() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNodeSync = builder.CreateStratisNode(); var stratisNode1 = builder.CreateStratisNode(); var stratisNode2 = builder.CreateStratisNode(); builder.StartAll(); stratisNodeSync.NotInIBD(); stratisNode1.NotInIBD(); stratisNode2.NotInIBD(); // generate blocks and wait for the downloader to pickup stratisNode1.SetDummyMinerSecret(new BitcoinSecret(new Key(), stratisNodeSync.FullNode.Network)); stratisNode2.SetDummyMinerSecret(new BitcoinSecret(new Key(), stratisNodeSync.FullNode.Network)); // sync both nodes stratisNodeSync.CreateRPCClient().AddNode(stratisNode1.Endpoint, true); stratisNodeSync.CreateRPCClient().AddNode(stratisNode2.Endpoint, true); stratisNode1.GenerateStratis(10); Class1.Eventually(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.Height == 10); Class1.Eventually(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNodeSync.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock); Class1.Eventually(() => stratisNode2.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNodeSync.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock); // remove node 2 stratisNodeSync.CreateRPCClient().RemoveNode(stratisNode2.Endpoint); // mine some more with node 1 stratisNode1.GenerateStratis(10); // wait for node 1 to sync Class1.Eventually(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.Height == 20); Class1.Eventually(() => stratisNode1.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNodeSync.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock); // remove node 1 stratisNodeSync.CreateRPCClient().RemoveNode(stratisNode1.Endpoint); // mine a higher chain with node2 stratisNode2.GenerateStratis(20); Class1.Eventually(() => stratisNode2.FullNode.ChainBehaviorState.HighestPersistedBlock.Height == 30); // add node2 stratisNodeSync.CreateRPCClient().AddNode(stratisNode2.Endpoint, true); // node2 should be synced Class1.Eventually(() => stratisNode2.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNodeSync.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock); } }
public void WalletCanCatchupWithBestChain() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisminer = builder.CreateStratisNode(); builder.StartAll(); stratisminer.NotInIBD(); // get a key from the wallet var mnemonic = stratisminer.FullNode.WalletManager.CreateWallet("123456", "mywallet"); Assert.Equal(12, mnemonic.Words.Length); var addr = stratisminer.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var key = stratisminer.FullNode.WalletManager.GetKeyForAddress("123456", addr).PrivateKey; stratisminer.SetDummyMinerSecret(key.GetBitcoinSecret(stratisminer.FullNode.Network)); stratisminer.GenerateStratis(10); // wait for block repo for block sync to work TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisminer)); // push the wallet back stratisminer.FullNode.Services.ServiceProvider.GetService <IWalletSyncManager>().SyncFrom(5); stratisminer.GenerateStratis(5); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisminer)); } }
public void CanStratisSyncFromCore() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNode = builder.CreateStratisNode(); var coreNode = builder.CreateNode(); builder.StartAll(); // not in IBD stratisNode.FullNode.ChainBehaviorState.SetIsInitialBlockDownload(false, DateTime.UtcNow.AddMinutes(5)); var tip = coreNode.FindBlock(10).Last(); stratisNode.CreateRPCClient().AddNode(coreNode.Endpoint, true); Eventually(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode.CreateRPCClient().GetBestBlockHash()); var bestBlockHash = stratisNode.CreateRPCClient().GetBestBlockHash(); Assert.Equal(tip.GetHash(), bestBlockHash); //Now check if Core connect to stratis stratisNode.CreateRPCClient().RemoveNode(coreNode.Endpoint); tip = coreNode.FindBlock(10).Last(); coreNode.CreateRPCClient().AddNode(stratisNode.Endpoint, true); Eventually(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode.CreateRPCClient().GetBestBlockHash()); bestBlockHash = stratisNode.CreateRPCClient().GetBestBlockHash(); Assert.Equal(tip.GetHash(), bestBlockHash); //For Core synching from Stratis, need to save blocks in stratis } }
public void WalletCanRecoverOnStartup() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNodeSync = builder.CreateStratisNode(); builder.StartAll(); stratisNodeSync.NotInIBD(); // get a key from the wallet var mnemonic = stratisNodeSync.FullNode.WalletManager.CreateWallet("123456", "mywallet"); Assert.Equal(12, mnemonic.Words.Length); var addr = stratisNodeSync.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var key = stratisNodeSync.FullNode.WalletManager.GetKeyForAddress("123456", addr).PrivateKey; stratisNodeSync.SetDummyMinerSecret(key.GetBitcoinSecret(stratisNodeSync.FullNode.Network)); stratisNodeSync.GenerateStratis(10); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisNodeSync)); // set the tip of best chain some blocks in the apst stratisNodeSync.FullNode.Chain.SetTip(stratisNodeSync.FullNode.Chain.GetBlock(stratisNodeSync.FullNode.Chain.Height - 5)); // stop the node it will persist the chain with the reset tip stratisNodeSync.FullNode.Stop(); var newNodeInstance = builder.CloneStratisNode(stratisNodeSync); // load the node, this should hit the block store recover code newNodeInstance.Start(); // check that store recovered to be the same as the best chain. Assert.Equal(newNodeInstance.FullNode.Chain.Tip.HashBlock, newNodeInstance.FullNode.WalletManager.WalletTipHash); } }
public void BlockStoreCanRecoverOnStartup() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNodeSync = builder.CreateStratisNode(); builder.StartAll(); stratisNodeSync.NotInIBD(); // generate blocks and wait for the downloader to pickup stratisNodeSync.SetDummyMinerSecret(new BitcoinSecret(new Key(), stratisNodeSync.FullNode.Network)); stratisNodeSync.GenerateStratis(10); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisNodeSync)); // set the tip of best chain some blocks in the apst stratisNodeSync.FullNode.Chain.SetTip(stratisNodeSync.FullNode.Chain.GetBlock(stratisNodeSync.FullNode.Chain.Height - 5)); // stop the node it will persist the chain with the reset tip stratisNodeSync.FullNode.Stop(); var newNodeInstance = builder.CloneStratisNode(stratisNodeSync); // load the node, this should hit the block store recover code newNodeInstance.Start(); // check that store recovered to be the same as the best chain. Assert.Equal(newNodeInstance.FullNode.Chain.Tip.HashBlock, newNodeInstance.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock); //TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisNodeSync)); } }
public void CanMineBlocks() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNodeSync = builder.CreateStratisNode(); builder.StartAll(); var rpc = stratisNodeSync.CreateRPCClient(); rpc.SendCommand(NBitcoin.RPC.RPCOperations.generate, 10); Assert.Equal(10, rpc.GetBlockCount()); } }
public void CanGetGenesisFromRPC() { using (NodeBuilder builder = NodeBuilder.Create()) { RPCClient rpc = builder.CreateStratisNode().CreateRPCClient(); builder.StartAll(); RPCResponse response = rpc.SendCommand(RPCOperations.getblockhash, 0); string actualGenesis = (string)response.Result; Assert.Equal(Network.RegTest.GetGenesis().GetHash().ToString(), actualGenesis); Assert.Equal(Network.RegTest.GetGenesis().GetHash(), rpc.GetBestBlockHash()); } }
public void BlockBroadcastInv() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNodeSync = builder.CreateStratisNode(); var stratisNode1 = builder.CreateStratisNode(); var stratisNode2 = builder.CreateStratisNode(); builder.StartAll(); stratisNodeSync.NotInIBD(); stratisNode1.NotInIBD(); stratisNode2.NotInIBD(); // generate blocks and wait for the downloader to pickup stratisNodeSync.SetDummyMinerSecret(new BitcoinSecret(new Key(), stratisNodeSync.FullNode.Network)); stratisNodeSync.GenerateStratis(10); // coinbase maturity = 10 // wait for block repo for block sync to work Class1.Eventually(() => stratisNodeSync.FullNode.ConsensusLoop.Tip.HashBlock == stratisNodeSync.FullNode.Chain.Tip.HashBlock); Class1.Eventually(() => stratisNodeSync.FullNode.ChainBehaviorState.HighestValidatedPoW.HashBlock == stratisNodeSync.FullNode.Chain.Tip.HashBlock); Class1.Eventually(() => stratisNodeSync.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisNodeSync.FullNode.Chain.Tip.HashBlock); // sync both nodes stratisNode1.CreateRPCClient().AddNode(stratisNodeSync.Endpoint, true); stratisNode2.CreateRPCClient().AddNode(stratisNodeSync.Endpoint, true); Class1.Eventually(() => stratisNode1.CreateRPCClient().GetBestBlockHash() == stratisNodeSync.CreateRPCClient().GetBestBlockHash()); Class1.Eventually(() => stratisNode2.CreateRPCClient().GetBestBlockHash() == stratisNodeSync.CreateRPCClient().GetBestBlockHash()); // set node2 to use inv (not headers) stratisNode2.FullNode.ConnectionManager.ConnectedNodes.First().Behavior <BlockStoreBehavior>().PreferHeaders = false; // generate two new blocks stratisNodeSync.GenerateStratis(2); // wait for block repo for block sync to work Class1.Eventually(() => stratisNodeSync.FullNode.Chain.Tip.HashBlock == stratisNodeSync.FullNode.ConsensusLoop.Tip.HashBlock); Class1.Eventually(() => stratisNodeSync.FullNode.BlockStoreManager.BlockRepository.GetAsync(stratisNodeSync.CreateRPCClient().GetBestBlockHash()).Result != null); // wait for the other nodes to pick up the newly generated blocks Class1.Eventually(() => stratisNode1.CreateRPCClient().GetBestBlockHash() == stratisNodeSync.CreateRPCClient().GetBestBlockHash()); Class1.Eventually(() => stratisNode2.CreateRPCClient().GetBestBlockHash() == stratisNodeSync.CreateRPCClient().GetBestBlockHash()); } }
public void CanSendToAddress() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNodeSync = builder.CreateStratisNode(); builder.StartAll(); var rpc = stratisNodeSync.CreateRPCClient(); rpc.SendCommand(NBitcoin.RPC.RPCOperations.generate, 101); var address = new Key().PubKey.GetAddress(rpc.Network); var tx = rpc.SendToAddress(address, Money.Coins(1.0m)); Assert.NotNull(tx); } }
public void NodesCanConnectToEachOthers() { using (NodeBuilder builder = NodeBuilder.Create()) { var node1 = builder.CreateStratisNode(); var node2 = builder.CreateStratisNode(); builder.StartAll(); Assert.Equal(0, node1.FullNode.ConnectionManager.ConnectedNodes.Count); Assert.Equal(0, node2.FullNode.ConnectionManager.ConnectedNodes.Count); var rpc1 = node1.CreateRPCClient(); var rpc2 = node2.CreateRPCClient(); rpc1.AddNode(node2.Endpoint, true); Assert.Equal(1, node1.FullNode.ConnectionManager.ConnectedNodes.Count); Assert.Equal(1, node2.FullNode.ConnectionManager.ConnectedNodes.Count); var behavior = node1.FullNode.ConnectionManager.ConnectedNodes.First().Behaviors.Find <ConnectionManagerBehavior>(); Assert.False(behavior.Inbound); Assert.True(behavior.OneTry); behavior = node2.FullNode.ConnectionManager.ConnectedNodes.First().Behaviors.Find <ConnectionManagerBehavior>(); Assert.True(behavior.Inbound); Assert.False(behavior.OneTry); } }
public void CanGetPeersInfo() { using (NodeBuilder builder = NodeBuilder.Create()) { CoreNode nodeA = builder.CreateStratisNode(); builder.StartAll(); RPCClient rpc = nodeA.CreateRPCClient(); using (Node nodeB = nodeA.CreateNodeClient()) { nodeB.VersionHandshake(); PeerInfo[] peers = rpc.GetPeersInfo(); Assert.NotEmpty(peers); } } }
public void CheckRPCFailures() { using (NodeBuilder builder = NodeBuilder.Create()) { var node = builder.CreateStratisNode(); builder.StartAll(); var client = node.CreateRPCClient(); var hash = client.GetBestBlockHash(); try { client.SendCommand("lol"); Assert.True(false, "should throw"); } catch (RPCException ex) { Assert.Equal(RPCErrorCode.RPC_METHOD_NOT_FOUND, ex.RPCCode); } Assert.Equal(hash, Network.RegTest.GetGenesis().GetHash()); var oldClient = client; client = new NBitcoin.RPC.RPCClient("abc:def", client.Address, client.Network); try { client.GetBestBlockHash(); Assert.True(false, "should throw"); } catch (Exception ex) { Assert.True(ex.Message.Contains("401")); } client = oldClient; try { client.SendCommand("addnode", "regreg", "addr"); Assert.True(false, "should throw"); } catch (RPCException ex) { Assert.Equal(RPCErrorCode.RPC_MISC_ERROR, ex.RPCCode); } } }
public void CanHandleReorgs() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisNode = builder.CreateStratisNode(); var coreNode1 = builder.CreateNode(); var coreNode2 = builder.CreateNode(); builder.StartAll(); //Core1 discovers 10 blocks, sends to stratis var tip = coreNode1.FindBlock(10).Last(); stratisNode.CreateRPCClient().AddNode(coreNode1.Endpoint, true); TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode1.CreateRPCClient().GetBestBlockHash()); stratisNode.CreateRPCClient().RemoveNode(coreNode1.Endpoint); //Core2 discovers 20 blocks, sends to stratis tip = coreNode2.FindBlock(20).Last(); stratisNode.CreateRPCClient().AddNode(coreNode2.Endpoint, true); TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode2.CreateRPCClient().GetBestBlockHash()); stratisNode.CreateRPCClient().RemoveNode(coreNode2.Endpoint); ((CachedCoinView)stratisNode.FullNode.CoinView()).FlushAsync().Wait(); //Core1 discovers 30 blocks, sends to stratis tip = coreNode1.FindBlock(30).Last(); stratisNode.CreateRPCClient().AddNode(coreNode1.Endpoint, true); TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode1.CreateRPCClient().GetBestBlockHash()); stratisNode.CreateRPCClient().RemoveNode(coreNode1.Endpoint); //Core2 discovers 50 blocks, sends to stratis tip = coreNode2.FindBlock(50).Last(); stratisNode.CreateRPCClient().AddNode(coreNode2.Endpoint, true); TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode2.CreateRPCClient().GetBestBlockHash()); stratisNode.CreateRPCClient().RemoveNode(coreNode2.Endpoint); ((CachedCoinView)stratisNode.FullNode.CoinView()).FlushAsync().Wait(); TestHelper.WaitLoop(() => stratisNode.CreateRPCClient().GetBestBlockHash() == coreNode2.CreateRPCClient().GetBestBlockHash()); } }
public void CanGetBlockHeaderFromRPC() { using (NodeBuilder builder = NodeBuilder.Create()) { CoreNode node = builder.CreateStratisNode(); RPCClient rpc = node.CreateRPCClient(); builder.StartAll(); uint256 hash = rpc.GetBlockHash(0); BlockHeader expectedHeader = node.FullNode.Chain?.GetBlock(hash)?.Header; BlockHeader actualHeader = rpc.GetBlockHeader(0); // Assert block header fields match Assert.Equal(expectedHeader.Version, actualHeader.Version); Assert.Equal(expectedHeader.HashPrevBlock, actualHeader.HashPrevBlock); Assert.Equal(expectedHeader.HashMerkleRoot, actualHeader.HashMerkleRoot); Assert.Equal(expectedHeader.Time, actualHeader.Time); Assert.Equal(expectedHeader.Bits, actualHeader.Bits); Assert.Equal(expectedHeader.Nonce, actualHeader.Nonce); // Assert header hash matches genesis hash Assert.Equal(Network.RegTest.GenesisHash, actualHeader.GetHash()); } }
public void WalletCanReceiveCorrectly() { using (NodeBuilder builder = NodeBuilder.Create()) { var stratisSender = builder.CreateStratisNode(); var stratisReceiver = builder.CreateStratisNode(); builder.StartAll(); stratisSender.NotInIBD(); stratisReceiver.NotInIBD(); // get a key from the wallet var mnemonic1 = stratisSender.FullNode.WalletManager.CreateWallet("123456", "mywallet"); Assert.Equal(12, mnemonic1.Words.Length); var mnemonic2 = stratisReceiver.FullNode.WalletManager.CreateWallet("123456", "mywallet"); Assert.Equal(12, mnemonic2.Words.Length); var addr = stratisSender.FullNode.WalletManager.GetUnusedAddress("mywallet", "account 0"); var key = stratisSender.FullNode.WalletManager.GetKeyForAddress("123456", addr).PrivateKey; stratisSender.SetDummyMinerSecret(new BitcoinSecret(key, stratisSender.FullNode.Network)); stratisSender.GenerateStratis(105); // coinbase maturity = 10 // wait for block repo for block sync to work Class1.Eventually(() => stratisSender.FullNode.ConsensusLoop.Tip.HashBlock == stratisSender.FullNode.Chain.Tip.HashBlock); Class1.Eventually(() => stratisSender.FullNode.ChainBehaviorState.HighestValidatedPoW.HashBlock == stratisSender.FullNode.Chain.Tip.HashBlock); Class1.Eventually(() => stratisSender.FullNode.ChainBehaviorState.HighestPersistedBlock.HashBlock == stratisSender.FullNode.Chain.Tip.HashBlock); // the mining should add coins to the wallet var total = stratisSender.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * 105 * 50, total); // sync both nodes stratisSender.CreateRPCClient().AddNode(stratisReceiver.Endpoint, true); Class1.Eventually(() => stratisSender.CreateRPCClient().GetBestBlockHash() == stratisReceiver.CreateRPCClient().GetBestBlockHash()); // send coins to the receiver var sendto = stratisReceiver.FullNode.WalletManager.GetUnusedAddress("mywallet", "account 0"); var trx = stratisSender.FullNode.WalletManager.BuildTransaction("mywallet", "account 0", "123456", sendto.Address, Money.COIN * 100, string.Empty, 101); // broadcast to the other node stratisSender.FullNode.WalletManager.SendTransaction(trx.hex); // wait for the trx to arrive Class1.Eventually(() => stratisReceiver.CreateRPCClient().GetRawMempool().Length > 0); Class1.Eventually(() => stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any()); var receivetotal = stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * 100, receivetotal); Assert.Null(stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); // generate two new blocks do the trx is confirmed stratisSender.GenerateStratis(2, new List <Transaction>(new[] { new Transaction(trx.hex) })); // wait for block repo for block sync to work Class1.Eventually(() => stratisSender.FullNode.Chain.Tip.HashBlock == stratisSender.FullNode.ConsensusLoop.Tip.HashBlock); Class1.Eventually(() => stratisSender.FullNode.BlockStoreManager.BlockRepository.GetAsync(stratisSender.CreateRPCClient().GetBestBlockHash()).Result != null); Class1.Eventually(() => stratisSender.CreateRPCClient().GetBestBlockHash() == stratisReceiver.CreateRPCClient().GetBestBlockHash()); Class1.Eventually(() => 106 == stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); } }
public void WalletCanReorg() { // this test has 4 parts: // send first transaction from one wallet to another and wait for it to be confirmed // send a second transaction and wait for it to be confirmed // connected to a longer chain that couse a reorg back so the second trasnaction is undone // mine the second transaction back in to the main chain using (NodeBuilder builder = NodeBuilder.Create()) { var stratisSender = builder.CreateStratisNode(); var stratisReceiver = builder.CreateStratisNode(); var stratisReorg = builder.CreateStratisNode(); builder.StartAll(); stratisSender.NotInIBD(); stratisReceiver.NotInIBD(); stratisReorg.NotInIBD(); // get a key from the wallet var mnemonic1 = stratisSender.FullNode.WalletManager.CreateWallet("123456", "mywallet"); var mnemonic2 = stratisReceiver.FullNode.WalletManager.CreateWallet("123456", "mywallet"); Assert.Equal(12, mnemonic1.Words.Length); Assert.Equal(12, mnemonic2.Words.Length); var addr = stratisSender.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var key = stratisSender.FullNode.WalletManager.GetKeyForAddress("123456", addr).PrivateKey; stratisSender.SetDummyMinerSecret(new BitcoinSecret(key, stratisSender.FullNode.Network)); stratisReorg.SetDummyMinerSecret(new BitcoinSecret(key, stratisSender.FullNode.Network)); var maturity = (int)stratisSender.FullNode.Network.Consensus.Option <PowConsensusOptions>().COINBASE_MATURITY; stratisSender.GenerateStratis(maturity + 15); var currentBestHeight = maturity + 15; // wait for block repo for block sync to work TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); // the mining should add coins to the wallet var total = stratisSender.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * currentBestHeight * 50, total); // sync all nodes stratisReceiver.CreateRPCClient().AddNode(stratisSender.Endpoint, true); stratisReceiver.CreateRPCClient().AddNode(stratisReorg.Endpoint, true); stratisSender.CreateRPCClient().AddNode(stratisReorg.Endpoint, true); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisReorg)); // Build Transaction 1 // ==================== // send coins to the receiver var sendto = stratisReceiver.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var transaction1 = stratisSender.FullNode.WalletManager.BuildTransaction(new WalletAccountReference("mywallet", "account 0"), "123456", sendto.ScriptPubKey, Money.COIN * 100, FeeType.Medium, 101); // broadcast to the other node stratisSender.FullNode.WalletManager.SendTransaction(transaction1.hex); // wait for the trx to arrive TestHelper.WaitLoop(() => stratisReceiver.CreateRPCClient().GetRawMempool().Length > 0); Assert.NotNull(stratisReceiver.CreateRPCClient().GetRawTransaction(transaction1.transactionId, false)); TestHelper.WaitLoop(() => stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any()); var receivetotal = stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * 100, receivetotal); Assert.Null(stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); // generate two new blocks so the trx is confirmed stratisSender.GenerateStratis(1, new List <Transaction>(new[] { new Transaction(transaction1.hex) })); var transaction1MinedHeight = currentBestHeight + 1; stratisSender.GenerateStratis(1); currentBestHeight = currentBestHeight + 2; // wait for block repo for block sync to work TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisReorg)); Assert.Equal(currentBestHeight, stratisReceiver.FullNode.Chain.Tip.Height); TestHelper.WaitLoop(() => transaction1MinedHeight == stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); // Build Transaction 2 // ==================== // remove the reorg node stratisReceiver.CreateRPCClient().RemoveNode(stratisReorg.Endpoint); stratisSender.CreateRPCClient().RemoveNode(stratisReorg.Endpoint); var forkblock = stratisReceiver.FullNode.Chain.Tip; // send more coins to the wallet sendto = stratisReceiver.FullNode.WalletManager.GetUnusedAddress(new WalletAccountReference("mywallet", "account 0")); var transaction2 = stratisSender.FullNode.WalletManager.BuildTransaction(new WalletAccountReference("mywallet", "account 0"), "123456", sendto.ScriptPubKey, Money.COIN * 10, FeeType.Medium, 101); stratisSender.FullNode.WalletManager.SendTransaction(transaction2.hex); // wait for the trx to arrive TestHelper.WaitLoop(() => stratisReceiver.CreateRPCClient().GetRawMempool().Length > 0); Assert.NotNull(stratisReceiver.CreateRPCClient().GetRawTransaction(transaction2.transactionId, false)); TestHelper.WaitLoop(() => stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any()); var newamount = stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(Money.COIN * 110, newamount); Assert.True(stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any(b => b.BlockHeight == null)); // mine more blocks so its included in the chain stratisSender.GenerateStratis(1, new List <Transaction>(new[] { new Transaction(transaction2.hex) })); var transaction2MinedHeight = currentBestHeight + 1; stratisSender.GenerateStratis(1); currentBestHeight = currentBestHeight + 2; TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); Assert.Equal(currentBestHeight, stratisReceiver.FullNode.Chain.Tip.Height); TestHelper.WaitLoop(() => stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any(b => b.BlockHeight == transaction2MinedHeight)); // create a reog by mining on two different chains // ================================================ // advance both chains, one chin is longer stratisSender.GenerateStratis(2); stratisReorg.GenerateStratis(10); currentBestHeight = forkblock.Height + 10; TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisReorg)); // connect the reorg chain stratisReceiver.CreateRPCClient().AddNode(stratisReorg.Endpoint, true); stratisSender.CreateRPCClient().AddNode(stratisReorg.Endpoint, true); // wait for the chains to catch up TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisReorg)); Assert.Equal(currentBestHeight, stratisReceiver.FullNode.Chain.Tip.Height); // ensure wallet reorg complete TestHelper.WaitLoop(() => stratisReceiver.FullNode.WalletManager.WalletTipHash == stratisReorg.CreateRPCClient().GetBestBlockHash()); // check the wallet amont was roled back var newtotal = stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(receivetotal, newtotal); TestHelper.WaitLoop(() => maturity + 16 == stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).First().BlockHeight); // ReBuild Transaction 2 // ==================== // mine the transaction again stratisSender.GenerateStratis(1, new List <Transaction>(new[] { new Transaction(transaction2.hex) })); transaction2MinedHeight = currentBestHeight + 1; stratisSender.GenerateStratis(1); currentBestHeight = currentBestHeight + 2; TestHelper.WaitLoop(() => TestHelper.IsNodeSynced(stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisSender)); TestHelper.WaitLoop(() => TestHelper.AreNodesSynced(stratisReceiver, stratisReorg)); Assert.Equal(currentBestHeight, stratisReceiver.FullNode.Chain.Tip.Height); var newsecondamount = stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Sum(s => s.Amount); Assert.Equal(newamount, newsecondamount); TestHelper.WaitLoop(() => stratisReceiver.FullNode.WalletManager.GetSpendableTransactions().SelectMany(s => s.Transactions).Any(b => b.BlockHeight == transaction2MinedHeight)); } }