public async Task ReorgChain_FailsPartialValidation_Nodes_DisconnectedAsync() { using (var builder = NodeBuilder.Create(this)) { var noValidationRulesNetwork = new BitcoinRegTestNoValidationRules(); var minerA = builder.CreateStratisPowNode(this.powNetwork, "cmfr-5-minerA").WithDummyWallet().WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start(); var minerB = builder.CreateStratisPowNode(noValidationRulesNetwork, "cmfr-5-minerB").NoValidation().WithDummyWallet().Start(); // Miner B syncs with Miner A TestHelper.ConnectAndSync(minerB, minerA); // Disconnect Miner A from Miner B TestHelper.Disconnect(minerB, minerA); // Miner A continues to mine to height 14 TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 14); // Miner B mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid var minerBTip = await TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(14, (coreNode, block) => BlockBuilder.InvalidDuplicateCoinbase(coreNode, block)).BuildAsync(); // Reconnect Miner A to Miner B. TestHelper.ConnectNoCheck(minerA, minerB); // Miner A will disconnect Miner B TestHelper.WaitLoop(() => !TestHelper.IsNodeConnectedTo(minerA, minerB)); // Ensure Miner A and Miner B remains on their respective heights. var badBlockOnMinerBChain = minerBTip.GetAncestor(14); Assert.Null(minerA.FullNode.ConsensusManager().Tip.FindAncestorOrSelf(badBlockOnMinerBChain)); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 14); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 15); } }
public void ReorgChain_FailsPartialValidation_Nodes_Disconnected() { using (var builder = NodeBuilder.Create(this)) { var noValidationRulesNetwork = new BitcoinRegTestNoValidationRules(); var minerA = builder.CreateStratisPowNode(this.powNetwork).WithDummyWallet().Start(); var minerB = builder.CreateStratisPowNode(noValidationRulesNetwork).NoValidation().WithDummyWallet().Start(); // MinerA mines 5 blocks TestHelper.MineBlocks(minerA, 5); // MinerB syncs with MinerA TestHelper.ConnectAndSync(minerB, minerA); // Disconnect minerA from miner B TestHelper.Disconnect(minerB, minerA); // Miner A continues to mine to height 9 TestHelper.MineBlocks(minerA, 4); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); // MinerB mines 5 more blocks: // Block 6,7,9,10 = valid // Block 8 = invalid TestHelper.BuildBlocks.OnNode(minerB).Amount(5).Invalid(8, (coreNode, block) => BlockBuilder.InvalidDuplicateCoinbase(coreNode, block)).BuildAsync(); // Reconnect minerA to minerB. // This will cause the reorg chain to fail at block 8 and roll back any changes. TestHelper.Connect(minerA, minerB); TestHelper.WaitLoop(() => minerA.FullNode.ConsensusManager().Tip.Height == 9); TestHelper.WaitLoop(() => minerB.FullNode.ConsensusManager().Tip.Height == 10); } }