Skip to content

Commit

Permalink
chain/ethereum: cross check txn hashes when using block receipts
Browse files Browse the repository at this point in the history
  • Loading branch information
incrypto32 committed Apr 17, 2024
1 parent 4fece3a commit 51ba9f7
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
20 changes: 16 additions & 4 deletions chain/ethereum/src/ethereum_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2156,7 +2156,7 @@ async fn fetch_receipts_with_retry(
supports_block_receipts: bool,
) -> Result<Vec<Arc<TransactionReceipt>>, IngestorError> {
if supports_block_receipts {
return fetch_block_receipts_with_retry(web3, block_hash, logger).await;
return fetch_block_receipts_with_retry(web3, hashes, block_hash, logger).await;
}
fetch_individual_receipts_with_retry(web3, hashes, block_hash, logger).await
}
Expand Down Expand Up @@ -2195,6 +2195,7 @@ async fn fetch_individual_receipts_with_retry(
/// Fetches transaction receipts of all transactions in a block with `eth_getBlockReceipts` call.
async fn fetch_block_receipts_with_retry(
web3: Arc<Web3<Transport>>,
hashes: Vec<H256>,
block_hash: H256,
logger: Logger,
) -> Result<Vec<Arc<TransactionReceipt>>, IngestorError> {
Expand All @@ -2212,9 +2213,20 @@ async fn fetch_block_receipts_with_retry(
// Check if receipts are available, and transform them if they are
match receipts_option {
Some(receipts) => {
// If receipts are found, transform them into Arc and return Ok
let transformed_receipts = receipts.into_iter().map(Arc::new).collect();
Ok(transformed_receipts)
// Create a HashSet from the transaction hashes of the receipts
let receipt_hashes_set: HashSet<_> =
receipts.iter().map(|r| r.transaction_hash).collect();

// Check if the set contains all the hashes and has the same length as the hashes vec
if hashes.len() == receipt_hashes_set.len()
&& hashes.iter().all(|hash| receipt_hashes_set.contains(hash))
{
let transformed_receipts = receipts.into_iter().map(Arc::new).collect();
Ok(transformed_receipts)
} else {
// If there's a mismatch in numbers or a missing hash, return an error
Err(IngestorError::BlockReceiptsMismatched(block_hash))
}
}
None => {
// If no receipts are found, return an error
Expand Down
4 changes: 4 additions & 0 deletions graph/src/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,10 @@ pub enum IngestorError {
#[error("Transaction receipts for block (block hash = {0:?}) is unavailable")]
BlockReceiptsUnavailable(H256),

/// The Ethereum node does not know about this block for some reason
#[error("Received confliciting block receipts for block (block hash = {0:?})")]
BlockReceiptsMismatched(H256),

/// An unexpected error occurred.
#[error("Ingestor error: {0:#}")]
Unknown(#[from] Error),
Expand Down

0 comments on commit 51ba9f7

Please sign in to comment.