@@ -2033,7 +2033,7 @@ where
2033
2033
// NB: 64 / 63 is due to Ethereum's gas-forwarding rules. Each call
2034
2034
// frame can forward only 63/64 of the gas it has when it makes a new
2035
2035
// frame.
2036
- let mut needle = gas_used + gas_refunded + revm:: interpreter:: gas:: CALL_STIPEND * 64 / 63 ;
2036
+ let mut needle = ( gas_used + gas_refunded + revm:: interpreter:: gas:: CALL_STIPEND ) * 64 / 63 ;
2037
2037
2038
2038
// If the first search is outside the range, we don't need to try it.
2039
2039
if search_range. contains ( needle) {
@@ -2346,6 +2346,84 @@ where
2346
2346
}
2347
2347
}
2348
2348
2349
+ #[ cfg( test) ]
2350
+ mod tests {
2351
+ use super :: * ;
2352
+ use crate :: {
2353
+ test_utils:: { test_trevm_with_funds, ALICE , BOB , LOG_DEPLOYED_BYTECODE } ,
2354
+ NoopBlock , NoopCfg , TrevmBuilder ,
2355
+ } ;
2356
+ use alloy:: {
2357
+ consensus:: constants:: ETH_TO_WEI ,
2358
+ network:: { TransactionBuilder , TransactionBuilder7702 } ,
2359
+ rpc:: types:: { Authorization , TransactionRequest } ,
2360
+ signers:: SignerSync ,
2361
+ } ;
2362
+ use revm:: { context:: transaction:: AuthorizationTr , database:: InMemoryDB , primitives:: bytes} ;
2363
+
2364
+ #[ test]
2365
+ fn test_estimate_gas_simple_transfer ( ) {
2366
+ let trevm = test_trevm_with_funds ( & [
2367
+ ( ALICE . address ( ) , U256 :: from ( ETH_TO_WEI ) ) ,
2368
+ ( BOB . address ( ) , U256 :: from ( ETH_TO_WEI ) ) ,
2369
+ ] ) ;
2370
+
2371
+ let tx = TransactionRequest :: default ( )
2372
+ . from ( ALICE . address ( ) )
2373
+ . to ( BOB . address ( ) )
2374
+ . value ( U256 :: from ( ETH_TO_WEI / 2 ) ) ;
2375
+
2376
+ let ( estimation, _trevm) =
2377
+ trevm. fill_cfg ( & NoopCfg ) . fill_block ( & NoopBlock ) . fill_tx ( & tx) . estimate_gas ( ) . unwrap ( ) ;
2378
+
2379
+ assert ! ( estimation. is_success( ) ) ;
2380
+ // The gas used should correspond to a simple transfer.
2381
+ assert_eq ! ( estimation. gas_used( ) , 21000 ) ;
2382
+ }
2383
+
2384
+ #[ test]
2385
+ fn test_7702_authorization_estimation ( ) {
2386
+ // Insert the LogContract code
2387
+ let db = InMemoryDB :: default ( ) ;
2388
+ let log_address = Address :: repeat_byte ( 0x32 ) ;
2389
+
2390
+ // Set up trevm, and test balances.
2391
+ let mut trevm =
2392
+ TrevmBuilder :: new ( ) . with_db ( db) . with_spec_id ( SpecId :: PRAGUE ) . build_trevm ( ) . unwrap ( ) ;
2393
+ let _ = trevm. test_set_balance ( ALICE . address ( ) , U256 :: from ( ETH_TO_WEI ) ) ;
2394
+ let _ = trevm. set_bytecode_unchecked ( log_address, Bytecode :: new_raw ( LOG_DEPLOYED_BYTECODE ) ) ;
2395
+
2396
+ // Bob will sign the authorization.
2397
+ let authorization = Authorization {
2398
+ chain_id : U256 :: ZERO ,
2399
+ address : log_address,
2400
+ // We know Bob's nonce is 0.
2401
+ nonce : 0 ,
2402
+ } ;
2403
+ let signature = BOB . sign_hash_sync ( & authorization. signature_hash ( ) ) . unwrap ( ) ;
2404
+ let signed_authorization = authorization. into_signed ( signature) ;
2405
+ assert_eq ! ( signed_authorization. authority( ) . unwrap( ) , BOB . address( ) ) ;
2406
+
2407
+ let tx = TransactionRequest :: default ( )
2408
+ . from ( ALICE . address ( ) )
2409
+ . to ( BOB . address ( ) )
2410
+ . with_authorization_list ( vec ! [ signed_authorization] )
2411
+ . with_input ( bytes ! ( "0x7b3ab2d0" ) ) ; // emitHello()
2412
+
2413
+ let ( estimation, trevm) =
2414
+ trevm. fill_cfg ( & NoopCfg ) . fill_block ( & NoopBlock ) . fill_tx ( & tx) . estimate_gas ( ) . unwrap ( ) ;
2415
+
2416
+ assert ! ( estimation. is_success( ) ) ;
2417
+
2418
+ let tx = tx. with_gas_limit ( estimation. limit ( ) ) ;
2419
+
2420
+ let output = trevm. clear_tx ( ) . fill_tx ( & tx) . run ( ) . unwrap ( ) . accept ( ) ;
2421
+
2422
+ assert ! ( output. 0 . is_success( ) ) ;
2423
+ assert_eq ! ( output. 0 . logs( ) . len( ) , 1 ) ;
2424
+ }
2425
+ }
2426
+
2349
2427
// Some code above and documentation is adapted from the revm crate, and is
2350
2428
// reproduced here under the terms of the MIT license.
2351
2429
//
0 commit comments