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 Byzantium_reward_two_uncles() { long blockNumber = RopstenSpecProvider.ByzantiumBlockNumber; Block uncle = Build.A.Block.WithNumber(blockNumber - 2).TestObject; Block uncle2 = Build.A.Block.WithNumber(blockNumber - 2).TestObject; Block block = Build.A.Block.WithNumber(blockNumber).WithUncles(uncle, uncle2).WithTotalDifficulty(1L).WithDifficulty(300).TestObject; Block block2 = Build.A.Block.WithNumber(blockNumber + 1).WithUncles(uncle, uncle2).WithTotalDifficulty(3L).WithDifficulty(0).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(); poSSwitcher.TryUpdateTerminalBlock(block.Header); MergeRewardCalculator calculator = new(new RewardCalculator(RopstenSpecProvider.Instance), poSSwitcher); BlockReward[] rewards = calculator.CalculateRewards(block); Assert.AreEqual(3, rewards.Length); Assert.AreEqual(3187500000000000000, (long)rewards[0].Value, "miner"); Assert.AreEqual(2250000000000000000, (long)rewards[1].Value, "uncle1"); Assert.AreEqual(2250000000000000000, (long)rewards[2].Value, "uncle2"); rewards = calculator.CalculateRewards(block2); Assert.AreEqual(0, rewards.Length); }
public void IsTerminalBlock_returning_expected_result_for_genesis_block(long genesisDifficulty, bool expectedResult) { TestSpecProvider specProvider = new(London.Instance); specProvider.TerminalTotalDifficulty = (UInt256)5000000; Block genesisBlock = Build.A.Block.WithNumber(0).WithDifficulty((UInt256)genesisDifficulty) .WithTotalDifficulty(genesisDifficulty).TestObject; BlockTree blockTree = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(6).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, new MemDb(), specProvider); Assert.AreEqual(expectedResult, genesisBlock.IsTerminalBlock(specProvider)); }
public void No_block_rewards_calculator() { Block block = Build.A.Block.WithTotalDifficulty(1L).WithDifficulty(0).TestObject; Block block2 = Build.A.Block.WithTotalDifficulty(3L).WithDifficulty(0).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(); poSSwitcher.TryUpdateTerminalBlock(block.Header); MergeRewardCalculator calculator = new(NoBlockRewards.Instance, poSSwitcher); BlockReward[] rewards = calculator.CalculateRewards(block); Assert.AreEqual(0, rewards.Length); rewards = calculator.CalculateRewards(block2); Assert.AreEqual(0, rewards.Length); }
private IBlockValidator CreateBlockValidator() { IBlockCacheService blockCacheService = new BlockCacheService(); PoSSwitcher = new PoSSwitcher(MergeConfig, SyncConfig.Default, new MemDb(), BlockTree, SpecProvider, LogManager); SealValidator = new MergeSealValidator(PoSSwitcher, Always.Valid); HeaderValidator preMergeHeaderValidator = new HeaderValidator(BlockTree, SealValidator, SpecProvider, LogManager); HeaderValidator = new MergeHeaderValidator(PoSSwitcher, preMergeHeaderValidator, BlockTree, SpecProvider, SealValidator, LogManager); return(new BlockValidator( new TxValidator(SpecProvider.ChainId), HeaderValidator, Always.Valid, SpecProvider, LogManager)); }
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 No_uncles() { Block block = Build.A.Block.WithNumber(2).WithTotalDifficulty(1L).WithDifficulty(300).TestObject; Block block2 = Build.A.Block.WithNumber(3).WithTotalDifficulty(3L).WithDifficulty(0).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(); poSSwitcher.TryUpdateTerminalBlock(block.Header); MergeRewardCalculator calculator = new(new RewardCalculator(RopstenSpecProvider.Instance), poSSwitcher); BlockReward[] rewards = calculator.CalculateRewards(block); Assert.AreEqual(1, rewards.Length); Assert.AreEqual(5000000000000000000, (long)rewards[0].Value, "miner"); rewards = calculator.CalculateRewards(block2); Assert.AreEqual(0, rewards.Length); }
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)); }
public void IsTerminalBlock_returning_expected_results(long terminalTotalDifficulty) { Block genesisBlock = Build.A.Block.WithNumber(0).TestObject; TestSpecProvider specProvider = new(London.Instance); specProvider.TerminalTotalDifficulty = (UInt256)terminalTotalDifficulty; BlockTree blockTree = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(6).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, new MemDb(), specProvider); BlockHeader?block3 = blockTree.FindHeader(3, BlockTreeLookupOptions.All); BlockHeader?block4 = blockTree.FindHeader(4, BlockTreeLookupOptions.All); BlockHeader?block5 = blockTree.FindHeader(5, BlockTreeLookupOptions.All); Block blockWithPostMergeFlag = Build.A.Block.WithNumber(4).WithDifficulty(0).WithPostMergeFlag(true) .WithParent(block3 !).TestObject; Assert.AreEqual(false, block3 !.IsTerminalBlock(specProvider)); // PoWBlock Assert.AreEqual(true, block4 !.IsTerminalBlock(specProvider)); // terminal block Assert.AreEqual(false, block5 !.IsTerminalBlock(specProvider)); // incorrect PoW not terminal block Assert.AreEqual(false, blockWithPostMergeFlag.IsTerminalBlock(specProvider)); // block with post merge flag }
public void GetBlockSwitchInfo_returning_expected_results(long terminalTotalDifficulty) { TestSpecProvider specProvider = new(London.Instance); specProvider.TerminalTotalDifficulty = (UInt256)terminalTotalDifficulty; Block genesisBlock = Build.A.Block.WithNumber(0).TestObject; BlockTree blockTree = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(6).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, new MemDb(), specProvider); BlockHeader?block3 = blockTree.FindHeader(3, BlockTreeLookupOptions.All); BlockHeader?block4 = blockTree.FindHeader(4, BlockTreeLookupOptions.All); BlockHeader?block5 = blockTree.FindHeader(5, BlockTreeLookupOptions.All); Block blockWithPostMergeFlag = Build.A.Block.WithNumber(4).WithDifficulty(0).WithPostMergeFlag(true) .WithParent(block3 !).TestObject; Assert.AreEqual((false, false), poSSwitcher.GetBlockConsensusInfo(block3 !)); // PoWBlock Assert.AreEqual((true, false), poSSwitcher.GetBlockConsensusInfo(block4 !)); // terminal block Assert.AreEqual((false, true), poSSwitcher.GetBlockConsensusInfo(block5 !)); // incorrect PoW, TTD > TD and it is not terminal, so we should process it in the same way like post merge blocks Assert.AreEqual((false, true), poSSwitcher.GetBlockConsensusInfo(blockWithPostMergeFlag.Header)); // block with post merge flag }
public void Two_uncles_from_the_same_coinbase() { Block uncle = Build.A.Block.WithNumber(1).TestObject; Block uncle2 = Build.A.Block.WithNumber(1).TestObject; Block block = Build.A.Block.WithNumber(3).WithUncles(uncle, uncle2).WithTotalDifficulty(1L).WithDifficulty(30).TestObject; Block block2 = Build.A.Block.WithNumber(4).WithUncles(uncle, uncle2).WithTotalDifficulty(2L).WithDifficulty(0).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(); poSSwitcher.TryUpdateTerminalBlock(block.Header); MergeRewardCalculator calculator = new(new RewardCalculator(RopstenSpecProvider.Instance), poSSwitcher); BlockReward[] rewards = calculator.CalculateRewards(block); Assert.AreEqual(3, rewards.Length); Assert.AreEqual(5312500000000000000, (long)rewards[0].Value, "miner"); Assert.AreEqual(3750000000000000000, (long)rewards[1].Value, "uncle1"); Assert.AreEqual(3750000000000000000, (long)rewards[2].Value, "uncle2"); rewards = calculator.CalculateRewards(block2); Assert.AreEqual(0, rewards.Length); }
public void GetBlockSwitchInfo_returning_expected_results_when_td_null_or_zero(long terminalTotalDifficulty, bool nullTdValue) { TestSpecProvider specProvider = new(London.Instance); specProvider.TerminalTotalDifficulty = (UInt256)terminalTotalDifficulty; Block genesisBlock = Build.A.Block.WithNumber(0).TestObject; BlockTree blockTree = Build.A.BlockTree(genesisBlock, specProvider).OfChainLength(6).TestObject; PoSSwitcher poSSwitcher = CreatePosSwitcher(blockTree, new MemDb(), specProvider); BlockHeader?block3 = blockTree.FindHeader(3, BlockTreeLookupOptions.All); BlockHeader?block4 = blockTree.FindHeader(4, BlockTreeLookupOptions.All); BlockHeader?block5 = blockTree.FindHeader(5, BlockTreeLookupOptions.All); Block blockWithPostMergeFlag = Build.A.Block.WithNumber(4).WithDifficulty(0).WithPostMergeFlag(true) .WithParent(block3 !).TestObject; block3 !.TotalDifficulty = nullTdValue ? null : UInt256.Zero; block4 !.TotalDifficulty = nullTdValue ? null : UInt256.Zero; block5 !.TotalDifficulty = nullTdValue ? null : UInt256.Zero; Assert.AreEqual((false, false), poSSwitcher.GetBlockConsensusInfo(block3 !)); // PoWBlock Assert.AreEqual((false, false), poSSwitcher.GetBlockConsensusInfo(block4 !)); // terminal block Assert.AreEqual((false, false), poSSwitcher.GetBlockConsensusInfo(block5 !)); Assert.AreEqual((false, true), poSSwitcher.GetBlockConsensusInfo(blockWithPostMergeFlag.Header)); // block with post merge flag }