feat(cold): add get_receipt_with_context composite query#19
Conversation
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>
|
[Claude Code] Integrating
|
| 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).
Summary
ReceiptContextstruct bundling header, transaction, receipt, confirmation metadata, and prior cumulative gasget_receipt_with_contextto theColdStoragetrait for single-roundtrip RPC receipt buildingMemColdBackendandMdbxColdBackendBlockTagenum andHeaderSpecifier::Tagvariant — dead code since the only "latest block" consumer usesget_latest_block(), andFinalized/Safewere never writtenMetadataKeyto onlyLatestBlock, removingFinalizedBlock,SafeBlock, andEarliestBlockTest plan
cargo clippy -p signet-cold --all-features --all-targetscargo clippy -p signet-cold --no-default-features --all-targetscargo clippy -p signet-cold-mdbx --all-features --all-targetscargo clippy -p signet-cold-mdbx --no-default-features --all-targetscargo +nightly fmtcargo t -p signet-cold— conformance passes for MemColdBackendcargo t -p signet-cold-mdbx --all-features— conformance passes for MdbxColdBackendcargo t -p signet-storage— UnifiedStorage still compiles and passes🤖 Generated with Claude Code