public void CheckBlocksAnnounced_AndQueueEmptiesOverTime() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode stratisNodeSync = builder.CreateStratisPowNode(this.network, "bss-1-stratisNodeSync").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start(); CoreNode stratisNode1 = builder.CreateStratisPowNode(this.network, "bss-1-stratisNode1").Start(); // Change the second node's list of default behaviours include the test behaviour in it. // We leave the other behaviors alone for this test because we want to see what messages the node gets under normal operation. IConnectionManager node1ConnectionManager = stratisNode1.FullNode.NodeService <IConnectionManager>(); node1ConnectionManager.Parameters.TemplateBehaviors.Add(new TestBehavior()); // Connect node1 to initial node. TestHelper.Connect(stratisNode1, stratisNodeSync); INetworkPeer connectedPeer = node1ConnectionManager.ConnectedPeers.FindByEndpoint(stratisNodeSync.Endpoint); TestBehavior testBehavior = connectedPeer.Behavior <TestBehavior>(); TestBase.WaitLoop(() => TestHelper.AreNodesSynced(stratisNode1, stratisNodeSync)); HashSet <uint256> advertised = new HashSet <uint256>(); // Check to see that all blocks got advertised to node1 via the "headers" payload. foreach (IncomingMessage message in testBehavior.receivedMessageTracker["headers"]) { if (message.Message.Payload is HeadersPayload) { foreach (BlockHeader header in ((HeadersPayload)message.Message.Payload).Headers) { advertised.Add(header.GetHash()); } } } foreach (ChainedHeader chainedHeader in stratisNodeSync.FullNode.ChainIndexer.EnumerateToTip(this.network.GenesisHash)) { if ((!advertised.Contains(chainedHeader.HashBlock)) && (!(chainedHeader.HashBlock == this.network.GenesisHash))) { throw new Exception($"An expected block was not advertised to peer: {chainedHeader.HashBlock}"); } } // Check current state of announce queue BlockStoreSignaled blockStoreSignaled = stratisNodeSync.FullNode.NodeService <BlockStoreSignaled>(); IAsyncQueue <ChainedHeader> blocksToAnnounce = (IAsyncQueue <ChainedHeader>)blockStoreSignaled.GetMemberValue("blocksToAnnounce"); Queue <ChainedHeader> queueItems = (Queue <ChainedHeader>)blocksToAnnounce.GetMemberValue("items"); TestBase.WaitLoop(() => queueItems.Count == 0); } }
public void MustNotAnnounceABlock_WhenNotInBestChain() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode stratisNodeSync = builder.CreateStratisPowNode(this.network, "bss-2-stratisNodeSync").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start(); CoreNode stratisNode1 = builder.CreateStratisPowNode(this.network, "bss-2-stratisNode1").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Listener).Start(); CoreNode stratisNode2 = builder.CreateStratisPowNode(this.network, "bss-2-stratisNode2").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10NoWallet).Start(); // Store block 1 of chain0 for later usage ChainedHeader firstBlock = null; foreach (ChainedHeader chainedHeader in stratisNodeSync.FullNode.ChainIndexer.EnumerateToTip(this.network.GenesisHash)) { if (chainedHeader.Height == 1) { firstBlock = chainedHeader; } } Assert.NotNull(firstBlock); // Mine longer chain1 using node1 TestHelper.MineBlocks(stratisNode1, 15); IConnectionManager node1ConnectionManager = stratisNode1.FullNode.NodeService <IConnectionManager>(); node1ConnectionManager.Parameters.TemplateBehaviors.Add(new TestBehavior()); IConnectionManager node2ConnectionManager = stratisNode2.FullNode.NodeService <IConnectionManager>(); node2ConnectionManager.Parameters.TemplateBehaviors.Add(new TestBehavior()); // Connect node0 and node1 TestHelper.Connect(stratisNode1, stratisNodeSync); INetworkPeer connectedPeer = node1ConnectionManager.ConnectedPeers.FindByEndpoint(stratisNodeSync.Endpoint); TestBehavior testBehavior = connectedPeer.Behavior <TestBehavior>(); // We expect that node0 will abandon the 10 block chain and use the 15 block chain from node1 TestBase.WaitLoop(() => TestHelper.AreNodesSynced(stratisNode1, stratisNodeSync)); // Connect all nodes together TestHelper.Connect(stratisNode2, stratisNodeSync); TestHelper.Connect(stratisNode1, stratisNode2); INetworkPeer connectedPeer2 = node2ConnectionManager.ConnectedPeers.FindByEndpoint(stratisNodeSync.Endpoint); TestBehavior testBehavior2 = connectedPeer2.Behavior <TestBehavior>(); // Wait for node2 to sync; it should have the 15 block chain TestBase.WaitLoop(() => TestHelper.AreNodesSynced(stratisNode2, stratisNodeSync)); // Insert block 1 from chain0 into node1's announce queue BlockStoreSignaled node1BlockStoreSignaled = stratisNode1.FullNode.NodeService <BlockStoreSignaled>(); IAsyncQueue <ChainedHeader> node1BlocksToAnnounce = (IAsyncQueue <ChainedHeader>)node1BlockStoreSignaled.GetMemberValue("blocksToAnnounce"); Queue <ChainedHeader> node1QueueItems = (Queue <ChainedHeader>)node1BlocksToAnnounce.GetMemberValue("items"); TestBase.WaitLoop(() => node1QueueItems.Count == 0); // Check that node2 does not have block 1 in test behaviour advertised list foreach (IncomingMessage message in testBehavior2.receivedMessageTracker["headers"]) { if (message.Message.Payload is HeadersPayload) { foreach (BlockHeader header in ((HeadersPayload)message.Message.Payload).Headers) { if (header.GetHash() == firstBlock.Header.GetHash()) { throw new Exception("Should not have received payload announcing block from wrong chain"); } } } } } }
public override object Clone() { var res = new TestBehavior(); return(res); }
public void CheckBlocksAnnounced_AndQueueEmptiesOverTime_ForMultiplePeers_WhenOneIsDisconnected() { using (NodeBuilder builder = NodeBuilder.Create(this)) { CoreNode stratisNodeSync = builder.CreateStratisPowNode(this.network, "bss-2-stratisNodeSync").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start(); CoreNode stratisNode1 = builder.CreateStratisPowNode(this.network, "bss-2-stratisNode1").Start(); CoreNode stratisNode2 = builder.CreateStratisPowNode(this.network, "bss-2-stratisNode2").Start(); CoreNode stratisNode3 = builder.CreateStratisPowNode(this.network, "bss-2-stratisNode3").Start(); // Change the other nodes' lists of default behaviours include the test behaviour in it. // We leave the other behaviors alone for this test because we want to see what messages the node gets under normal operation. IConnectionManager node1ConnectionManager = stratisNode1.FullNode.NodeService <IConnectionManager>(); node1ConnectionManager.Parameters.TemplateBehaviors.Add(new TestBehavior()); IConnectionManager node2ConnectionManager = stratisNode2.FullNode.NodeService <IConnectionManager>(); node2ConnectionManager.Parameters.TemplateBehaviors.Add(new TestBehavior()); // Connect other nodes to initial node. TestHelper.Connect(stratisNode1, stratisNodeSync); TestHelper.Connect(stratisNode2, stratisNodeSync); TestHelper.Connect(stratisNode3, stratisNodeSync); // Make node3 unable to respond to anything, effectively disconnecting it. IConnectionManager node3ConnectionManager = stratisNode3.FullNode.NodeService <IConnectionManager>(); node3ConnectionManager.Parameters.TemplateBehaviors.Clear(); node3ConnectionManager.Parameters.TemplateBehaviors.Add(new TestBehavior()); INetworkPeer connectedPeer1 = node1ConnectionManager.ConnectedPeers.FindByEndpoint(stratisNodeSync.Endpoint); TestBehavior testBehavior1 = connectedPeer1.Behavior <TestBehavior>(); INetworkPeer connectedPeer2 = node2ConnectionManager.ConnectedPeers.FindByEndpoint(stratisNodeSync.Endpoint); TestBehavior testBehavior2 = connectedPeer2.Behavior <TestBehavior>(); INetworkPeer connectedPeer3 = node3ConnectionManager.ConnectedPeers.FindByEndpoint(stratisNodeSync.Endpoint); TestBehavior testBehavior3 = connectedPeer3.Behavior <TestBehavior>(); // If the announce queue is not getting stalled, the other 2 nodes should sync properly. TestBase.WaitLoop(() => TestHelper.AreNodesSynced(stratisNode1, stratisNodeSync)); TestBase.WaitLoop(() => TestHelper.AreNodesSynced(stratisNode2, stratisNodeSync)); HashSet <uint256> advertised = new HashSet <uint256>(); // Check to see that all blocks got advertised to node1 via the "headers" payload. foreach (IncomingMessage message in testBehavior1.receivedMessageTracker["headers"]) { if (message.Message.Payload is HeadersPayload) { foreach (BlockHeader header in ((HeadersPayload)message.Message.Payload).Headers) { advertised.Add(header.GetHash()); } } } foreach (ChainedHeader chainedHeader in stratisNodeSync.FullNode.ChainIndexer.EnumerateToTip(this.network.GenesisHash)) { if ((!advertised.Contains(chainedHeader.HashBlock)) && (!(chainedHeader.HashBlock == this.network.GenesisHash))) { throw new Exception($"An expected block was not advertised to peer 1: {chainedHeader.HashBlock}"); } } advertised.Clear(); // Check to see that all blocks got advertised to node1 via the "headers" payload. foreach (IncomingMessage message in testBehavior2.receivedMessageTracker["headers"]) { if (message.Message.Payload is HeadersPayload) { foreach (BlockHeader header in ((HeadersPayload)message.Message.Payload).Headers) { advertised.Add(header.GetHash()); } } } foreach (ChainedHeader chainedHeader in stratisNodeSync.FullNode.ChainIndexer.EnumerateToTip(this.network.GenesisHash)) { if ((!advertised.Contains(chainedHeader.HashBlock)) && (!(chainedHeader.HashBlock == this.network.GenesisHash))) { throw new Exception($"An expected block was not advertised to peer 2: {chainedHeader.HashBlock}"); } } // Check current state of announce queue. BlockStoreSignaled blockStoreSignaled = stratisNodeSync.FullNode.NodeService <BlockStoreSignaled>(); IAsyncQueue <ChainedHeader> blocksToAnnounce = (IAsyncQueue <ChainedHeader>)blockStoreSignaled.GetMemberValue("blocksToAnnounce"); Queue <ChainedHeader> queueItems = (Queue <ChainedHeader>)blocksToAnnounce.GetMemberValue("items"); // It should still eventually empty despite not being able to communicate with node3. TestBase.WaitLoop(() => queueItems.Count == 0); } }