Skip to content

Commit b7c663b

Browse files
committed
feat: support BSC system transactions and refactor tracer code
- Add support for BSC system transactions by skipping block gas limit validation - Detect BSC system txs by: gas_limit == u64::MAX/2 && caller == beneficiary - Add handle_bsc_system_transaction() helper to reduce code duplication - Apply BSC check across all tracers: 4byteTracer, callTracer, preStateTracer, muxTracer, flatCallTracer - Support both debug_traceCall and debug_traceTransaction methods
1 parent 6f649cd commit b7c663b

File tree

1 file changed

+39
-6
lines changed

1 file changed

+39
-6
lines changed

crates/rpc/rpc/src/debug.rs

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,20 @@ impl<Eth> DebugApi<Eth>
8080
where
8181
Eth: EthApiTypes + TraceExt + 'static,
8282
{
83+
/// Handles BSC system transactions by disabling block gas limit validation.
84+
///
85+
/// BSC system transactions are identified by:
86+
/// 1. gas_limit == u64::MAX / 2
87+
/// 2. caller == block beneficiary (coinbase)
88+
fn handle_bsc_system_transaction(
89+
evm_env: &mut EvmEnvFor<Eth::Evm>,
90+
tx_env: &TxEnvFor<Eth::Evm>,
91+
) {
92+
if tx_env.gas_limit() == u64::MAX / 2 && tx_env.caller() == evm_env.block_env.beneficiary {
93+
evm_env.cfg_env.disable_block_gas_limit = true;
94+
}
95+
}
96+
8397
/// Acquires a permit to execute a tracing call.
8498
async fn acquire_trace_permit(&self) -> Result<OwnedSemaphorePermit, AcquireError> {
8599
self.inner.blocking_task_guard.clone().acquire_owned().await
@@ -283,7 +297,8 @@ where
283297
let mut inspector = FourByteInspector::default();
284298
let inspector = self
285299
.eth_api()
286-
.spawn_with_call_at(call, at, overrides, move |db, evm_env, tx_env| {
300+
.spawn_with_call_at(call, at, overrides, move |db, mut evm_env, tx_env| {
301+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
287302
this.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?;
288303
Ok(inspector)
289304
})
@@ -301,7 +316,9 @@ where
301316

302317
let frame = self
303318
.eth_api()
304-
.spawn_with_call_at(call, at, overrides, move |db, evm_env, tx_env| {
319+
.spawn_with_call_at(call, at, overrides, move |db, mut evm_env, tx_env| {
320+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
321+
305322
let gas_limit = tx_env.gas_limit();
306323
let res =
307324
this.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?;
@@ -324,11 +341,13 @@ where
324341

325342
let frame = self
326343
.eth_api()
327-
.spawn_with_call_at(call, at, overrides, move |db, evm_env, tx_env| {
344+
.spawn_with_call_at(call, at, overrides, move |db, mut evm_env, tx_env| {
328345
// wrapper is hack to get around 'higher-ranked lifetime error',
329346
// see <https://github.com/rust-lang/rust/issues/100013>
330347
let db = db.0;
331348

349+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
350+
332351
let gas_limit = tx_env.gas_limit();
333352
let res = this.eth_api().inspect(
334353
&mut *db,
@@ -358,7 +377,7 @@ where
358377
let frame = self
359378
.inner
360379
.eth_api
361-
.spawn_with_call_at(call, at, overrides, move |db, evm_env, tx_env| {
380+
.spawn_with_call_at(call, at, overrides, move |db, mut evm_env, tx_env| {
362381
// wrapper is hack to get around 'higher-ranked lifetime error', see
363382
// <https://github.com/rust-lang/rust/issues/100013>
364383
let db = db.0;
@@ -371,6 +390,8 @@ where
371390
index: None,
372391
};
373392

393+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
394+
374395
let res = this.eth_api().inspect(
375396
&mut *db,
376397
evm_env,
@@ -397,7 +418,9 @@ where
397418
let frame: FlatCallFrame = self
398419
.inner
399420
.eth_api
400-
.spawn_with_call_at(call, at, overrides, move |db, evm_env, tx_env| {
421+
.spawn_with_call_at(call, at, overrides, move |db, mut evm_env, tx_env| {
422+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
423+
401424
let gas_limit = tx_env.gas_limit();
402425
this.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?;
403426
let tx_info = TransactionInfo::default();
@@ -719,7 +742,7 @@ where
719742
fn trace_transaction(
720743
&self,
721744
opts: &GethDebugTracingOptions,
722-
evm_env: EvmEnvFor<Eth::Evm>,
745+
mut evm_env: EvmEnvFor<Eth::Evm>,
723746
tx_env: TxEnvFor<Eth::Evm>,
724747
db: &mut StateCacheDb<'_>,
725748
transaction_context: Option<TransactionContext>,
@@ -744,6 +767,7 @@ where
744767
GethDebugTracerType::BuiltInTracer(tracer) => match tracer {
745768
GethDebugBuiltInTracerType::FourByteTracer => {
746769
let mut inspector = FourByteInspector::default();
770+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
747771
let res = self.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?;
748772
return Ok((FourByteFrame::from(&inspector).into(), res.state))
749773
}
@@ -759,6 +783,8 @@ where
759783
))
760784
});
761785

786+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
787+
762788
let gas_limit = tx_env.gas_limit();
763789
let res = self.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?;
764790

@@ -781,6 +807,9 @@ where
781807
TracingInspectorConfig::from_geth_prestate_config(&prestate_config),
782808
)
783809
});
810+
811+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
812+
784813
let gas_limit = tx_env.gas_limit();
785814
let res =
786815
self.eth_api().inspect(&mut *db, evm_env, tx_env, &mut inspector)?;
@@ -805,6 +834,8 @@ where
805834
let mut inspector = MuxInspector::try_from_config(mux_config)
806835
.map_err(Eth::Error::from_eth_err)?;
807836

837+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
838+
808839
let res =
809840
self.eth_api().inspect(&mut *db, evm_env, tx_env, &mut inspector)?;
810841
let frame = inspector
@@ -822,6 +853,8 @@ where
822853
TracingInspectorConfig::from_flat_call_config(&flat_call_config),
823854
);
824855

856+
Self::handle_bsc_system_transaction(&mut evm_env, &tx_env);
857+
825858
let gas_limit = tx_env.gas_limit();
826859
let res = self.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?;
827860
let frame: FlatCallFrame = inspector

0 commit comments

Comments
 (0)