From c7187130ba3d4d8c7d7e49e6b5ac603be6125c3e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 8 Jun 2023 01:32:11 +0200 Subject: [PATCH] feat(rpc): track gas remaining (#3049) --- .../revm/revm-inspectors/src/tracing/mod.rs | 27 +++++++------------ .../revm/revm-inspectors/src/tracing/types.rs | 7 +++-- crates/rpc/rpc-types/src/eth/trace/parity.rs | 19 +++++++++++++ 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/crates/revm/revm-inspectors/src/tracing/mod.rs b/crates/revm/revm-inspectors/src/tracing/mod.rs index 3a7acf18c..920ab5bb9 100644 --- a/crates/revm/revm-inspectors/src/tracing/mod.rs +++ b/crates/revm/revm-inspectors/src/tracing/mod.rs @@ -147,20 +147,23 @@ impl TracingInspector { /// # Panics /// /// This expects an existing trace [Self::start_trace_on_call] - fn fill_trace_on_call_end( + fn fill_trace_on_call_end( &mut self, + data: &EVMData<'_, DB>, status: InstructionResult, - gas_used: u64, + gas: &Gas, output: Bytes, created_address: Option
, ) { let trace_idx = self.pop_trace_idx(); let trace = &mut self.traces.arena[trace_idx].trace; - let success = matches!(status, return_ok!()); - trace.status = status; - trace.success = success; + let gas_used = gas_used(data.env.cfg.spec_id, gas.spend(), gas.refunded() as u64); + trace.gas_used = gas_used; + trace.gas_limit = gas.limit(); + trace.status = status; + trace.success = matches!(status, return_ok!()); trace.output = output.clone(); self.last_call_return_data = Some(output); @@ -380,12 +383,7 @@ where ) -> (InstructionResult, Gas, Bytes) { self.gas_inspector.call_end(data, inputs, gas, ret, out.clone(), is_static); - self.fill_trace_on_call_end( - ret, - gas_used(data.env.cfg.spec_id, gas.spend(), gas.refunded() as u64), - out.clone(), - None, - ); + self.fill_trace_on_call_end(data, ret, &gas, out.clone(), None); (ret, gas, out) } @@ -439,12 +437,7 @@ where }) .unwrap_or_default(); - self.fill_trace_on_call_end( - status, - gas_used(data.env.cfg.spec_id, gas.spend(), gas.refunded() as u64), - code.into(), - address, - ); + self.fill_trace_on_call_end(data, status, &gas, code.into(), address); (status, address, gas, retdata) } diff --git a/crates/revm/revm-inspectors/src/tracing/types.rs b/crates/revm/revm-inspectors/src/tracing/types.rs index b62e28b9d..c11e2f102 100644 --- a/crates/revm/revm-inspectors/src/tracing/types.rs +++ b/crates/revm/revm-inspectors/src/tracing/types.rs @@ -141,6 +141,8 @@ pub(crate) struct CallTrace { pub(crate) last_call_return_value: Option, /// The gas cost of the call pub(crate) gas_used: u64, + /// The gas limit of the call + pub(crate) gas_limit: u64, /// The status of the trace's call pub(crate) status: InstructionResult, /// call context of the runtime @@ -176,6 +178,7 @@ impl Default for CallTrace { output: Default::default(), last_call_return_value: None, gas_used: Default::default(), + gas_limit: Default::default(), status: InstructionResult::Continue, call_context: Default::default(), steps: Default::default(), @@ -347,7 +350,7 @@ impl CallTraceNode { from: self.trace.caller, to: self.trace.address, value: self.trace.value, - gas: self.trace.gas_used.into(), + gas: self.trace.gas_limit.into(), input: self.trace.data.clone().into(), call_type: self.kind().into(), }) @@ -355,7 +358,7 @@ impl CallTraceNode { CallKind::Create | CallKind::Create2 => Action::Create(CreateAction { from: self.trace.caller, value: self.trace.value, - gas: self.trace.gas_used.into(), + gas: self.trace.gas_limit.into(), init: self.trace.data.clone().into(), }), } diff --git a/crates/rpc/rpc-types/src/eth/trace/parity.rs b/crates/rpc/rpc-types/src/eth/trace/parity.rs index a60dd8e95..74b8b399e 100644 --- a/crates/rpc/rpc-types/src/eth/trace/parity.rs +++ b/crates/rpc/rpc-types/src/eth/trace/parity.rs @@ -151,23 +151,35 @@ pub enum CallType { StaticCall, } +/// Represents a certain [CallType] of a _call_ or message transaction. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CallAction { + /// Address of the sending account. pub from: Address, + /// Address of the destination/target account. pub to: Address, + /// Value transferred to the destination account. pub value: U256, + /// The gas available for executing the call. pub gas: U64, + /// The input data provided to the call. pub input: Bytes, + /// The type of the call. pub call_type: CallType, } +/// Represents a _create_ action, either a `CREATE` operation or a CREATE transaction. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CreateAction { + /// The address of the creator. pub from: Address, + /// The value with which the new account is endowed. pub value: U256, + /// The gas available for the creation init code. pub gas: U64, + /// The init code. pub init: Bytes, } @@ -181,16 +193,23 @@ pub enum RewardType { #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct RewardAction { + /// Author's address. pub author: Address, + /// Reward amount. pub value: U256, + /// Reward type. pub reward_type: RewardType, } +/// Represents a _selfdestruct_ action fka `suicide`. #[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SelfdestructAction { + /// destroyed/suicided address. pub address: Address, + /// destroyed contract heir. pub refund_address: Address, + /// Balance of the contract just before it was destroyed. pub balance: U256, }