public void Can_load_parameters_after_the_restart()
        {
            using MemDb metadataDb = new();
            int terminalBlock             = 4;
            TestSpecProvider specProvider = new(London.Instance);

            specProvider.TerminalTotalDifficulty = 5000000;
            Block       genesisBlock = Build.A.Block.WithNumber(0).TestObject;
            BlockTree   blockTree    = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(4).TestObject;
            PoSSwitcher poSSwitcher  = CreatePosSwitcher(blockTree, metadataDb, specProvider);

            Assert.AreEqual(false, poSSwitcher.HasEverReachedTerminalBlock());
            Block block = Build.A.Block.WithTotalDifficulty(5000000L).WithNumber(terminalBlock).WithParent(blockTree.Head !).WithDifficulty(1000000L).TestObject;

            blockTree.SuggestBlock(block);
            blockTree.UpdateMainChain(block);
            Assert.AreEqual(terminalBlock + 1, specProvider.MergeBlockNumber);
            Assert.AreEqual(true, poSSwitcher.HasEverReachedTerminalBlock());

            TestSpecProvider newSpecProvider = new(London.Instance);

            newSpecProvider.TerminalTotalDifficulty = 5000000L;
            // we're using the same MemDb for a new switcher
            PoSSwitcher newPoSSwitcher = CreatePosSwitcher(blockTree, metadataDb, newSpecProvider);

            Assert.AreEqual(terminalBlock + 1, newSpecProvider.MergeBlockNumber);
            Assert.AreEqual(true, newPoSSwitcher.HasEverReachedTerminalBlock());
        }
        public void Switch_when_TTD_is_reached()
        {
            TestSpecProvider specProvider = new(London.Instance);

            specProvider.TerminalTotalDifficulty = 5000000;
            Block     genesisBlock = Build.A.Block.WithNumber(0).TestObject;
            BlockTree blockTree    = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(4).TestObject;

            PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, new MemDb(), specProvider);

            Assert.AreEqual(false, poSSwitcher.HasEverReachedTerminalBlock());
            Block block = Build.A.Block.WithTotalDifficulty(5000000L).WithNumber(4).WithParent(blockTree.Head !).WithDifficulty(1000000L).TestObject;

            blockTree.SuggestBlock(block);
            blockTree.UpdateMainChain(block);

            Assert.AreEqual(true, poSSwitcher.HasEverReachedTerminalBlock());
        }
        public void New_terminal_block_when_ttd_reached()
        {
            TestSpecProvider specProvider = new(London.Instance);

            specProvider.TerminalTotalDifficulty = 5000000;
            Block     genesisBlock = Build.A.Block.WithNumber(0).TestObject;
            BlockTree blockTree    = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(4).TestObject;

            PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, new MemDb(), specProvider);

            Assert.AreEqual(false, poSSwitcher.HasEverReachedTerminalBlock());
            Block block = Build.A.Block.WithTotalDifficulty(5000000L).WithNumber(4).WithParent(blockTree.Head !).WithDifficulty(1000000L).TestObject;
            Block alternativeTerminalBlock = Build.A.Block.WithTotalDifficulty(5000000L).WithNumber(4).WithParent(blockTree.Head !).WithGasLimit(20000000).WithDifficulty(1000000L).TestObject;

            blockTree.SuggestBlock(block);
            blockTree.UpdateMainChain(block);
            Assert.AreEqual(true, poSSwitcher.HasEverReachedTerminalBlock());
            Assert.AreEqual((true, false), poSSwitcher.GetBlockConsensusInfo(alternativeTerminalBlock.Header));
        }