Skip to content

Commit 58278e7

Browse files
committed
chore(evm): add 7702 estimation test
1 parent 129b64f commit 58278e7

File tree

2 files changed

+101
-1
lines changed

2 files changed

+101
-1
lines changed

src/evm.rs

Lines changed: 98 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2033,7 +2033,7 @@ where
20332033
// NB: 64 / 63 is due to Ethereum's gas-forwarding rules. Each call
20342034
// frame can forward only 63/64 of the gas it has when it makes a new
20352035
// 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;
20372037

20382038
// If the first search is outside the range, we don't need to try it.
20392039
if search_range.contains(needle) {
@@ -2346,6 +2346,103 @@ where
23462346
}
23472347
}
23482348

2349+
#[cfg(test)]
2350+
mod tests {
2351+
use std::sync::LazyLock;
2352+
2353+
use alloy::network::{TransactionBuilder, TransactionBuilder7702};
2354+
use alloy::rpc::types::Authorization;
2355+
use alloy::signers::k256::ecdsa::SigningKey;
2356+
use alloy::signers::local::PrivateKeySigner;
2357+
use alloy::signers::SignerSync;
2358+
use alloy::{consensus::constants::ETH_TO_WEI, rpc::types::TransactionRequest};
2359+
2360+
use revm::database::InMemoryDB;
2361+
use revm::inspector::NoOpInspector;
2362+
use revm::primitives::bytes;
2363+
2364+
use crate::test_utils::{test_trevm_with_funds, LOG_BYTECODE};
2365+
use crate::{EvmNeedsCfg, TrevmBuilder};
2366+
use crate::{NoopBlock, NoopCfg};
2367+
2368+
use super::*;
2369+
2370+
static ALICE: LazyLock<PrivateKeySigner> =
2371+
LazyLock::new(|| PrivateKeySigner::from(SigningKey::from_slice(&[0x11; 32]).unwrap()));
2372+
static BOB: LazyLock<PrivateKeySigner> =
2373+
LazyLock::new(|| PrivateKeySigner::from(SigningKey::from_slice(&[0x22; 32]).unwrap()));
2374+
2375+
fn trevm_with_funds() -> EvmNeedsCfg<InMemoryDB, NoOpInspector> {
2376+
test_trevm_with_funds(&[
2377+
(ALICE.address(), U256::from(ETH_TO_WEI)),
2378+
(BOB.address(), U256::from(ETH_TO_WEI)),
2379+
])
2380+
}
2381+
2382+
#[test]
2383+
fn test_estimate_gas_simple_transfer() {
2384+
let trevm = trevm_with_funds();
2385+
2386+
let tx = TransactionRequest::default()
2387+
.from(ALICE.address())
2388+
.to(BOB.address())
2389+
.value(U256::from(ETH_TO_WEI / 2));
2390+
2391+
let (estimation, _trevm) =
2392+
trevm.fill_cfg(&NoopCfg).fill_block(&NoopBlock).fill_tx(&tx).estimate_gas().unwrap();
2393+
2394+
assert!(estimation.is_success());
2395+
// The gas used should correspond to a simple transfer.
2396+
assert!(estimation.gas_used() == 21000);
2397+
}
2398+
2399+
#[test]
2400+
fn test_7702_authorization_estimation() {
2401+
// Insert the LogContract code
2402+
let db = InMemoryDB::default();
2403+
let log_address = Address::repeat_byte(0x32);
2404+
2405+
// Set up trevm, and test balances.
2406+
let mut trevm =
2407+
TrevmBuilder::new().with_db(db).with_spec_id(SpecId::PRAGUE).build_trevm().unwrap();
2408+
let _ = trevm.test_set_balance(ALICE.address(), U256::from(ETH_TO_WEI));
2409+
let _ = trevm.set_bytecode_unchecked(log_address, Bytecode::new_raw(LOG_BYTECODE.into()));
2410+
2411+
// Bob will sign the authorization.
2412+
let authorization = Authorization {
2413+
chain_id: U256::ZERO,
2414+
address: log_address,
2415+
// We know Bob's nonce is 0.
2416+
nonce: 0,
2417+
};
2418+
let signature = BOB.sign_hash_sync(&authorization.signature_hash()).unwrap();
2419+
let signed_authorization = authorization.into_signed(signature);
2420+
2421+
let tx = TransactionRequest::default()
2422+
.from(ALICE.address())
2423+
.to(BOB.address())
2424+
.with_authorization_list(vec![signed_authorization])
2425+
.with_input(bytes!("0x7b3ab2d0")); // emitHello()
2426+
2427+
let (estimation, trevm) =
2428+
trevm.fill_cfg(&NoopCfg).fill_block(&NoopBlock).fill_tx(&tx).estimate_gas().unwrap();
2429+
2430+
dbg!(&estimation);
2431+
assert!(estimation.is_success());
2432+
2433+
let tx = tx.with_gas_limit(estimation.limit());
2434+
2435+
let mut output = trevm.clear_tx().fill_tx(&tx).run().unwrap();
2436+
2437+
let bob_code = output.read_code(BOB.address());
2438+
dbg!(&bob_code);
2439+
2440+
dbg!(&output.result());
2441+
assert!(output.result().is_success());
2442+
assert!(output.result().logs().len() == 1);
2443+
}
2444+
}
2445+
23492446
// Some code above and documentation is adapted from the revm crate, and is
23502447
// reproduced here under the terms of the MIT license.
23512448
//

src/test_utils.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ use revm::{
1212
Context, Inspector, MainBuilder,
1313
};
1414

15+
/// LogContract bytecode
16+
pub const LOG_BYTECODE: &str = "0x60806040526004361015610013575b6100ca565b61001d5f3561003c565b80637b3ab2d01461003757639ee1a4400361000e57610097565b610064565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f91031261005a57565b61004c565b5f0190565b3461009257610074366004610050565b61007c6100ce565b610084610042565b8061008e8161005f565b0390f35b610048565b346100c5576100a7366004610050565b6100af610106565b6100b7610042565b806100c18161005f565b0390f35b610048565b5f80fd5b7fbcdfe0d5b27dd186282e187525415c57ea3077c34efb39148111e4d342e7ab0e6100f7610042565b806101018161005f565b0390a1565b7f2d67bb91f17bca05af6764ab411e86f4ddf757adb89fcec59a7d21c525d4171261012f610042565b806101398161005f565b0390a156fea2646970667358221220e22cd46ba129dcbd6f62f632cc862b0924d3f36c991fd0b45947581aa3010d6464736f6c634300081a0033";
17+
1518
impl<Insp, State> Trevm<InMemoryDB, Insp, State>
1619
where
1720
Insp: Inspector<Ctx<InMemoryDB>>,

0 commit comments

Comments
 (0)