Skip to content

Fix block cache deserialization for old ethereum blocks#6330

Open
incrypto32 wants to merge 3 commits intomasterfrom
krishna/unified-json-patching
Open

Fix block cache deserialization for old ethereum blocks#6330
incrypto32 wants to merge 3 commits intomasterfrom
krishna/unified-json-patching

Conversation

@incrypto32
Copy link
Member

No description provided.

Add a dedicated module for JSON patching utilities that handle missing
`type` fields in Ethereum transactions and receipts. This consolidates
patching logic that will be used by both the HTTP transport layer (for
RPC responses) and cache deserialization (for stored blocks).

The module provides:
- patch_type_field: Adds "type": "0x0" to JSON objects missing the field
- patch_block_transactions: Patches all transactions in a block
- patch_receipts: Patches single receipts or arrays of receipts
Refactor the HTTP transport's receipt patching to use the shared
json_patch module instead of duplicating the patching logic.

This removes the patch_receipt and patch_result methods from
PatchingHttp and replaces them with calls to json_patch::patch_receipts.
The patch_rpc_response and patch_response methods remain as they handle
RPC-specific JSON-RPC response structure.
Add patching for cached blocks before deserialization to handle blocks
that were cached before March 2022 when graph-node's rust-web3 fork
didn't capture the transaction type field.

This patches transactions and receipts in cached blocks at two locations:
- ancestor_block(): For full block deserialization (EthereumBlock),
  patches both transactions and transaction_receipts
- parent_ptr(): For light block deserialization (LightEthereumBlock),
  patches only transactions (light blocks don't include receipts)

The patching adds type: 0x0 (legacy) to transactions/receipts missing
the field, allowing alloy to deserialize blocks that would otherwise
fail due to the missing required field.
@incrypto32 incrypto32 force-pushed the krishna/unified-json-patching branch from 5eaa074 to c52a748 Compare February 5, 2026 14:08
@dwerner dwerner requested review from dwerner and lutter February 5, 2026 16:34
Copy link
Collaborator

@lutter lutter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but I would tighten up the code by introducing a new JsonBlock type that helps with determining what the block is and conversion into one of our blocks.

if json.get("block").is_none() {
warn!(
// Shallow blocks have "data": null - no block data to deserialize
if json.get("data") == Some(&json::Value::Null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this check is repeated a few times and a little noisy, I wonder if it wouldn't be better to introduce a newtype JsonBlock(json::Value) so that you could have methods like is_shallow(&self) and patch_transactions on that

let mut json = json;
if let Some(block) = json.get_mut("block") {
json_patch::patch_block_transactions(block);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put the entire if statement into a json_block.path_block_transactions() method

}
if let Some(receipts) = json.get_mut("transaction_receipts") {
json_patch::patch_receipts(receipts);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for this if statement

if let Some(receipts) = json.get_mut("transaction_receipts") {
json_patch::patch_receipts(receipts);
}
match json::from_value::<EthereumBlock>(json) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or since patching happens here and on line 1205, just have a JsonBlock::patched_block<T>(self) -> Result<T, SomeError> that does the patching and conversion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants