Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bench: add uniswap independent bench #5

Merged
merged 2 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions benches/gigagas.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
#![allow(missing_docs)]

#[path = "../tests/common/mod.rs"]
pub mod common;

#[path = "../tests/erc20/mod.rs"]
pub mod erc20;

#[path = "../tests/uniswap/mod.rs"]
pub mod uniswap;

use crate::erc20::erc20_contract::ERC20Token;
use crate::erc20::generate_cluster;
use alloy_chains::NamedChain;
use common::storage::InMemoryDB;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
Expand All @@ -11,14 +19,9 @@ use fastrace_jaeger::JaegerReporter;
use grevm::GrevmScheduler;
use revm::primitives::alloy_primitives::U160;
use revm::primitives::{Address, Env, SpecId, TransactTo, TxEnv, U256};
use std::collections::HashMap;
use std::sync::Arc;

#[path = "../tests/common/mod.rs"]
pub mod common;

#[path = "../tests/erc20/mod.rs"]
pub mod erc20;

const GIGA_GAS: u64 = 1_000_000_000;

#[global_allocator]
Expand Down Expand Up @@ -131,14 +134,14 @@ fn benchmark_gigagas(c: &mut Criterion) {
bench_dependent_raw_transfers(c, db_latency_us);
benchmark_erc20(c, db_latency_us);
benchmark_dependent_erc20(c, db_latency_us);
bench_uniswap(c, db_latency_us);

fastrace::flush();
}

