-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
perf: add benchmarks for different components (#273)
- Loading branch information
Showing
7 changed files
with
9,930 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
//! Benchmarks the CPU execution of a transaction calling a simple Fibonacci | ||
//! contract, iterating over and over until reaching the 25M gas limit. | ||
//! | ||
//! Total number of user instructions: 7_136_858. | ||
//! Total number of loops: 2_378_952. | ||
use std::collections::HashMap; | ||
use std::str::FromStr; | ||
|
||
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; | ||
use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; | ||
use ethereum_types::{Address, H256, U256}; | ||
use evm_arithmetization::cpu::kernel::aggregator::KERNEL; | ||
use evm_arithmetization::cpu::kernel::opcodes::{get_opcode, get_push_opcode}; | ||
use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; | ||
use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; | ||
use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; | ||
use evm_arithmetization::prover::testing::simulate_execution; | ||
use evm_arithmetization::Node; | ||
use hex_literal::hex; | ||
use keccak_hash::keccak; | ||
use mpt_trie::nibbles::Nibbles; | ||
use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; | ||
use plonky2::field::goldilocks_field::GoldilocksField; | ||
|
||
type F = GoldilocksField; | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
let inputs = prepare_setup().unwrap(); | ||
|
||
// Dummy call to preinitialize the kernel. | ||
let _ = KERNEL.hash(); | ||
|
||
let mut group = c.benchmark_group("fibonacci_25m_gas"); | ||
group.sample_size(10); | ||
group.bench_function(BenchmarkId::from_parameter(8), |b| { | ||
b.iter_batched( | ||
|| inputs.clone(), | ||
|inp| simulate_execution::<F>(inp).unwrap(), | ||
BatchSize::LargeInput, | ||
) | ||
}); | ||
|
||
// Last run to print the number of CPU cycles. | ||
init_logger(); | ||
simulate_execution::<F>(inputs).unwrap(); | ||
} | ||
|
||
fn prepare_setup() -> anyhow::Result<GenerationInputs> { | ||
let sender = hex!("8943545177806ED17B9F23F0a21ee5948eCaa776"); | ||
let to = hex!("159271B89fea49aF29DFaf8b4eCE7D042D5d6f07"); | ||
|
||
let sender_state_key = keccak(sender); | ||
let to_state_key = keccak(to); | ||
|
||
let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap(); | ||
let to_nibbles = Nibbles::from_bytes_be(to_state_key.as_bytes()).unwrap(); | ||
|
||
let push1 = get_push_opcode(1); | ||
let push4 = get_push_opcode(4); | ||
let add = get_opcode("ADD"); | ||
let swap1 = get_opcode("SWAP1"); | ||
let dup2 = get_opcode("DUP2"); | ||
let jump = get_opcode("JUMP"); | ||
let jumpdest = get_opcode("JUMPDEST"); | ||
let code = [ | ||
push1, 1, push1, 1, jumpdest, dup2, add, swap1, push4, 0, 0, 0, 4, jump, | ||
]; | ||
let code_hash = keccak(code); | ||
|
||
let empty_trie_root = HashedPartialTrie::from(Node::Empty).hash(); | ||
|
||
let sender_account_before = AccountRlp { | ||
nonce: 169.into(), | ||
balance: U256::from_dec_str("999999999998417410153631615")?, | ||
storage_root: empty_trie_root, | ||
code_hash: keccak(vec![]), | ||
}; | ||
let to_account_before = AccountRlp { | ||
nonce: 1.into(), | ||
balance: 0.into(), | ||
storage_root: empty_trie_root, | ||
code_hash, | ||
}; | ||
|
||
let mut state_trie_before = HashedPartialTrie::from(Node::Empty); | ||
state_trie_before.insert(sender_nibbles, rlp::encode(&sender_account_before).to_vec())?; | ||
state_trie_before.insert(to_nibbles, rlp::encode(&to_account_before).to_vec())?; | ||
|
||
let tries_before = TrieInputs { | ||
state_trie: state_trie_before, | ||
transactions_trie: Node::Empty.into(), | ||
receipts_trie: Node::Empty.into(), | ||
storage_tries: vec![ | ||
(sender_state_key, Node::Empty.into()), | ||
(to_state_key, Node::Empty.into()), | ||
], | ||
}; | ||
|
||
let gas_used = U256::from(0x17d7840_u32); | ||
|
||
let txn = hex!("f86981a9843b9aca1084017d784094159271b89fea49af29dfaf8b4ece7d042d5d6f0780808360306ba00cdea08ac2e8075188b289d779fa84bf86020c2b162bbee11d2785b5225b0ccca00ea9a76f4641955a74ae8c1589914fc7d6c5bfe5940454a89daf5b12d6f06617"); | ||
let value = U256::zero(); | ||
|
||
let block_metadata = BlockMetadata { | ||
block_beneficiary: Address::from(sender), | ||
block_difficulty: 0x0.into(), | ||
block_number: 0x176.into(), | ||
block_chain_id: 0x301824.into(), | ||
block_timestamp: 0x664e63af.into(), | ||
block_gaslimit: 0x1c9c380.into(), | ||
block_gas_used: gas_used, | ||
block_bloom: [0.into(); 8], | ||
block_base_fee: 0x11.into(), | ||
block_random: H256(hex!( | ||
"388bd2892c01ab13e22f713316cc2b5d3c3d963e1426c25a80c7878a1815f889" | ||
)), | ||
}; | ||
|
||
let mut contract_code = HashMap::new(); | ||
contract_code.insert(keccak(vec![]), vec![]); | ||
contract_code.insert(code_hash, code.to_vec()); | ||
|
||
let sender_account_after = AccountRlp { | ||
balance: sender_account_before.balance - value - gas_used * block_metadata.block_base_fee, | ||
nonce: sender_account_before.nonce + 1, | ||
..sender_account_before | ||
}; | ||
let to_account_after = to_account_before; | ||
|
||
let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty); | ||
expected_state_trie_after | ||
.insert(sender_nibbles, rlp::encode(&sender_account_after).to_vec())?; | ||
expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec())?; | ||
|
||
let receipt_0 = LegacyReceiptRlp { | ||
status: false, | ||
cum_gas_used: gas_used, | ||
bloom: vec![0; 256].into(), | ||
logs: vec![], | ||
}; | ||
let mut receipts_trie = HashedPartialTrie::from(Node::Empty); | ||
receipts_trie.insert( | ||
Nibbles::from_str("0x80").unwrap(), | ||
rlp::encode(&receipt_0).to_vec(), | ||
)?; | ||
let transactions_trie: HashedPartialTrie = Node::Leaf { | ||
nibbles: Nibbles::from_str("0x80").unwrap(), | ||
value: txn.to_vec(), | ||
} | ||
.into(); | ||
|
||
let trie_roots_after = TrieRoots { | ||
state_root: expected_state_trie_after.hash(), | ||
transactions_root: transactions_trie.hash(), | ||
receipts_root: receipts_trie.hash(), | ||
}; | ||
|
||
Ok(GenerationInputs { | ||
signed_txn: Some(txn.to_vec()), | ||
withdrawals: vec![], | ||
tries: tries_before, | ||
trie_roots_after, | ||
contract_code, | ||
checkpoint_state_trie_root: H256(hex!( | ||
"fe07ff6d1ab215df17884b89112ccf2373597285a56c5902150313ad1a53ee57" | ||
)), | ||
block_metadata, | ||
txn_number_before: 0.into(), | ||
gas_used_before: 0.into(), | ||
gas_used_after: gas_used, | ||
block_hashes: BlockHashes { | ||
prev_hashes: vec![H256::default(); 256], | ||
cur_hash: H256::default(), | ||
}, | ||
}) | ||
} | ||
|
||
fn init_logger() { | ||
let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); | ||
} | ||
|
||
criterion_group!(benches, criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//! Benchmarks the processing by the decoder of a block witness obtained from a | ||
//! node into a sequence of prover inputs ready to be sent to a prover. | ||
//! | ||
//! The block being processed here is the 19240650th Ethereum block | ||
//! (<https://etherscan.io/block/19240650>) containing 201 transactions and 16 withdrawals. | ||
use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; | ||
use serde::{Deserialize, Serialize}; | ||
use trace_decoder::{ | ||
processed_block_trace::ProcessingMeta, | ||
trace_protocol::BlockTrace, | ||
types::{CodeHash, OtherBlockData}, | ||
}; | ||
|
||
#[derive(Clone, Debug, Deserialize, Serialize)] | ||
pub struct ProverInput { | ||
pub block_trace: BlockTrace, | ||
pub other_data: OtherBlockData, | ||
} | ||
|
||
fn resolve_code_hash_fn(_: &CodeHash) -> Vec<u8> { | ||
todo!() | ||
} | ||
|
||
fn criterion_benchmark(c: &mut Criterion) { | ||
let bytes = std::fs::read("benches/block_input.json").unwrap(); | ||
let prover_input: ProverInput = serde_json::from_slice(&bytes).unwrap(); | ||
|
||
c.bench_function("Block 19240650 processing", |b| { | ||
b.iter_batched( | ||
|| prover_input.clone(), | ||
|pi| { | ||
pi.block_trace | ||
.into_txn_proof_gen_ir( | ||
&ProcessingMeta::new(resolve_code_hash_fn), | ||
prover_input.other_data.clone(), | ||
) | ||
.unwrap() | ||
}, | ||
BatchSize::LargeInput, | ||
) | ||
}); | ||
} | ||
|
||
criterion_group!( | ||
name = benches; | ||
config = Criterion::default().sample_size(10); | ||
targets = criterion_benchmark); | ||
criterion_main!(benches); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters