Skip to content

Commit 1dd29e5

Browse files
committed
Refine sponsorship flow and broadcast readiness
1 parent 0fa7693 commit 1dd29e5

1 file changed

Lines changed: 48 additions & 1 deletion

File tree

docs/adr/ADR-0003-typed-transactions-sponsorship.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,53 @@ Operational constraints:
125125
* Intrinsic gas MUST be computed over **all** calls in the batch (calldata, cold access per call, CREATE cost, and any signature-related costs).
126126
* If any call fails, all state changes from previous calls in the batch MUST be reverted.
127127

128+
## Sponsorship Flow (Genesis → Sponsor Signature)
129+
130+
This section describes an end-to-end flow for creating a sponsored `0x76` transaction, from initial intent to sponsor signing and submission. It complements (but does not replace) the rules in “Signatures and Hashing”.
131+
132+
### 0) Pre-conditions / Genesis State
133+
- The executor has a key pair, nonce space, and required permissions for the calls.
134+
- The sponsor has funds and is willing to pay gas for the executor’s intent.
135+
- The protocol does **not** implement an automated fee-paying system; sponsorship is arranged off-chain.
136+
- A sponsorship service **may** be used to provide fee sponsorship, but for now this is the responsibility of the chain.
137+
138+
### 1) Executor Builds the Unsponsored Payload (Intent)
139+
- The executor constructs `EvNodeTransaction` with:
140+
- `fee_payer_signature = None`
141+
- all call data, gas params, and access list
142+
- The executor signs the **executor signature hash**:
143+
- `hash_exec = keccak256(0x76 || rlp(payload_fields... with fee_payer_signature = 0x80))`
144+
- The executor produces `executor_signature` (secp256k1), forming `Signed<EvNodeTransaction>`.
145+
146+
### 2) Sponsor-Ready Envelope (Unsigned by Sponsor)
147+
- The executor shares the payload + executor signature with a sponsor (directly or via a service).
148+
- The payload is unchanged; `fee_payer_signature` remains empty.
149+
- **Broadcast readiness:** at this point the tx is valid but **unsponsored** and can be broadcast as a normal executor-paid transaction.
150+
151+
### 3) Sponsor Computes the Sponsor Hash
152+
- The sponsor computes:
153+
- `hash_sponsor = keccak256(0x78 || rlp(payload_fields... with fee_payer_signature = 0x80))`
154+
- The sponsor uses the same payload as the executor (no mutation other than the domain byte).
155+
156+
### 4) Sponsor Signs and Fills `fee_payer_signature`
157+
- The sponsor signs `hash_sponsor` **off-chain** (e.g., within the app or via an app-side signing service) and obtains `fee_payer_signature`.
158+
- The transaction payload is updated:
159+
- `fee_payer_signature = Some(sponsor_signature)`
160+
- The sponsor can verify that `recover_fee_payer(hash_sponsor, signature)` returns their address.
161+
- **Broadcast readiness:** once `fee_payer_signature` is present, the tx is fully sponsored and can be broadcast.
162+
163+
### 5) Submission and Validation
164+
- The fully formed typed tx is:
165+
- `0x76 || rlp([payload_fields..., v, r, s])` with `fee_payer_signature` included in the payload
166+
- Validation path:
167+
- Executor signature verified on domain `0x76`
168+
- Sponsor signature verified on domain `0x78`
169+
- Sponsor address recovered from signature and used for fee checks / balance
170+
171+
### 6) Execution and Receipt
172+
- Execution occurs with `tx.origin` = executor.
173+
- Gas is charged to the recovered sponsor address.
174+
128175
## Implementation Strategy
129176

130177
We will utilize Reth's `NodeTypes` configuration to wire these primitives without modifying core crates.
@@ -156,7 +203,7 @@ pub enum EvTxEnvelope {
156203

157204
* **Handler:** Extend `ConfigureEvm` or implement a custom `EvmHandler`.
158205
* **Fee Deduction:** Override the standard fee deduction logic.
159-
* If `tx.type == 0x76` and `fee_payer` is present, debit the `fee_payer` account in the REVM database.
206+
* If `tx.type == 0x76` and `fee_payer_signature` is present, debit the **recovered sponsor** account in the REVM database.
160207
* Otherwise, fallback to standard deduction (debit `caller`).
161208
* **Batch Execution:** Execute `calls` sequentially under an outer checkpoint; revert all state if any call fails.
162209
* **Context:** Map `EvNodeTransaction` to `TxEnv`. Ensure `TxEnv.caller` is always the executor.

0 commit comments

Comments
 (0)