fn benchmark_erc20(c: &mut Criterion, db_latency_us: u64) {
const PEVM_GAS_LIMIT: u64 = 26_938;
let block_size = (GIGA_GAS as f64 / PEVM_GAS_LIMIT as f64).ceil() as usize;
let (mut state, bytecodes, eoa, sca) = generate_cluster(block_size, 1);
let block_size = (GIGA_GAS as f64 / erc20::ESTIMATED_GAS_USED as f64).ceil() as usize;
let (mut state, bytecodes, eoa, sca) = erc20::generate_cluster(block_size, 1);
let miner = common::mock_miner_account();
state.insert(miner.0, miner.1);
let mut txs = Vec::with_capacity(block_size);
Expand All @@ -148,7 +151,7 @@ fn benchmark_erc20(c: &mut Criterion, db_latency_us: u64) {
caller: addr,
transact_to: TransactTo::Call(sca),
value: U256::from(0),
gas_limit: 50_000,
gas_limit: erc20::GAS_LIMIT,
gas_price: U256::from(1),
nonce: Some(0),
data: ERC20Token::transfer(addr, U256::from(900)),
Expand All @@ -163,21 +166,19 @@ fn benchmark_erc20(c: &mut Criterion, db_latency_us: u64) {
}

fn benchmark_dependent_erc20(c: &mut Criterion, db_latency_us: u64) {
const PEVM_GAS_LIMIT: u64 = 26_938;
let block_size = (GIGA_GAS as f64 / PEVM_GAS_LIMIT as f64).ceil() as usize;
let (mut state, bytecodes, eoa, sca) = generate_cluster(block_size, 1);
let block_size = (GIGA_GAS as f64 / erc20::ESTIMATED_GAS_USED as f64).ceil() as usize;
let (mut state, bytecodes, eoa, sca) = erc20::generate_cluster(block_size, 1);
let miner = common::mock_miner_account();
state.insert(miner.0, miner.1);
let mut txs = Vec::with_capacity(block_size);
let sca = sca[0];
for (i, addr) in eoa.iter().enumerate() {
// Every 64 EOAs transfer token to the same recipient.
let recipient = eoa[i % 64];
let tx = TxEnv {
caller: *addr,
transact_to: TransactTo::Call(sca),
value: U256::from(0),
gas_limit: 50_000,
gas_limit: erc20::GAS_LIMIT,
gas_price: U256::from(1),
nonce: Some(0),
data: ERC20Token::transfer(recipient, U256::from(900)),
Expand All @@ -191,5 +192,21 @@ fn benchmark_dependent_erc20(c: &mut Criterion, db_latency_us: u64) {
bench(c, "Dependent ERC20", db, txs);
}

fn bench_uniswap(c: &mut Criterion, db_latency_us: u64) {
let block_size = (GIGA_GAS as f64 / uniswap::ESTIMATED_GAS_USED as f64).ceil() as usize;
let mut final_state = HashMap::from([common::mock_miner_account()]);
let mut final_bytecodes = HashMap::default();
let mut final_txs = Vec::<TxEnv>::new();
for _ in 0..block_size {
let (state, bytecodes, txs) = uniswap::generate_cluster(1, 1);
final_state.extend(state);
final_bytecodes.extend(bytecodes);
final_txs.extend(txs);
}
let mut db = InMemoryDB::new(final_state, final_bytecodes, Default::default());
db.latency_us = db_latency_us;
bench(c, "Independent Uniswap", db, final_txs);
}

criterion_group!(benches, benchmark_gigagas);
criterion_main!(benches);
32 changes: 21 additions & 11 deletions tests/common/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ use std::sync::Arc;
use std::time::Instant;

fn compare_bundle_state(left: &BundleState, right: &BundleState) {
let left = left.clone();
let right = right.clone();
assert!(
left.contracts.keys().all(|k| right.contracts.contains_key(k)),
"Left contracts: {:?}, Right contracts: {:?}",
Expand All @@ -33,22 +31,21 @@ fn compare_bundle_state(left: &BundleState, right: &BundleState) {
right.contracts.keys()
);

let left_state: BTreeMap<Address, BundleAccount> = left.state.into_iter().collect();
let right_state: BTreeMap<Address, BundleAccount> = right.state.into_iter().collect();
let left_state: BTreeMap<&Address, &BundleAccount> = left.state.iter().collect();
let right_state: BTreeMap<&Address, &BundleAccount> = right.state.iter().collect();
assert_eq!(left_state.len(), right_state.len());

for ((addr1, account1), (addr2, account2)) in
left_state.into_iter().zip(right_state.into_iter())
{
assert_eq!(addr1, addr2);
let BundleAccount { info, original_info, storage, status } = account1;
assert_eq!(info, account2.info);
assert_eq!(original_info, account2.original_info);
assert_eq!(status, account2.status);
let left_storage: BTreeMap<U256, StorageSlot> = storage.into_iter().collect();
let right_storage: BTreeMap<U256, StorageSlot> = account2.storage.into_iter().collect();
assert_eq!(account1.info, account2.info, "Address: {:?}", addr1);
assert_eq!(account1.original_info, account2.original_info, "Address: {:?}", addr1);
assert_eq!(account1.status, account2.status, "Address: {:?}", addr1);
let left_storage: BTreeMap<&U256, &StorageSlot> = account1.storage.iter().collect();
let right_storage: BTreeMap<&U256, &StorageSlot> = account2.storage.iter().collect();
for (s1, s2) in left_storage.into_iter().zip(right_storage.into_iter()) {
assert_eq!(s1, s2);
assert_eq!(s1, s2, "Address: {:?}", addr1);
}
}
}
Expand Down Expand Up @@ -137,6 +134,19 @@ pub fn compare_evm_execute<DB>(
let reth_result = execute_revm_sequential(db.clone(), SpecId::LATEST, env.clone(), txs.clone());
println!("Origin sequential execute time: {}ms", start.elapsed().as_millis());

let mut max_gas_spent = 0;
let mut max_gas_used = 0;
for result in &reth_result.as_ref().unwrap().results {
match result {
ExecutionResult::Success { gas_used, gas_refunded, .. } => {
max_gas_spent = max_gas_spent.max(gas_used + gas_refunded);
max_gas_used = max_gas_used.max(*gas_used);
}
_ => panic!("result is not success"),
}
}
println!("max_gas_spent: {}, max_gas_used: {}", max_gas_spent, max_gas_used);

compare_execution_result(
&reth_result.as_ref().unwrap().results,
&sequential_result.as_ref().unwrap().results,
Expand Down
3 changes: 2 additions & 1 deletion tests/erc20/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::erc20::erc20_contract::ERC20Token;

pub mod erc20_contract;

pub const GAS_LIMIT: u64 = 50_000;
pub const GAS_LIMIT: u64 = 35_000;
pub const ESTIMATED_GAS_USED: u64 = 29_738;

/// Mapping from address to [EvmAccount]
pub type ChainState = HashMap<Address, DbAccount>;
Expand Down
5 changes: 4 additions & 1 deletion tests/uniswap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ pub mod contract;
use crate::erc20::erc20_contract::ERC20Token;
use contract::{SingleSwap, SwapRouter, UniswapV3Factory, UniswapV3Pool, WETH9};
use revm::db::PlainAccount;
use revm::interpreter::analysis::to_analysed;
use revm::primitives::{
fixed_bytes, uint, AccountInfo, Address, Bytecode, Bytes, TransactTo, TxEnv, B256, U256,
};
use std::collections::HashMap;

pub const GAS_LIMIT: u64 = 155_934;
pub const GAS_LIMIT: u64 = 200_000;
pub const ESTIMATED_GAS_USED: u64 = 155_934;

pub fn generate_cluster(
num_people: usize,
Expand Down Expand Up @@ -165,6 +167,7 @@ pub fn generate_cluster(
for account in state.values_mut() {
let code = account.info.code.take();
if let Some(code) = code {
let code = to_analysed(code);
bytecodes.insert(account.info.code_hash, code);
}
}
Expand Down
Loading