public void ConsensusManager_Connect_New_Block_Failed()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                var syncerNetwork = new BitcoinOverrideRegTest();

                // Inject a rule that will fail at block 11 of the new chain
                syncerNetwork.Consensus.ConsensusRules.FullValidationRules.Insert(1, typeof(FailValidation11));

                var minerA = builder.CreateStratisPowNode(this.powNetwork, "cm-8-minerA").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start();
                var syncer = builder.CreateStratisPowNode(syncerNetwork, "cm-8-syncer").Start();

                // Miner A mines to height 11.
                TestHelper.MineBlocks(minerA, 1);

                // Connect syncer to Miner A, reorg should fail.
                TestHelper.ConnectNoCheck(syncer, minerA);

                // Syncer should disconnect from miner A after the failed block.
                TestBase.WaitLoop(() => !TestHelper.IsNodeConnectedTo(syncer, minerA));

                // Make sure syncer rolled back
                Assert.True(TestHelper.IsNodeSyncedAtHeight(syncer, 10));
            }
        }
        public void ConsensusManager_Reorgs_Then_Try_To_Connect_Longer_Chain_With_Connected_Blocks_And_Fail_Then_Revert_Back()
        {
            using (NodeBuilder builder = NodeBuilder.Create(this))
            {
                var syncerNetwork = new BitcoinOverrideRegTest("regtet1");

                // Inject a rule that will fail at block 15 of the new chain.
                syncerNetwork.Consensus.ConsensusRules.FullValidationRules.Insert(1, typeof(FailValidation15_2));

                var minerA = builder.CreateStratisPowNode(this.powNetwork, "cm-5-minerA").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Miner).Start();
                var minerB = builder.CreateStratisPowNode(this.powNetwork, "cm-5-minerB").WithReadyBlockchainData(ReadyBlockchain.BitcoinRegTest10Listener).Start();
                var syncer = builder.CreateStratisPowNode(syncerNetwork, "cm-5-syncer").Start();

                // Sync the network to height 10.
                TestHelper.ConnectAndSync(syncer, minerA, minerB);

                // Disable syncer from sending blocks to miner B
                TestHelper.DisableBlockPropagation(syncer, minerB);

                // Miner A and syncer continues to mine to height 20.
                TestHelper.MineBlocks(minerA, 10);
                TestBase.WaitLoop(() => TestHelper.AreNodesSynced(syncer, minerA));

                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerA, 20));
                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerB, 10));
                Assert.True(TestHelper.IsNodeSyncedAtHeight(syncer, 20));

                // Miner B continues to mine to height 30 on a new and longer chain.
                TestHelper.MineBlocks(minerB, 20);

                // check miner B at height 30.
                Assert.True(TestHelper.IsNodeSyncedAtHeight(minerB, 30));

                // Miner B should become disconnected.
                TestBase.WaitLoop(() => !TestHelper.IsNodeConnectedTo(syncer, minerB));

                // Make sure syncer rolled back.
                TestBase.WaitLoop(() => syncer.FullNode.ConsensusManager().Tip.Height == 20);

                // Check syncer is still synced with Miner A.
                TestBase.WaitLoop(() => TestHelper.AreNodesSynced(syncer, minerA));
            }
        }