Skip to content

Commit

Permalink
perf(levm): flamegraphs to l2 node for evm (#1616)
Browse files Browse the repository at this point in the history
**Motivation**

Generate flamegraph of ethrex client in order  to test levm performance.

**Description**

Add the flag -c or --contract to the ethrex_l2 cli to send tx to a
contract with bytecode to test the evm.

Steps to run the flamegraph (2 terminals are needed):
1. `make start-node-with-flamegraph`
2. `make load-node`

---------

Co-authored-by: fborello-lambda <federicoborello@lambdaclass.com>
Co-authored-by: Federico Borello <156438142+fborello-lambda@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 10, 2025
1 parent 856dcdb commit 44d957c
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 7 deletions.
34 changes: 34 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,37 @@ stats:
cd crates/vm/levm && make run-evm-ef-tests QUIET=true && echo
make hive-stats
cargo run --quiet --release -p hive_report

install-cli: ## 🛠️ Installs the ethrex-l2 cli
cargo install --path cmd/ethrex_l2/ --force

start-node-with-flamegraph: rm-test-db ## 🚀🔥 Starts an ethrex client used for testing
@if [ -z "$$L" ]; then \
LEVM=""; \
echo "Running the test-node without the LEVM feature"; \
echo "If you want to use levm, run the target with an L at the end: make <target> L=1"; \
else \
LEVM=",levm"; \
echo "Running the test-node with the LEVM feature"; \
fi; \
sudo CARGO_PROFILE_RELEASE_DEBUG=true cargo flamegraph \
--bin ethrex \
--features "dev$$LEVM" \
-- \
--network test_data/genesis-l2.json \
--http.port 1729 \
--datadir test_ethrex

load-node: install-cli ## 🚧 Runs a load-test. Run make start-node-with-flamegraph and in a new terminal make load-node
@if [ -z "$$C" ]; then \
CONTRACT_INTERACTION=""; \
echo "Running the load-test without contract interaction"; \
echo "If you want to interact with contracts to load the evm, run the target with a C at the end: make <target> C=1"; \
else \
CONTRACT_INTERACTION="-c"; \
echo "Running the load-test with contract interaction"; \
fi; \
ethrex_l2 test load --path test_data/private_keys.txt -i 100 -v --value 1 $$CONTRACT_INTERACTION

rm-test-db: ## 🛑 Removes the DB used by the ethrex client used for testing
sudo cargo run --release --bin ethrex -- removedb --datadir test_ethrex
55 changes: 49 additions & 6 deletions cmd/ethrex_l2/src/commands/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ use bytes::Bytes;
use clap::Subcommand;
use ethereum_types::{Address, H256, U256};
use ethrex_blockchain::constants::TX_GAS_COST;
use ethrex_l2_sdk::eth_client::{eth_sender::Overrides, EthClient};
use ethrex_l2_sdk::{
calldata::{self, Value},
eth_client::{eth_sender::Overrides, EthClient},
};
use keccak_hash::keccak;
use secp256k1::SecretKey;
use std::{
Expand Down Expand Up @@ -50,6 +53,13 @@ pub(crate) enum Command {
help = "Prints each transaction."
)]
verbose: bool,
#[clap(
short = 'c',
long = "contract",
default_value = "false",
help = "send value to address with contract"
)]
contract: bool,
},
}

Expand All @@ -67,6 +77,7 @@ async fn transfer_from(
value: U256,
iterations: u64,
verbose: bool,
calldata: Bytes,
cfg: EthrexL2Config,
) -> u64 {
let client = EthClient::new(&cfg.network.l2_rpc_url);
Expand Down Expand Up @@ -94,14 +105,18 @@ async fn transfer_from(
.build_eip1559_transaction(
to_address,
address,
Bytes::new(),
calldata.clone(),
Overrides {
chain_id: Some(cfg.network.l2_chain_id),
nonce: Some(i),
value: Some(value),
value: if calldata.is_empty() {
Some(value)
} else {
None
},
max_fee_per_gas: Some(3121115334),
max_priority_fee_per_gas: Some(3000000000),
gas_limit: Some(TX_GAS_COST),
gas_limit: Some(TX_GAS_COST * 5),
..Default::default()
},
10,
Expand All @@ -128,12 +143,40 @@ impl Command {
value,
iterations,
verbose,
contract,
} => {
if let Ok(lines) = read_lines(path) {
let to_address = match to {
let mut to_address = match to {
Some(address) => address,
None => Address::random(),
};
let calldata: Bytes = if contract {
// This is the bytecode for the contract with the following functions
// version() -> always returns 2
// function fibonacci(uint n) public pure returns (uint) -> returns the nth fib number
let init_code = hex::decode("6080604052348015600e575f5ffd5b506103198061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610034575f3560e01c806354fd4d501461003857806361047ff414610056575b5f5ffd5b610040610086565b60405161004d9190610152565b60405180910390f35b610070600480360381019061006b9190610199565b61008b565b60405161007d9190610152565b60405180910390f35b600281565b5f5f8210156100cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100c69061021e565b60405180910390fd5b5f82036100de575f9050610135565b600182036100ef5760019050610135565b5f5f90505f600190505f600290505b84811161012e575f82905083836101159190610269565b92508093505080806101269061029c565b9150506100fe565b5080925050505b919050565b5f819050919050565b61014c8161013a565b82525050565b5f6020820190506101655f830184610143565b92915050565b5f5ffd5b6101788161013a565b8114610182575f5ffd5b50565b5f813590506101938161016f565b92915050565b5f602082840312156101ae576101ad61016b565b5b5f6101bb84828501610185565b91505092915050565b5f82825260208201905092915050565b7f496e707574206d757374206265206e6f6e2d6e656761746976650000000000005f82015250565b5f610208601a836101c4565b9150610213826101d4565b602082019050919050565b5f6020820190508181035f830152610235816101fc565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f6102738261013a565b915061027e8361013a565b92508282019050808211156102965761029561023c565b5b92915050565b5f6102a68261013a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036102d8576102d761023c565b5b60018201905091905056fea264697066735822122021e2c2b56b7e23b9555cc95390dfb2979a8526595038818d133d5bb772c01a6564736f6c634300081c0033")?;
let client = EthClient::new(&cfg.network.l2_rpc_url);

let (_, contract_address) = client
.deploy(
cfg.wallet.address,
cfg.wallet.private_key,
init_code.into(),
Overrides::default(),
)
.await?;

to_address = contract_address;

calldata::encode_calldata(
"fibonacci(uint256)",
&[Value::Uint(100000000000000_u64.into())],
)?
.into()
} else {
Bytes::new()
};

println!("Sending to: {to_address:#x}");

let mut threads = vec![];
Expand All @@ -144,6 +187,7 @@ impl Command {
value,
iterations,
verbose,
calldata.clone(),
cfg.clone(),
));
threads.push(thread);
Expand All @@ -156,7 +200,6 @@ impl Command {

println!("Total retries: {retries}");
}

Ok(())
}
}
Expand Down
1 change: 0 additions & 1 deletion test_data/private_keys.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
0x63b8139bbf84a5a65613e544be239f59f884434462598bd8bfe9f2c9045aa336
0xe4f7dc8b199fdaac6693c9c412ea68aed9e1584d193e1c3478d30a6f01f26057
0xb142300756f21d04354cd336fb01138767825d50c1d91cf751236bdd7cf522ab
0xba73c72b16553dbba5a275f541c06e77dcf7773514898dc0f3ddfe13c44f9e11
Expand Down

0 comments on commit 44d957c

Please sign in to comment.