public static void AddBranch(this BlockTree blockTree, int branchLength, int splitBlockNumber) { var splitVariant = 0; BlockTree alternative = Build.A.BlockTree(blockTree.FindBlock(0, BlockTreeLookupOptions.RequireCanonical)).OfChainLength(branchLength, splitVariant).TestObject; List <Block> blocks = new List <Block>(); Keccak parentHash = null; for (int i = splitBlockNumber + 1; i < branchLength; i++) { Block block = alternative.FindBlock(i, BlockTreeLookupOptions.RequireCanonical); if (i == splitBlockNumber + 1) { var mainBlock = blockTree.FindBlock(i - 1, BlockTreeLookupOptions.RequireCanonical); if (mainBlock != null) { parentHash = mainBlock.Hash; } } block.Header.ParentHash = parentHash; block.Header.Hash = block.Header.CalculateHash(); parentHash = block.Hash; blockTree.SuggestBlock(block, i == branchLength - 1, false); blocks.Add(block); } }
public async Task Feed_able_to_sync_when_new_pivot_is_set() { BlockTree syncedBlockTree = Build.A.BlockTree().OfChainLength(1000).TestObject; Block genesisBlock = syncedBlockTree.FindBlock(syncedBlockTree.GenesisHash, BlockTreeLookupOptions.None) !; BlockTree blockTree = Build.A.BlockTree().TestObject; blockTree.SuggestBlock(genesisBlock); ISyncConfig syncConfig = new SyncConfig { FastSync = true, FastBlocks = true, PivotNumber = "500", PivotHash = Keccak.Zero.ToString(), PivotTotalDifficulty = "1000000" // default difficulty in block tree builder }; BlockHeader? pivotHeader = syncedBlockTree.FindHeader(700, BlockTreeLookupOptions.None); IBeaconPivot pivot = PreparePivot(700, syncConfig, blockTree, pivotHeader); Context ctx = new (blockTree, syncConfig, pivot); BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 0, 501); // move best pointers forward as proxy for chain merge Block highestBlock = syncedBlockTree.FindBlock(700, BlockTreeLookupOptions.None) !; blockTree.Insert(highestBlock, BlockTreeInsertBlockOptions.SaveHeader); pivot.EnsurePivot(syncedBlockTree.FindHeader(900, BlockTreeLookupOptions.None)); BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 700, 701); highestBlock = syncedBlockTree.FindBlock(900, BlockTreeLookupOptions.None) !; blockTree.Insert(highestBlock, BlockTreeInsertBlockOptions.SaveHeader); pivot.EnsurePivot(syncedBlockTree.FindHeader(999, BlockTreeLookupOptions.None)); BuildAndProcessHeaderSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 900, 901); }
public async Task Feed_able_to_connect_to_existing_chain_through_block_hash() { BlockTree syncedBlockTree = Build.A.BlockTree().OfChainLength(600).TestObject; Block genesisBlock = syncedBlockTree.FindBlock(syncedBlockTree.GenesisHash, BlockTreeLookupOptions.None) !; BlockTree blockTree = Build.A.BlockTree().TestObject; blockTree.SuggestBlock(genesisBlock); Block?firstBlock = syncedBlockTree.FindBlock(1, BlockTreeLookupOptions.None); blockTree.SuggestBlock(firstBlock); BlockHeader? pivotHeader = syncedBlockTree.FindHeader(500, BlockTreeLookupOptions.None); IBeaconPivot pivot = PreparePivot(500, new SyncConfig(), blockTree, pivotHeader); Context ctx = new (blockTree, new SyncConfig(), pivot); // fork in chain Block parent = firstBlock; for (int i = 0; i < 5; i++) { Block block = Build.A.Block.WithParent(parent).WithNonce(1).TestObject; blockTree.SuggestBlock(block); parent = block; } ctx.BeaconSync.ShouldBeInBeaconHeaders().Should().BeTrue(); blockTree.BestKnownNumber.Should().Be(6); BuildHeadersSyncBatches(ctx, blockTree, syncedBlockTree, pivot, 2); HeadersSyncBatch result = await ctx.Feed.PrepareRequest(); result.Should().BeNull(); blockTree.BestKnownNumber.Should().Be(6); ctx.Feed.CurrentState.Should().Be(SyncFeedState.Dormant); ctx.BeaconSync.ShouldBeInBeaconHeaders().Should().BeFalse(); }
public static void AddBranch(this BlockTree blockTree, int branchLength, int splitBlockNumber) { int splitVariant = 0; BlockTree alternative = Build.A.BlockTree(blockTree.FindBlock(0, BlockTreeLookupOptions.RequireCanonical) !).OfChainLength(branchLength, splitVariant).TestObject; Block? parent = null; for (int i = splitBlockNumber + 1; i < branchLength; i++) { Block block = alternative.FindBlock(i, BlockTreeLookupOptions.RequireCanonical) !; if (i == splitBlockNumber + 1) { Block?mainBlock = blockTree.FindBlock(i - 1, BlockTreeLookupOptions.RequireCanonical); if (mainBlock != null) { parent = mainBlock; } } block.Header.ParentHash = parent?.Hash; block.Header.StateRoot = parent?.StateRoot; block.Header.Hash = block.Header.CalculateHash(); parent = block; blockTree.SuggestBlock(block, i == branchLength - 1, false); } }
public async Task Can_load_blocks_from_db_odd() { for (int chainLength = 2; chainLength <= 32; chainLength++) { Block genesisBlock = Build.A.Block.Genesis.TestObject; MemDb blocksDb = new MemDb(); MemDb blockInfosDb = new MemDb(); BlockTree testTree = Build.A.BlockTree(genesisBlock).OfChainLength(chainLength).TestObject; for (int i = 0; i < testTree.Head.Number + 1; i++) { Block ithBlock = testTree.FindBlock((ulong)i); blocksDb.Set(ithBlock.Hash, Rlp.Encode(ithBlock).Bytes); ChainLevelInfo ithLevel = new ChainLevelInfo(true, new BlockInfo[1] { new BlockInfo(ithBlock.Hash, ithBlock.TotalDifficulty.Value, (ulong)ithBlock.Transactions.Length) }); blockInfosDb.Set(i, Rlp.Encode(ithLevel).Bytes); } blocksDb.Set(Keccak.Zero, Rlp.Encode(testTree.FindBlock(1)).Bytes); BlockTree blockTree = new BlockTree(blocksDb, blockInfosDb, OlympicSpecProvider.Instance, Substitute.For <ITransactionPool>(), LimboLogs.Instance); await blockTree.LoadBlocksFromDb(CancellationToken.None); Assert.AreEqual(blockTree.BestSuggested.Hash, testTree.Head.Hash, $"head {chainLength}"); } }
public async Task Can_load_blocks_from_db() { for (int chainLength = 2; chainLength <= 32; chainLength++) { Block genesisBlock = Build.A.Block.Genesis.TestObject; MemDb blocksDb = new(); MemDb blockInfosDb = new(); MemDb headersDb = new(); BlockTree testTree = Build.A.BlockTree(genesisBlock).OfChainLength(chainLength).TestObject; for (int i = 0; i < testTree.Head.Number + 1; i++) { Block ithBlock = testTree.FindBlock(i, BlockTreeLookupOptions.None); blocksDb.Set(ithBlock.Hash, Rlp.Encode(ithBlock).Bytes); headersDb.Set(ithBlock.Hash, Rlp.Encode(ithBlock.Header).Bytes); ChainLevelInfo ithLevel = new( true, new BlockInfo[1] { new( ithBlock.Hash, ithBlock.TotalDifficulty.Value) { WasProcessed = true } });
protected override UInt256 CalculateDifficulty(BlockHeader parent, UInt256 timestamp) { Block parentBlock = BlockTree.FindBlock(parent.Hash, BlockTreeLookupOptions.None); return(_difficultyCalculator.Calculate( parent.Difficulty, parent.Timestamp, timestamp, parent.Number + 1, parentBlock.Ommers.Length > 0)); }
public async Task Can_load_blocks_from_db_odd() { for (int chainLength = 2; chainLength <= 32; chainLength++) { Block genesisBlock = Build.A.Block.Genesis.TestObject; MemDb blocksDb = new MemDb(); MemDb blockInfosDb = new MemDb(); MemDb headersDb = new MemDb(); BlockTree testTree = Build.A.BlockTree(genesisBlock).OfChainLength(chainLength).TestObject; for (int i = 0; i < testTree.Head.Number + 1; i++) { Block ithBlock = testTree.FindBlock(i, BlockTreeLookupOptions.None); blocksDb.Set(ithBlock.Hash, Rlp.Encode(ithBlock).Bytes); headersDb.Set(ithBlock.Hash, Rlp.Encode(ithBlock.Header).Bytes); ChainLevelInfo ithLevel = new ChainLevelInfo(true, new BlockInfo[1] { new BlockInfo(ithBlock.Hash, ithBlock.TotalDifficulty.Value) }); blockInfosDb.Set(i, Rlp.Encode(ithLevel).Bytes); } blockInfosDb.Set(Keccak.Zero, genesisBlock.Header.Hash.Bytes); headersDb.Set(genesisBlock.Header.Hash, Rlp.Encode(genesisBlock.Header).Bytes); BlockTree blockTree = new BlockTree(blocksDb, headersDb, blockInfosDb, new ChainLevelInfoRepository(blockInfosDb), OlympicSpecProvider.Instance, Substitute.For <ITxPool>(), NullBloomStorage.Instance, LimboLogs.Instance); DbBlocksLoader loader = new DbBlocksLoader(blockTree, LimboNoErrorLogger.Instance); await blockTree.Accept(loader, CancellationToken.None); Assert.AreEqual(testTree.Head.Hash, blockTree.BestSuggestedHeader.Hash, $"head {chainLength}"); } }
public void Can_accept_new_valid_blocks(bool sealOk, bool validationOk, bool accepted) { BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject; BlockTree localBlockTree = Build.A.BlockTree().OfChainLength(9).TestObject; ISealValidator sealValidator = sealOk ? TestSealValidator.AlwaysValid : TestSealValidator.NeverValid; IBlockValidator blockValidator = validationOk ? TestBlockValidator.AlwaysValid : TestBlockValidator.NeverValid; _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, blockValidator, sealValidator, _peerPool, _synchronizer, new SyncConfig(), LimboLogs.Instance); Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None); _synchronizer.SyncMode.Returns(SyncMode.Full); if (!accepted) { Assert.Throws <EthSynchronizationException>(() => _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock)); } else { _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock); } if (accepted) { Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header); } else { Assert.AreNotEqual(localBlockTree.BestSuggestedHeader, block.Header); } }
private void SetupLocalTree(int length = 1) { _localBlockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), MainNetSpecProvider.Instance, NullTxPool.Instance, _syncConfig, LimboLogs.Instance); for (int i = 0; i < length; i++) { _localBlockTree.SuggestBlock(_validTree2048.FindBlock(i)); } }
public void Test_real_block(string blockRlp) { Block block = Rlp.Decode <Block>(new Rlp(Bytes.FromHexString(blockRlp))); bool validHeader = _clique.ValidateParams(_blockTree.FindBlock(block.ParentHash, false), block.Header); bool validSeal = _clique.ValidateSeal(block.Header); Assert.True(validHeader); Assert.True(validSeal); }
public void Add_on_branch_and_not_find_on_main() { BlockTree blockTree = BuildBlockTree(); Block block = Build.A.Block.TestObject; blockTree.SuggestBlock(block); Block found = blockTree.FindBlock(block.Hash, true); Assert.IsNull(found); }
public void Add_on_branch_move_find() { BlockTree blockTree = BuildBlockTree(); Block block = Build.A.Block.TestObject; AddToMain(blockTree, block); Block found = blockTree.FindBlock(block.Hash, true); Assert.AreEqual(block.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Add_and_find_branch() { BlockTree blockTree = BuildBlockTree(); Block block = Build.A.Block.TestObject; blockTree.SuggestBlock(block); Block found = blockTree.FindBlock(block.Hash, false); Assert.AreEqual(block.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Add_and_find_branch() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block = Build.A.Block.TestObject; blockTree.SuggestBlock(block); Block found = blockTree.FindBlock(block.Hash, false); Assert.AreEqual(block.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Add_on_branch_move_find() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block = Build.A.Block.TestObject; AddToMain(blockTree, block); Block found = blockTree.FindBlock(block.Hash, true); Assert.AreEqual(block.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Add_on_branch_and_not_find_on_main() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block = Build.A.Block.TestObject; blockTree.SuggestBlock(block); Block found = blockTree.FindBlock(block.Hash, true); Assert.IsNull(found); }
private void SetupLocalTree(int length = 1) { var blockInfoDb = new MemDb(); _localBlockTree = new BlockTree(new MemDb(), new MemDb(), blockInfoDb, new ChainLevelInfoRepository(blockInfoDb), MainNetSpecProvider.Instance, NullTxPool.Instance, _syncConfig, LimboLogs.Instance); for (int i = 0; i < length; i++) { _localBlockTree.SuggestBlock(_validTree2048.FindBlock(i, BlockTreeLookupOptions.None)); } }
public async Task Can_sign_block() { Block block6 = CreateBlock(2, 6, _lastBlock); Block signed = await _clique.SealBlock(block6, CancellationToken.None); bool validHeader = _clique.ValidateParams(_blockTree.FindBlock(signed.ParentHash, false), signed.Header); bool validSeal = _clique.ValidateSeal(signed.Header); Assert.True(validHeader); Assert.True(validSeal); }
public void Find_by_number_negative() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); Assert.Throws <ArgumentException>(() => blockTree.FindBlock(-1)); }
public void Find_by_number_returns_null_when_block_is_missing() { BlockTree blockTree = BuildBlockTree(); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); Block found = blockTree.FindBlock(5); Assert.IsNull(found); }
public void Find_by_number_missing() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); Block found = blockTree.FindBlock(5); Assert.IsNull(found); }
public void Rejects_new_blocks_with_failing_seal() { BlockTree remoteBlockTree = Build.A.BlockTree().OfChainLength(10).TestObject; BlockTree localBlockTree = Build.A.BlockTree().OfChainLength(9).TestObject; _syncServer = new SyncServer(new StateDb(), new StateDb(), localBlockTree, NullReceiptStorage.Instance, TestBlockValidator.AlwaysValid, TestSealValidator.AlwaysValid, _peerPool, _synchronizer, new SyncConfig(), LimboLogs.Instance); Block block = remoteBlockTree.FindBlock(9, BlockTreeLookupOptions.None); _synchronizer.SyncMode.Returns(SyncMode.Full); _syncServer.AddNewBlock(block, _nodeWhoSentTheBlock); Assert.AreEqual(localBlockTree.BestSuggestedHeader, block.Header); }
public void Find_by_number_basic() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; Block block2 = Build.A.Block.WithNumber(2).WithParent(block1).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); AddToMain(blockTree, block2); Block found = blockTree.FindBlock(2); Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(found.Header)); }
public static void AddBranch(this BlockTree blockTree, int branchLength, int splitBlockNumber, int splitVariant) { BlockTree alternative = Build.A.BlockTree(blockTree.RetrieveGenesisBlock()).OfChainLength(branchLength, splitBlockNumber, splitVariant).TestObject; for (int i = splitBlockNumber + 1; i < branchLength; i++) { Block block = alternative.FindBlock((ulong)i); blockTree.SuggestBlock(block); blockTree.MarkAsProcessed(block.Hash); if (branchLength > blockTree.Head.Number) { blockTree.MoveToMain(block.Hash); } } }
public void Find_by_number_beyond_what_is_known_returns_null() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; Block block2 = Build.A.Block.WithNumber(2).WithParent(block1).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); AddToMain(blockTree, block2); Block found = blockTree.FindBlock(1920000); Assert.Null(found); }
public void Stores_multiple_blocks_per_level() { BlockTree blockTree = new BlockTree(new MemDb(), new MemDb(), new MemDb(), OlympicSpecProvider.Instance, NullLogManager.Instance); Block block0 = Build.A.Block.WithNumber(0).WithDifficulty(1).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject; Block block1B = Build.A.Block.WithNumber(1).WithDifficulty(3).WithParent(block0).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); blockTree.SuggestBlock(block1B); Block found = blockTree.FindBlock(block1B.Hash, false); Assert.AreEqual(block1B.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Stores_multiple_blocks_per_level() { BlockTree blockTree = BuildBlockTree(); Block block0 = Build.A.Block.WithNumber(0).WithDifficulty(1).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithDifficulty(2).WithParent(block0).TestObject; Block block1B = Build.A.Block.WithNumber(1).WithDifficulty(3).WithParent(block0).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); blockTree.SuggestBlock(block1B); Block found = blockTree.FindBlock(block1B.Hash, false); Assert.AreEqual(block1B.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Find_by_number_basic() { BlockTree blockTree = BuildBlockTree(); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; Block block2 = Build.A.Block.WithNumber(2).WithParent(block1).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); AddToMain(blockTree, block2); Block found = blockTree.FindBlock(2); Assert.AreEqual(block2.Hash, BlockHeader.CalculateHash(found.Header)); }
public void Find_by_number_beyond_what_is_known_returns_null() { BlockTree blockTree = BuildBlockTree(); Block block0 = Build.A.Block.WithNumber(0).TestObject; Block block1 = Build.A.Block.WithNumber(1).WithParent(block0).TestObject; Block block2 = Build.A.Block.WithNumber(2).WithParent(block1).TestObject; AddToMain(blockTree, block0); AddToMain(blockTree, block1); AddToMain(blockTree, block2); Block found = blockTree.FindBlock(1920000); Assert.Null(found); }