Skip to content

feat(cold): add get_receipt_with_context composite query#19

Merged
prestwich merged 4 commits intomainfrom
feat/receipt-with-context
Feb 12, 2026
Merged

feat(cold): add get_receipt_with_context composite query#19
prestwich merged 4 commits intomainfrom
feat/receipt-with-context

Conversation

@prestwich
Copy link
Member

@prestwich prestwich commented Feb 11, 2026

Summary

  • Adds ReceiptContext struct bundling header, transaction, receipt, confirmation metadata, and prior cumulative gas
  • Adds get_receipt_with_context to the ColdStorage trait for single-roundtrip RPC receipt building
  • Implements for both MemColdBackend and MdbxColdBackend
  • Adds conformance test covering block+index lookup, tx hash lookup, prior gas computation, and missing-block case
  • Removes BlockTag enum and HeaderSpecifier::Tag variant — dead code since the only "latest block" consumer uses get_latest_block(), and Finalized/Safe were never written
  • Trims MetadataKey to only LatestBlock, removing FinalizedBlock, SafeBlock, and EarliestBlock

Test plan

  • cargo clippy -p signet-cold --all-features --all-targets
  • cargo clippy -p signet-cold --no-default-features --all-targets
  • cargo clippy -p signet-cold-mdbx --all-features --all-targets
  • cargo clippy -p signet-cold-mdbx --no-default-features --all-targets
  • cargo +nightly fmt
  • cargo t -p signet-cold — conformance passes for MemColdBackend
  • cargo t -p signet-cold-mdbx --all-features — conformance passes for MdbxColdBackend
  • cargo t -p signet-storage — UnifiedStorage still compiles and passes

🤖 Generated with Claude Code

prestwich and others added 4 commits February 11, 2026 16:45
Add a single-roundtrip method to ColdStorage that returns everything
needed to build an RPC receipt response: the header, transaction,
receipt, confirmation metadata, and prior cumulative gas.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite get_header, get_headers, get_transaction, get_receipt, and
get_receipt_with_context to each open a single read transaction with
inline cursor lookups instead of delegating to helpers that each open
their own transaction. Removes 9 now-unused private helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use Confirmed<Receipt> instead of separate receipt + meta fields,
add default trait impl for get_receipt_with_context, and eliminate
MDBX get_receipt_inner duplication by delegating to the composite method.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BlockTag and HeaderSpecifier::Tag were dead code — the only real
consumer of "latest block" uses the dedicated get_latest_block() method,
and Finalized/Safe were never written. Removing them simplifies the
trait contract and reduces implementation burden for backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@prestwich prestwich merged commit 915c335 into main Feb 12, 2026
6 checks passed
@prestwich
Copy link
Member Author

[Claude Code]

Integrating ReceiptContext

What it provides

ReceiptContext bundles everything an RPC layer needs to build a complete eth_getTransactionReceipt response from a single cold storage call:

Field Type Purpose
header Header Block header (for block_hash, block_number, etc.)
transaction TransactionSigned The originating transaction (for from, to, type, etc.)
receipt Confirmed<Receipt> Receipt wrapped with ConfirmationMeta (block number, block hash, tx index)
prior_cumulative_gas u64 Cumulative gas of all preceding txs — subtract from the receipt's cumulative_gas_used to get per-tx gas_used

Querying

Use either handle type (ColdStorageHandle or ColdStorageReadHandle):

// By transaction hash
let ctx = handle
    .get_receipt_with_context(ReceiptSpecifier::TxHash(tx_hash))
    .await?;

// By block number + tx index
let ctx = handle
    .get_receipt_with_context(ReceiptSpecifier::BlockAndIndex { block: 42, index: 0 })
    .await?;

Both return ColdResult<Option<ReceiptContext>>None when the receipt doesn't exist.

Computing per-transaction gas

let gas_used = ctx.receipt.inner().inner.cumulative_gas_used - ctx.prior_cumulative_gas;

prior_cumulative_gas is 0 for the first transaction in a block, so the subtraction always works.

Accessing confirmation metadata

ConfirmationMeta is carried inside Confirmed<Receipt>:

let meta = ctx.receipt.meta();
let block_number = meta.block_number();
let block_hash  = meta.block_hash();
let tx_index    = meta.transaction_index();

Backend performance

The MDBX backend (signet-cold-mdbx) overrides the default implementation to serve get_receipt_with_context in a single read transaction, avoiding the multiple roundtrips that the default trait implementation requires. The in-memory backend uses the default composed implementation.

Trait implementors

If you're writing a custom ColdStorage backend, get_receipt_with_context has a default implementation that composes get_receipt, get_header, and get_transaction. Override it only if your backend can serve the query more efficiently (e.g., in a single database transaction).

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.

1 participant