Skip to content

Commit

Permalink
add evm debug trace profile
Browse files Browse the repository at this point in the history
- add evm.debug_trace locust profile
- add get_random_tx in test_data\base.py
- change default block range to 10000 instead of 20
- add print to console to display test data preparation progress
- add debug_traceCall params factory and add timeout to trace configs
  • Loading branch information
erwin-wee committed Dec 6, 2023
1 parent ab45d44 commit 6361e56
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 4 deletions.
44 changes: 44 additions & 0 deletions chainbench/profile/evm/debug_trace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""
Ethereum profile (heavy mode).
"""

from locust import constant_pacing, task

from chainbench.user.evm import EVMBenchUser
from chainbench.util.rng import get_rng


class EthereumDebugTraceProfile(EVMBenchUser):
wait_time = constant_pacing(10)

@task(324)
def debug_trace_transaction_task(self):
self.make_call(
name="debug_trace_transaction",
method="debug_traceTransaction",
params=self._trace_transaction_params_factory(get_rng()),
),

@task(41)
def debug_trace_call_task(self):
self.make_call(
name="debug_trace_call",
method="debug_traceCall",
params=self._trace_call_params_factory(get_rng()),
),

@task(36)
def debug_trace_block_by_number_task(self):
self.make_call(
name="debug_trace_block_by_number",
method="debug_traceBlockByNumber",
params=self._trace_block_by_number_params_factory(get_rng()),
),

@task(1)
def debug_trace_block_by_hash_task(self):
self.make_call(
name="debug_trace_block_by_hash",
method="debug_traceBlockByHash",
params=self._trace_block_by_hash_params_factory(get_rng()),
),
5 changes: 5 additions & 0 deletions chainbench/test_data/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ def get_random_tx_hash(self, rng: RNG | None = None) -> TxHash:
rng = get_rng()
return rng.random.choice(self.tx_hashes)

def get_random_tx(self, rng: RNG | None = None) -> Tx:
if rng is None:
rng = get_rng()
return rng.random.choice(self.txs)

def get_random_recent_block_number(self, n: int, rng: RNG | None = None) -> BlockNumber:
if rng is None:
rng = get_rng()
Expand Down
7 changes: 6 additions & 1 deletion chainbench/test_data/evm.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _get_start_and_end_blocks(self, use_recent_blocks: bool) -> tuple[int, int]:
return start_block_number, end_block_number
else:
end_block_number = self._fetch_latest_block_number()
start_block_number = end_block_number - 20
start_block_number = end_block_number - 10000
logger.info("Using recent blocks from %s to %s as test data", start_block_number, end_block_number)
return start_block_number, end_block_number

Expand All @@ -99,6 +99,11 @@ def _get_init_data(self, parsed_options) -> BlockchainData:
start_block_number, end_block_number = self._get_start_and_end_blocks(parsed_options.use_recent_blocks)

while self.TXS_REQUIRED > len(txs) or self.ACCOUNTS_REQUIRED > len(accounts) or self.SAVE_BLOCKS > len(blocks):
print(
f"txs = {len(txs)}/{self.TXS_REQUIRED} "
f"accounts = {len(accounts)}/{self.ACCOUNTS_REQUIRED} "
f"blocks = {len(blocks)}/{self.SAVE_BLOCKS}"
)
if self.ACCOUNTS_REQUIRED > len(accounts) or self.TXS_REQUIRED > len(txs):
return_txs = True
else:
Expand Down
38 changes: 35 additions & 3 deletions chainbench/user/evm.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class EVMBenchUser(BaseBenchUser):
abstract = True
test_data = EVMTestData()

_default_trace_timeout = "120s"

def _get_logs_params_factory(self, rng: RNG):
return [
{
Expand Down Expand Up @@ -38,16 +40,43 @@ def _get_balance_params_factory(self, rng: RNG):
hex(self.test_data.get_random_block_number(rng)),
]

def _trace_call_params_factory(self, rng: RNG):
tx_data = self.test_data.get_random_tx(rng)
tx_param = {
"to": tx_data["to"],
"gas": tx_data["gas"],
"value": tx_data["value"],
}

if "maxFeePerGas" in tx_data:
tx_param["maxFeePerGas"] = tx_data["maxFeePerGas"]
else:
tx_param["gasPrice"] = tx_data["gasPrice"]

if "input" in tx_data:
if tx_data["input"] != "0x":
tx_param["data"] = tx_data["input"]

if "accessList" in tx_data:
if len(tx_data["accessList"]) > 0:
tx_param["accessList"] = tx_data["accessList"]

return [
tx_param,
tx_data["blockNumber"],
{"tracer": "callTracer", "timeout": self._default_trace_timeout},
]

def _trace_block_by_number_params_factory(self, rng: RNG):
return [
hex(self.test_data.get_random_block_number(rng)),
{"tracer": "callTracer"},
{"tracer": "callTracer", "timeout": self._default_trace_timeout},
]

def _trace_block_by_hash_params_factory(self, rng: RNG):
return [
self.test_data.get_random_block_hash(rng),
{"tracer": "callTracer"},
{"tracer": "callTracer", "timeout": self._default_trace_timeout},
]

def _trace_replay_block_transaction_params_factory(self, rng: RNG):
Expand All @@ -63,7 +92,10 @@ def _trace_replay_transaction_params_factory(self, rng: RNG):
]

def _trace_transaction_params_factory(self, rng: RNG):
return [self.test_data.get_random_tx_hash(rng), {"tracer": "prestateTracer"}]
return [
self.test_data.get_random_tx_hash(rng),
{"tracer": "callTracer", "timeout": self._default_trace_timeout},
]

def _trace_filter_params_factory(self, rng: RNG):
block_number = self.test_data.get_random_block_number(rng)
Expand Down

0 comments on commit 6361e56

Please sign in to comment.