Skip to content

fix: include aa_authorization_list in the 0x76/0x78 signing-hash preimages#696

Open
compusophy wants to merge 1 commit into
tempoxyz:mainfrom
compusophy:fix/spec-tempo-transaction-signing-hashes
Open

fix: include aa_authorization_list in the 0x76/0x78 signing-hash preimages#696
compusophy wants to merge 1 commit into
tempoxyz:mainfrom
compusophy:fix/spec-tempo-transaction-signing-hashes

Conversation

@compusophy

Copy link
Copy Markdown

Problem

On protocol/transactions/spec-tempo-transaction, the Signing Domains field lists disagree with the node's actual encoder:

  1. Fee Payer Signature Hash (keccak256(0x78 || rlp([...]))) jumps from sender_address straight to key_authorization, omitting aa_authorization_list (and is missing the comma after sender_address).
  2. Both Sender Signature Hash blocks (keccak256(0x76 || rlp([...]))) end at the field-12 fee-payer placeholder, omitting aa_authorization_list and the optional key_authorization (true positions 13 and 14).

The RLP Encoding section further down the same page already lists the envelope correctly (... fee_payer_signature, aa_authorization_list, key_authorization?, sender_signature) — only the signing-hash blocks are stale. An implementor who follows them verbatim produces signatures the chain rejects whenever they trust the spec over the reference client.

Ground truth

Node sourcetempoxyz/tempo crates/primitives/src/transaction/tempo_transaction.rs: both signature_hash() (via encode_for_signing) and fee_payer_signature_hash() route through the shared rlp_encode_fields helper, which unconditionally encodes the authorization list and the optional key authorization after the fee-payer-signature slot:

encode_signature(&self.fee_payer_signature, out);

// Encode authorization_list
self.tempo_authorization_list.encode(out);

// Encode key_authorization (truly optional - only encoded if present)
if let Some(key_auth) = &self.key_authorization {
    key_auth.encode(out);
}

For the fee-payer domain, fee_payer_signature_hash(sender) passes a closure that encodes sender in that slot — the trailing fields are identical.

wevm/oxsrc/tempo/TxEnvelopeTempo.ts uses one field list for both domains; deserialize destructures ..., feePayerSignatureOrSender, authorizationList, keyAuthorizationOrSignature, ... in exactly this order.

Live verification — the localharness Rust implementation (an independent 0x76 encoder, not derived from alloy or ox) only produced signatures accepted by both Moderato and Tempo mainnet once aa_authorization_list was included in both preimages; following this page as written yields invalid-signature rejections.

Fix

Minimal edit to the three signing-hash code blocks: append aa_authorization_list and key_authorization? (comment style copied from the page's own RLP Encoding block), and add the missing comma after sender_address. Nothing else touched.

A mirror PR against the canonical TIP (tempoxyz/tempo tips/tip-0001.md, which this page tracks) is being filed simultaneously. Precedent for clarifying this section: #111.

🤖 Generated with Claude Code

…mages

The sender-hash and fee-payer-hash field lists in spec-tempo-transaction.mdx
omitted aa_authorization_list (and, for the sender hashes, the optional
key_authorization), disagreeing with the node's shared rlp_encode_fields
encoder and with the RLP Encoding section further down the same page.
Also fixes the missing comma after sender_address in the fee-payer block.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 15, 2026

Copy link
Copy Markdown

@compusophy is attempting to deploy a commit to the Tempo Team on Vercel.

A member of the Team first needs to authorize it.

@compusophy

Copy link
Copy Markdown
Author

Companion PR for the canonical TIP: tempoxyz/tempo#6842

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