feat(rpc): support native multisig simulation - #7239
Conversation
5c5872d to
4b070c1
Compare
✅ Changelog found on PR. |
5a15408 to
13c1bc9
Compare
13c1bc9 to
f023ebe
Compare
📊 Tempo Precompiles CoverageprecompilesCoverage: 6450/10891 lines (59.22%) File details
contractsCoverage: 1/223 lines (0.45%) File details
Total: 6451/11114 lines (58.04%) |
|
cyclops audit fast note="this belongs to the GH stack #7243 and the TIP 1061 is specified in the PR 7242. any bug not introduced by this PR should be clearly marked" |
tempoxyz-bot
left a comment
There was a problem hiding this comment.
👁️ Cyclops Review
This change adds state-derived recursive mock approvals so RPC simulation can estimate native-multisig transactions conservatively. One verified low-severity correctness issue remains: the duplicated quorum cost model omits a real intrinsic-gas charge and can under-estimate valid nested-multisig transactions.
Reviewer Callouts
- ⚡ Simulation context boundary:
ExecutionContext::Simulationskips native-multisig authorization, and empty transaction encoding can mark a transaction as RPC simulation. This behavior predates the PR, but a human should confirm no consensus or payload-building path can construct aTempoTxEnvwith empty encoding or its default simulation context. - ⚡ WebAuthn hint ranking: Explicit WebAuthn hints are ranked at maximum WebAuthn gas while mock construction uses the supplied key-data size. The node currently emits only
UnknownPrimitiveorMultisig, but in-process or SDK hint producers could violate the conservative-ranking invariant. - ⚡ Signed-request round trip:
From<AASigned> for TempoTransactionRequestemitsmultisig_signature_countwhile leavingfromunset. Confirm no server or SDK path feeds that request back into simulation, where it now fails withmultisig account cannot be zero.
f023ebe to
e575087
Compare
e575087 to
35fbe63
Compare
|
cyclops audit fast note="this belongs to the GH stack #7243 and the TIP 1061 is specified in the PR 7242. any bug not introduced by this PR should be clearly marked" |
tempoxyz-bot
left a comment
There was a problem hiding this comment.
👁️ Cyclops Review
This change adds native-multisig gas modeling to Tempo RPC simulations. The state-aware call path is careful and conservative, but simulateV1 bypasses it and can understate intrinsic gas; hint derivation also adds bounded attacker-shaped work before EVM gas accounting.
Reviewer Callouts
- ⚡ Contract-creation calls from registered multisigs: Populating a hint makes
has_aa_fields()true, while AA conversion requires a non-empty calls list. Verify thateth_callwith notostill simulates CREATE rather than failing withempty calls list. - ⚡ Conservative owner key assumptions: The state-derived path prices unknown owners as maximum-size WebAuthn. Confirm that this intentional overestimate does not make otherwise valid simulations fail the caller balance check.
35fbe63 to
04d8e75
Compare
b37ee58 to
c511a17
Compare
|
cyclops audit fast note="this belongs to the GH stack #7243 and the TIP 1061 is specified in the PR 7242. any bug not introduced by this PR should be clearly marked" |
c511a17 to
6f64329
Compare
tempoxyz-bot
left a comment
There was a problem hiding this comment.
👁️ Cyclops Review
Rechecked against current head 6f643292333cac24a649cc8c8d019e0e4067a466 after head drift. Three actionable findings remain.
Reviewer Callouts
- ⚡ Conservative primitive-owner pricing: State-derived hints still emit
UnknownPrimitivefor every non-multisig owner, pricing each as maximal WebAuthn. A common registered 1-of-1 secp256k1 estimate is inflated by about 35,720 gas; consider a way to provide exact per-owner key hints. - ⚡ Hint-builder work bound: A state override can create the maximum nested owner graph without on-chain setup cost, causing thousands of storage reads and millions of bounded DP iterations for one RPC call. Benchmark and rate-limit this path.
- ⚡ Storage-reader invariant parity: The RPC reader uses
InitMultisig::validate()while the precompile usesvalidate_for_account(account). Keep these readers aligned so future state sources cannot make self-owned configurations acceptable only to simulation.
| mut request: TempoTransactionRequest, | ||
| mut db: impl Database<Error: Into<EthApiError>>, | ||
| ) -> Result<TxEnvFor<Self::Evm>, Self::Error> { | ||
| populate_native_multisig_simulation_hints(&mut request, &mut db) |
There was a problem hiding this comment.
🚨 [SECURITY] Block simulation bypasses state-aware multisig hint construction
This preprocessing runs only through Call::create_txn_env; eth_simulateV1 and tempo_simulateV1 resolve raw requests through TryIntoSimTx. A normal registered-multisig request therefore stays non-AA and omits the TIP-1061 surcharge, while a request with multisigSignatureCount fabricates primitive approvals without loading the stored threshold or nested owner tree. Under T11 simulation this can report success and gas for an authorization shape that cannot execute on chain.
Recommended Fix:
Run the same state-aware preprocessing for each transaction at its simulated block position before build_simulate_v1_transaction, or reject count-only registered-multisig simulation when state-aware preprocessing is unavailable.
6f64329 to
e8a27db
Compare
460ab98 to
5fbfbd5
Compare
5fbfbd5 to
5f8607a
Compare
5f8607a to
5dcc3d5
Compare
2461771 to
5d9872d
Compare
5d9872d to
cf6e07c
Compare
cf6e07c to
a0c9d35
Compare
Adds recursive request witnesses for state-aware multisig calls, gas estimation, and transaction filling. Witnesses are checked against pending state before conservative mock approvals are constructed; block-sequence witness simulation fails closed until it has position-aware preprocessing.
Stacked on #7238; reference implementation: #4069.