public void Can_retrieve_empty_receipts() { _blockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(2).TestObject; Block block0 = _blockTree.FindBlock(0, BlockTreeLookupOptions.None); Block block1 = _blockTree.FindBlock(1, BlockTreeLookupOptions.None); _syncServer.GetReceipts(block0.Hash).Should().HaveCount(0); _syncServer.GetReceipts(block1.Hash).Should().HaveCount(0); _syncServer.GetReceipts(TestItem.KeccakA).Should().HaveCount(0); }
public Task <Block[]> GetBlocks(Keccak[] blockHashes, CancellationToken token) { Block[] result = new Block[blockHashes.Length]; for (int i = 0; i < blockHashes.Length; i++) { result[i] = _blockTree.FindBlock(blockHashes[i], true); } return(Task.FromResult(result)); }
public Task <BlockBody[]> GetBlocks(Keccak[] blockHashes, CancellationToken token) { BlockBody[] result = new BlockBody[blockHashes.Length]; for (int i = 0; i < blockHashes.Length; i++) { Block block = _remoteTree.FindBlock(blockHashes[i], true); result[i] = new BlockBody(block.Transactions, block.Ommers); } return(Task.FromResult(result)); }
public Task <BlockBody[]> GetBlockBodies(IList <Keccak> blockHashes, CancellationToken token) { BlockBody[] result = new BlockBody[blockHashes.Count]; for (int i = 0; i < blockHashes.Count; i++) { Block block = _remoteTree.FindBlock(blockHashes[i], BlockTreeLookupOptions.RequireCanonical); result[i] = new BlockBody(block.Transactions, block.Ommers); } return(Task.FromResult(result)); }
public void Can_retrieve_empty_receipts() { _blockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(2).TestObject; Block block0 = _blockTree.FindBlock(0); Block block1 = _blockTree.FindBlock(1); TransactionReceipt[][] transactionReceipts = _manager.GetReceipts(new[] { block0.Hash, block1.Hash, TestObject.KeccakA }); Assert.AreEqual(3, transactionReceipts.Length, "data.Length"); Assert.AreEqual(0, transactionReceipts[0].Length, "data[0]"); Assert.AreEqual(0, transactionReceipts[1].Length, "data[1]"); Assert.AreEqual(0, transactionReceipts[2].Length, "data[2]"); }
public void Can_retrieve_empty_receipts() { _blockTree = Build.A.BlockTree(_genesisBlock).OfChainLength(2).TestObject; Block block0 = _blockTree.FindBlock(0, BlockTreeLookupOptions.None); Block block1 = _blockTree.FindBlock(1, BlockTreeLookupOptions.None); TxReceipt[][] txReceipts = _syncServer.GetReceipts(new[] { block0.Hash, block1.Hash, TestItem.KeccakA }); Assert.AreEqual(3, txReceipts.Length, "data.Length"); Assert.AreEqual(0, txReceipts[0].Length, "data[0]"); Assert.AreEqual(0, txReceipts[1].Length, "data[1]"); Assert.AreEqual(0, txReceipts[2].Length, "data[2]"); }
public bool Validate(BlockHeader header, BlockHeader[] ommers) { if (ommers.Length > 2) { _logger?.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - too many ommers"); return(false); } if (ommers.Length == 2 && ommers[0].Hash == ommers[1].Hash) { _logger?.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - duplicated ommer"); return(false); } for (int i = 0; i < ommers.Length; i++) { BlockHeader ommer = ommers[i]; if (!_headerValidator.Validate(ommer, true)) { _logger?.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - ommer's header invalid"); return(false); } if (!IsKin(header, ommer, 6)) { _logger?.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - ommer just pretending to be ommer"); return(false); } Block ancestor = _blockTree.FindBlock(header.ParentHash, false); for (int ancestorLevel = 0; ancestorLevel < 5; ancestorLevel++) { if (ancestor == null) { break; } if (ancestor.Ommers.Any(o => o.Hash == ommer.Hash)) { _logger?.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - ommers has already been included by an ancestor"); return(false); } ancestor = _blockTree.FindBlock(ancestor.Header.ParentHash, false); } } return(true); }
public bool Validate(BlockHeader header, BlockHeader[] uncles) { if (uncles.Length > 2) { _logger.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - too many uncles"); return(false); } if (uncles.Length == 2 && uncles[0].Hash == uncles[1].Hash) { _logger.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - duplicated uncle"); return(false); } for (int i = 0; i < uncles.Length; i++) { BlockHeader uncle = uncles[i]; if (!_headerValidator.Validate(uncle, true)) { _logger.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - uncle's header invalid"); return(false); } if (!IsKin(header, uncle, 6)) { _logger.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - uncle just pretending to be uncle"); return(false); } Block ancestor = _blockTree.FindBlock(header.ParentHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); for (int ancestorLevel = 0; ancestorLevel < 5; ancestorLevel++) { if (ancestor == null) { break; } if (ancestor.Uncles.Any(o => o.Hash == uncle.Hash)) { _logger.Info($"Invalid block ({header.ToString(BlockHeader.Format.Full)}) - uncles has already been included by an ancestor"); return(false); } ancestor = _blockTree.FindBlock(ancestor.Header.ParentHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); } } return(true); }
public bool TrySetNextBlocks(int maxCount, BlockDownloadContext context) { if (context.Blocks.Length == 0) { return(false); } BlockInfo?beaconMainChainBlockInfo = GetBeaconMainChainBlockInfo(context.Blocks[0].Number); if (beaconMainChainBlockInfo?.IsBeaconHeader == true && beaconMainChainBlockInfo.IsBeaconBody == false) { return(false); } int offset = 0; while (offset != context.NonEmptyBlockHashes.Count) { IReadOnlyList <Keccak> hashesToRequest = context.GetHashesByOffset(offset, maxCount); for (int i = 0; i < hashesToRequest.Count; i++) { Block?block = _blockTree.FindBlock(hashesToRequest[i], BlockTreeLookupOptions.None); if (block == null) { return(false); } BlockBody blockBody = new(block.Transactions, block.Uncles); context.SetBody(i + offset, blockBody); } offset += hashesToRequest.Count; } return(true); }
private void LoadScenario(Scenario scenario, ISyncConfig syncConfig) { _syncConfig = syncConfig; _syncConfig.PivotNumber = _pivotNumber.ToString(); _syncConfig.PivotHash = scenario.Blocks.Last().Hash.ToString(); _feed = new FastReceiptsSyncFeed( _selector, _specProvider, _blockTree, _receiptStorage, _syncPeerPool, _syncConfig, _syncReport, LimboLogs.Instance); _feed.LagBehindBodies = 0; _blockTree.Genesis.Returns(scenario.Blocks[0].Header); _blockTree.FindBlock(Keccak.Zero, BlockTreeLookupOptions.None) .ReturnsForAnyArgs(ci => scenario.BlocksByHash.ContainsKey(ci.Arg <Keccak>()) ? scenario.BlocksByHash[ci.Arg <Keccak>()] : null); _receiptStorage.LowestInsertedReceiptBlock.Returns((long?)null); _blockTree.LowestInsertedBody.Returns(scenario.LowestInsertedBody); }
private void TimerOnElapsed(object sender, ElapsedEventArgs e) { try { if (_blockTree.Head == null) { _timer.Enabled = true; return; } if (_scheduledBlock == null) { if (_blockTree.Head.Timestamp + _config.BlockPeriod < _timestamp.EpochSeconds) { _signalsQueue.Add(_blockTree.FindBlock(_blockTree.Head.Hash, false)); } _timer.Enabled = true; return; } ulong extraDelayMilliseconds = 0; if (_scheduledBlock.Difficulty == Clique.DifficultyNoTurn) { int wiggle = _snapshotManager.GetOrCreateSnapshot(_scheduledBlock.Header.Number - 1, _scheduledBlock.Header.ParentHash).Signers.Count / 2 + 1 * Clique.WiggleTime; extraDelayMilliseconds += (ulong)_cryptoRandom.NextInt(wiggle); } if (_scheduledBlock.Timestamp * 1000 + extraDelayMilliseconds < _timestamp.EpochMilliseconds) { if (_scheduledBlock.Number > _blockTree.Head.Number) { if (_logger.IsInfo) { _logger.Info($"Suggesting own block {_scheduledBlock.ToString(Block.Format.HashNumberDiffAndTx)}"); } _blockTree.SuggestBlock(_scheduledBlock); } else { if (_logger.IsInfo) { _logger.Info($"Dropping a losing block {_scheduledBlock.ToString(Block.Format.HashNumberDiffAndTx)}"); } } _scheduledBlock = null; } _timer.Enabled = true; } catch (Exception exception) { if (_logger.IsError) { _logger.Error("Clique block producer failure", exception); } } }
public (TxReceipt Receipt, UInt256?EffectiveGasPrice) GetReceiptAndEffectiveGasPrice(Keccak txHash) { Keccak blockHash = _receiptFinder.FindBlockHash(txHash); if (blockHash != null) { Block block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); TxReceipt txReceipt = _receiptFinder.Get(block).ForTransaction(txHash); Transaction tx = block?.Transactions[txReceipt.Index]; bool is1559Enabled = _specProvider.GetSpec(block.Number).IsEip1559Enabled; UInt256 effectiveGasPrice = tx.CalculateEffectiveGasPrice(is1559Enabled, block.Header.BaseFeePerGas); return(txReceipt, effectiveGasPrice); } return(null, null); }
public (TxReceipt Receipt, Transaction Transaction) GetTransaction(Keccak transactionHash) { TxReceipt txReceipt = _receiptStorage.Find(transactionHash); if (txReceipt?.BlockHash != null) { Block block = _blockTree.FindBlock(txReceipt.BlockHash, BlockTreeLookupOptions.RequireCanonical); return(txReceipt, block?.Transactions[txReceipt.Index]); } else if (_txPool.TryGetPendingTransaction(transactionHash, out var transaction)) { return(null, transaction); } else { return(null, null); } }
public (TxReceipt Receipt, Transaction Transaction) GetTransaction(Keccak txHash) { Keccak blockHash = _receiptFinder.FindBlockHash(txHash); if (blockHash != null) { Block block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.TotalDifficultyNotNeeded); TxReceipt txReceipt = _receiptFinder.Get(block).ForTransaction(txHash); return(txReceipt, block?.Transactions[txReceipt.Index]); } if (_txPool.TryGetPendingTransaction(txHash, out var transaction)) { return(null, transaction); } return(null, null); }
public GethLikeTxTrace Trace(Keccak blockHash, int txIndex) { Block block = _blockTree.FindBlock(blockHash, false); if (block == null) { throw new InvalidOperationException("Only historical blocks"); } if (txIndex > block.Transactions.Length - 1) { throw new InvalidOperationException($"Block {blockHash} has only {block.Transactions.Length} transactions and the requested tx index was {txIndex}"); } return(Trace(block, block.Transactions[txIndex].Hash)); }
public void get_transaction_returns_receipt_and_transaction_when_found() { int index = 5; var receipt = Build.A.Receipt .WithBlockHash(TestItem.KeccakB) .WithTransactionHash(TestItem.KeccakA) .WithIndex(index) .TestObject; IEnumerable <Transaction> transactions = Enumerable.Range(0, 10) .Select(i => Build.A.Transaction.WithNonce((UInt256)i).TestObject); var block = Build.A.Block .WithTransactions(transactions.ToArray()) .TestObject; _blockTree.FindBlock(TestItem.KeccakB, Arg.Any <BlockTreeLookupOptions>()).Returns(block); _receiptStorage.FindBlockHash(TestItem.KeccakA).Returns(TestItem.KeccakB); _receiptStorage.Get(block).Returns(new[] { receipt }); _blockchainBridge.GetTransaction(TestItem.KeccakA).Should() .BeEquivalentTo((receipt, Build.A.Transaction.WithNonce((UInt256)index).TestObject)); }
public void Can_get_transaction(bool withHeader) { Keccak txHash = _blockTree.FindBlock(1).Transactions[0].Hash; TransactionWithProof txWithProof = _proofModule.proof_getTransactionByHash(txHash, withHeader).Data; Assert.NotNull(txWithProof.Transaction); Assert.AreEqual(2, txWithProof.TxProof.Length); if (withHeader) { Assert.NotNull(txWithProof.BlockHeader); } else { Assert.Null(txWithProof.BlockHeader); } string response = RpcTest.TestSerializedRequest(_proofModule, "proof_getTransactionByHash", $"{txHash}", $"{withHeader}"); Assert.True(response.Contains("\"result\"")); }
private void PrepareReceiptsResponse(ReceiptsSyncBatch receiptSyncBatch, LatencySyncPeerMock syncPeer, IBlockTree tree) { receiptSyncBatch.Response = new TxReceipt[receiptSyncBatch.Request.Length][]; for (int i = 0; i < receiptSyncBatch.Request.Length; i++) { Block block = tree.FindBlock(receiptSyncBatch.Request[i], false); receiptSyncBatch.Response[i] = new TxReceipt[block.Transactions.Length]; for (int j = 0; j < block.Transactions.Length; j++) { receiptSyncBatch.Response[i][j] = _remoteReceiptStorage.Find(block.Transactions[j].Hash); } } }
public OmmersValidatorTests() { _blockTree = Build.A.BlockTree().OfChainLength(1).TestObject; _grandgrandparent = _blockTree.FindBlock(0); _grandparent = Build.A.Block.WithParent(_grandgrandparent).TestObject; _duplicateOmmer = Build.A.Block.WithParent(_grandgrandparent).TestObject; _parent = Build.A.Block.WithParent(_grandparent).WithOmmers(_duplicateOmmer).TestObject; _block = Build.A.Block.WithParent(_parent).TestObject; _blockTree.SuggestBlock(_grandparent); _blockTree.SuggestBlock(_parent); _blockTree.SuggestBlock(_block); }
public void get_transaction_returns_receipt_and_transaction_when_found() { int index = 5; var receipt = Build.A.Receipt.WithBlockHash(TestItem.KeccakB).WithIndex(index).TestObject; _blockTree.FindBlock(TestItem.KeccakB, BlockTreeLookupOptions.RequireCanonical).Returns( Build.A.Block.WithTransactions( Enumerable.Range(0, 10).Select(i => Build.A.Transaction.WithNonce((UInt256)i).TestObject).ToArray() ).TestObject); _receiptStorage.Find(TestItem.KeccakA).Returns(receipt); _blockchainBridge.GetTransaction(TestItem.KeccakA).Should() .BeEquivalentTo((receipt, (Transaction)Build.A.Transaction.WithNonce((UInt256)index).TestObject)); }
public (TxReceipt Receipt, Transaction Transaction) GetTransaction(Keccak transactionHash) { TxReceipt txReceipt = _receiptStorage.Find(transactionHash); if (txReceipt?.BlockHash == null) { return(null, null); } Block block = _blockTree.FindBlock(txReceipt.BlockHash, BlockTreeLookupOptions.RequireCanonical); return(txReceipt, block?.Transactions[txReceipt.Index]); }
public OmmersValidatorTests() { _blockTree = Build.A.BlockTree().OfChainLength(1).TestObject; _grandgrandparent = _blockTree.FindBlock(0, BlockTreeLookupOptions.None); _grandparent = Build.A.Block.WithParent(_grandgrandparent).TestObject; _duplicateOmmer = Build.A.Block.WithParent(_grandgrandparent).TestObject; _parent = Build.A.Block.WithParent(_grandparent).WithOmmers(_duplicateOmmer).TestObject; _block = Build.A.Block.WithParent(_parent).TestObject; _blockTree.SuggestHeader(_grandparent.Header); _blockTree.SuggestHeader(_parent.Header); _blockTree.SuggestHeader(_block.Header); }
private Block?GetBlock(Keccak headBlockHash) { Block?block = _blockTree.FindBlock(headBlockHash, BlockTreeLookupOptions.DoNotCalculateTotalDifficulty); if (block is null) { if (_logger.IsInfo) { _logger.Info($"Syncing... Block {headBlockHash} not found."); } } return(block); }
public ResultWrapper <Result> Handle(Keccak blockHash) { Block?newHeadBlock = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.None); if (newHeadBlock == null) { if (_logger.IsWarn) { _logger.Warn($"Block {blockHash} cannot be found and it will not be set as head."); } return(ResultWrapper <Result> .Success(Result.Fail)); } if (!TryGetBranch(newHeadBlock, out Block[] blocks))
private void PrepareBodiesResponse(BodiesSyncBatch bodiesSyncBatch, LatencySyncPeerMock syncPeer, IBlockTree tree) { int requestSize = bodiesSyncBatch.Request.Length; int responseSize = bodiesSyncBatch.Request.Length; if (_incorrectByTooLongMessages.Contains(syncPeer)) { responseSize *= 2; TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND TOO LONG MESSAGE ({responseSize} INSTEAD OF {requestSize})"); } else if (_incorrectByTooShortMessages.Contains(syncPeer)) { responseSize = Math.Max(1, responseSize / 2); TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND TOO SHORT MESSAGE ({responseSize} INSTEAD OF {requestSize})"); } bodiesSyncBatch.Response = new BlockBody[responseSize]; int maxResponseSize = _peerMaxResponseSizes.ContainsKey(syncPeer) ? Math.Min(responseSize, _peerMaxResponseSizes[syncPeer]) : responseSize; for (int i = 0; i < Math.Min(maxResponseSize, requestSize); i++) { Block block = tree.FindBlock(bodiesSyncBatch.Request[i], BlockTreeLookupOptions.None); bodiesSyncBatch.Response[i] = new BlockBody(block.Transactions, block.Ommers); } if (_maliciousByShortAtStart.Contains(syncPeer)) { bodiesSyncBatch.Response[0] = null; TestContext.WriteLine($"{_time,6} | SYNC PEER {syncPeer.Node:s} WILL SEND A MALICIOUS (SHORT AT START) MESSAGE"); } if (_maliciousByInvalidTxs.Contains(syncPeer)) { for (int i = 0; i < bodiesSyncBatch.Response.Length; i++) { BlockBody valid = bodiesSyncBatch.Response[i]; bodiesSyncBatch.Response[i] = new BlockBody(new[] { Build.A.Transaction.WithData(Bytes.FromHexString("bad")).TestObject }, valid.Ommers); } } if (_maliciousByInvalidOmmers.Contains(syncPeer)) { for (int i = 0; i < bodiesSyncBatch.Response.Length; i++) { BlockBody valid = bodiesSyncBatch.Response[i]; bodiesSyncBatch.Response[i] = new BlockBody(valid.Transactions, new[] { Build.A.BlockHeader.WithAuthor(new Address(Keccak.Compute("bad_ommer").Bytes.Take(20).ToArray())).TestObject }); } } }
private PendingValidators TryGetInitChangeFromPastBlocks(Keccak blockHash) { PendingValidators pendingValidators = null; var lastFinalized = _blockFinalizationManager.GetLastLevelFinalizedBy(blockHash); var toBlock = Math.Max(lastFinalized, InitBlockNumber); var block = _blockTree.FindBlock(blockHash, BlockTreeLookupOptions.None); while (block?.Number >= toBlock) { var receipts = _receiptFinder.Get(block) ?? Array.Empty <TxReceipt>(); if (ValidatorContract.CheckInitiateChangeEvent(block.Header, receipts, out var potentialValidators)) { if (Validators.SequenceEqual(potentialValidators)) { break; } pendingValidators = new PendingValidators(block.Number, block.Hash, potentialValidators); } block = _blockTree.FindBlock(block.ParentHash, BlockTreeLookupOptions.None); } return(pendingValidators); }
public Task <ResultWrapper <ExecutionPayloadBodyV1Result[]> > HandleAsync(Keccak[] blockHashes) { List <ExecutionPayloadBodyV1Result> payloadBodies = new(); foreach (Keccak hash in blockHashes) { Block?block = _blockTree.FindBlock(hash); if (block is not null) { payloadBodies.Add(new ExecutionPayloadBodyV1Result(block.Transactions)); } } return(Task.FromResult(ResultWrapper <ExecutionPayloadBodyV1Result[]> .Success(payloadBodies.ToArray()))); }
private void LoadScenario(Scenario scenario, ISyncConfig syncConfig) { _syncConfig = syncConfig; _syncConfig.PivotNumber = _pivotNumber.ToString(); _syncConfig.PivotHash = scenario.Blocks.Last().Hash.ToString(); _feed = new ReceiptsSyncFeed( _selector, _specProvider, _blockTree, _receiptStorage, _syncPeerPool, _syncConfig, _syncReport, LimboLogs.Instance); _blockTree.Genesis.Returns(scenario.Blocks[0].Header); _blockTree.FindCanonicalBlockInfo(Arg.Any <long>()).Returns( ci => { Block block = scenario.Blocks[ci.Arg <long>()]; if (block == null) { return(null); } BlockInfo blockInfo = new BlockInfo(block.Hash, block.TotalDifficulty ?? 0); blockInfo.BlockNumber = ci.Arg <long>(); return(blockInfo); }); _blockTree.FindBlock(Keccak.Zero, BlockTreeLookupOptions.None) .ReturnsForAnyArgs(ci => scenario.BlocksByHash.ContainsKey(ci.Arg <Keccak>()) ? scenario.BlocksByHash[ci.Arg <Keccak>()] : null); _blockTree.FindHeader(Keccak.Zero, BlockTreeLookupOptions.None) .ReturnsForAnyArgs(ci => scenario.BlocksByHash.ContainsKey(ci.Arg <Keccak>()) ? scenario.BlocksByHash[ci.Arg <Keccak>()].Header : null); _receiptStorage.LowestInsertedReceiptBlockNumber.Returns((long?)null); _blockTree.LowestInsertedBodyNumber.Returns(scenario.LowestInsertedBody.Number); }
private bool ResolveBlockRef(BlockRef blockRef) { if (blockRef.IsInDb) { Block block = _blockTree.FindBlock(blockRef.BlockHash, BlockTreeLookupOptions.None); if (block == null) { return(false); } blockRef.Block = block; blockRef.BlockHash = null; blockRef.IsInDb = false; } return(true); }
public bool Resolve(IBlockTree blockTree) { if (IsInDb) { Block block = blockTree.FindBlock(BlockHash, BlockTreeLookupOptions.None); if (block == null) { return(false); } Block = block; BlockHash = null; IsInDb = false; } return(true); }