revive_strategy/tracing/
call_tracer.rs1use alloy_primitives::{Address, U256 as RU256};
2use foundry_cheatcodes::ExpectedCallTracker;
3use polkadot_sdk::{
4 pallet_revive,
5 pallet_revive::tracing::Tracing,
6 sp_core::{H160, U256},
7};
8
9#[derive(Debug)]
10pub(crate) struct ExpectedCallTracer {
11 pub data: ExpectedCallTracker,
12 is_create: bool,
13}
14
15impl ExpectedCallTracer {
16 pub fn new(data: ExpectedCallTracker) -> Self {
17 Self { data, is_create: false }
18 }
19}
20
21impl Tracing for ExpectedCallTracer {
22 fn enter_child_span(
23 &mut self,
24 _from: H160,
25 to: H160,
26 is_delegate_call: Option<H160>,
27 _is_read_only: bool,
28 value: U256,
29 input: &[u8],
30 _gas: U256,
31 ) {
32 let addr =
33 is_delegate_call.map(|x| Address::from(x.0)).unwrap_or_else(|| Address::from(to.0));
34 if !self.is_create
35 && let Some(expected_calls_for_target) = self.data.get_mut(&addr)
36 {
37 for (calldata, (expected, actual_count)) in expected_calls_for_target {
39 if calldata.len() <= input.len() &&
42 *calldata == input[..calldata.len()] &&
44 expected
46 .value.is_none_or(|v| v == RU256::from_limbs(value.0))
47 {
52 *actual_count += 1;
53 }
54 }
55 }
56 }
57 fn exit_child_span(&mut self, _output: &pallet_revive::ExecReturnValue, _gas_left: U256) {
58 self.is_create = false;
59 }
60
61 fn instantiate_code(
62 &mut self,
63 _code: &polkadot_sdk::pallet_revive::Code,
64 _salt: Option<&[u8; 32]>,
65 ) {
66 self.is_create = true;
67 }
68}