@@ -76,7 +76,7 @@ use tempo_primitives::{
7676 TEMPO_GAS_PRICE_SCALING_FACTOR , TempoHeader , TempoPrimitives , TempoReceipt , TempoTxEnvelope ,
7777 subblock:: PartialValidatorKey ,
7878} ;
79- use tempo_revm:: TempoTxEnv ;
79+ use tempo_revm:: { NATIVE_MULTISIG_NESTED_ACCOUNT_GAS , TempoTxEnv } ;
8080use tokio:: sync:: { Mutex , broadcast} ;
8181
8282/// Placeholder constant for `eth_getBalance` calls because the native token balance is N/A on
@@ -450,7 +450,9 @@ fn load_native_multisig_simulation_hint(
450450 NativeMultisig :: account_threshold_storage_slot ( account) ;
451451 let ( owner_count_slot, owner_count_offset) =
452452 NativeMultisig :: account_owners_len_storage_slot ( account) ;
453+ let ( version_slot, version_offset) = NativeMultisig :: account_version_storage_slot ( account) ;
453454 debug_assert_eq ! ( threshold_slot, owner_count_slot) ;
455+ debug_assert_eq ! ( threshold_slot, version_slot) ;
454456 let header = db
455457 . storage ( NATIVE_MULTISIG_ADDRESS , threshold_slot)
456458 . map_err ( Into :: into) ?;
@@ -459,10 +461,12 @@ fn load_native_multisig_simulation_hint(
459461 . map_err ( |err| EthApiError :: InvalidParams ( err. to_string ( ) ) ) ?;
460462 let owner_count = extract_from_word :: < u8 > ( header, owner_count_offset. unwrap_or_default ( ) , 1 )
461463 . map_err ( |err| EthApiError :: InvalidParams ( err. to_string ( ) ) ) ? as usize ;
462- if threshold == 0 && owner_count == 0 {
464+ let version = extract_from_word :: < u64 > ( header, version_offset. unwrap_or_default ( ) , 8 )
465+ . map_err ( |err| EthApiError :: InvalidParams ( err. to_string ( ) ) ) ?;
466+ if threshold == 0 && owner_count == 0 && version == 0 {
463467 return Ok ( None ) ;
464468 }
465- if threshold == 0 || owner_count == 0 || owner_count > MAX_MULTISIG_OWNERS {
469+ if threshold == 0 || owner_count == 0 || version == 0 || owner_count > MAX_MULTISIG_OWNERS {
466470 return Err ( EthApiError :: InvalidParams (
467471 "native multisig config has an invalid header" . to_string ( ) ,
468472 ) ) ;
@@ -609,7 +613,8 @@ fn native_multisig_simulation_approval_gas(approval: &MultisigSimulationApproval
609613 SignatureType :: WebAuthn => MAX_WEBAUTHN_GAS ,
610614 } ,
611615 MultisigSimulationApproval :: UnknownPrimitive => MAX_WEBAUTHN_GAS ,
612- MultisigSimulationApproval :: Multisig ( hint) => NODE_HEADER_GAS
616+ MultisigSimulationApproval :: Multisig ( hint) => NATIVE_MULTISIG_NESTED_ACCOUNT_GAS
617+ . saturating_add ( NODE_HEADER_GAS )
613618 . saturating_add ( CONFIG_OWNER_GAS . saturating_mul ( hint. owner_count as u64 ) )
614619 . saturating_add (
615620 hint. approvals
@@ -981,6 +986,10 @@ mod tests {
981986 NativeMultisig :: account_owners_len_storage_slot ( account) ,
982987 owners. len ( ) as u8 ,
983988 ) ;
989+ let ( version_slot, version_offset) =
990+ NativeMultisig :: account_version_storage_slot ( account) ;
991+ * self . 0 . entry ( version_slot) . or_default ( ) |=
992+ U256 :: from ( 1 ) << ( version_offset. unwrap_or_default ( ) * 8 ) ;
984993 for ( index, & ( owner, weight) ) in owners. iter ( ) . enumerate ( ) {
985994 self . insert_address (
986995 NativeMultisig :: config_owner_address_storage_slot ( account, index) ,
@@ -1254,6 +1263,36 @@ mod tests {
12541263 assert_eq ! ( nested. approvals. len( ) , 8 ) ;
12551264 }
12561265
1266+ #[ test]
1267+ fn nested_simulation_approval_includes_account_access_gas ( ) {
1268+ let approval = MultisigSimulationApproval :: Multisig ( Box :: new ( MultisigSimulationHint {
1269+ account : Address :: from ( [ 0x22 ; 20 ] ) ,
1270+ owner_count : 1 ,
1271+ approvals : vec ! [ MultisigSimulationApproval :: Primitive {
1272+ key_type: SignatureType :: Secp256k1 ,
1273+ key_data: None ,
1274+ } ] ,
1275+ } ) ) ;
1276+
1277+ assert_eq ! (
1278+ native_multisig_simulation_approval_gas( & approval) ,
1279+ 2_100 + NATIVE_MULTISIG_NESTED_ACCOUNT_GAS + 2_100 + 4_200 + 2_100 + 3_000
1280+ ) ;
1281+ }
1282+
1283+ #[ test]
1284+ fn simulation_hints_reject_zero_config_version ( ) {
1285+ let account = Address :: from ( [ 0xaa ; 20 ] ) ;
1286+ let mut db = SlotDb :: default ( ) ;
1287+ db. insert_u8 ( NativeMultisig :: account_threshold_storage_slot ( account) , 1 ) ;
1288+ db. insert_u8 ( NativeMultisig :: account_owners_len_storage_slot ( account) , 1 ) ;
1289+
1290+ assert ! ( matches!(
1291+ load_native_multisig_simulation_hints( account, None , & mut db) ,
1292+ Err ( EthApiError :: InvalidParams ( reason) ) if reason. contains( "invalid header" )
1293+ ) ) ;
1294+ }
1295+
12571296 #[ test]
12581297 fn simulation_hints_reject_nonzero_reserved_storage_bits ( ) {
12591298 let account = Address :: from ( [ 0xaa ; 20 ] ) ;
0 commit comments