Docs
Docs
Home
Getting Started
Agent Tooling
CLI
Supported Chains
Acala
Aptos
Arbitrum
Arc
Asset Hub
Astar
Avalanche
Base
Berachain
Bifrost
Binance Smart Chain
Bittensor
Blast
Boba Network
Bridge Hub
Celo
Centrifuge
Chiliz
Cronos
Enjin
Ethereum
Etherlink
Flow EVM Gateway
Gnosis
Hydration
Hyperliquid
Immutable
Ink
IoTeX
Kusama
Linea
LISK
Manta Atlantic
Manta Pacific
Mantle
MegaETH
Monad
Movement
Neuroweb
opBNB
Optimism
Plasma
Polkadot
Polygon
Pulsechain
Robinhood
Ronin
Scroll
Sonic
Starknet
Taiko
Tempo
Sui
TRON
Unichain
Viction
World Chain
XDC Network
XX Network
Zetachain
zkSync Era
Zora
Supported ChainsPlasmaJSON-RPC APIDebug Methods

debug_traceBlock - Plasma RPC Method

Trace all transactions in a block on Plasma using a serialized block payload. Essential for block-level debugging, gas profiling, and MEV analysis.

Plasma RPC endpoint: endpoint URLs, plans and pricing.

Traces all transactions in a block on Plasma by accepting a serialized block payload. Returns detailed execution traces for every transaction in the block, including opcode-level steps, gas consumption, and internal calls.

Why Plasma? Build on an EVM Layer 1 for stablecoin payments with PlasmaBFT consensus and Reth execution with 1 second blocks, XPL gas, full EVM JSON-RPC, and debug plus txpool on Dwellir.

Archive Node Required

This method requires an archive node with debug APIs enabled. Standard full nodes prune the historical state needed for transaction tracing. Dwellir provides archive node access for Plasma - ensure your plan includes debug namespace support.

When to Use This Method

debug_traceBlock is valuable for payment app developers, wallet teams, and teams shipping Solidity contracts for dollar transfers:

  • Block-Level Debugging - Trace every transaction in a block simultaneously when you have the serialized block payload, useful for offline analysis or replaying captured block data
  • Gas Profiling Across Transactions - Measure gas consumption per opcode across all transactions in a block to identify expensive patterns on Plasma
  • MEV Analysis - Analyze transaction ordering, sandwich attacks, and arbitrage patterns by tracing full block execution for stablecoin transfers, payment apps, and wallets that need 1 second confirmation
  • Protocol Research - Replay historical blocks from RLP data to study state transitions and EVM behavior

Best Practices

  • Requires archive node access; not available on standard full nodes
  • Block traces can be very resource-intensive on densely packed blocks
  • Consider tracing individual transactions instead for targeted analysis
  • Prefer debug_traceBlockByNumber or debug_traceBlockByHash for simpler workflows
JSON-RPC request
{
  "jsonrpc": "2.0",
  "method": "debug_traceBlock",
  "params": [
    "0xf90217a0...SERIALIZED_BLOCK_PAYLOAD",
    {
      "tracer": "callTracer"
    }
  ],
  "id": 1
}

Code Examples

Bash
curl -X POST https://api-plasma-mainnet.n.dwellir.com/YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "debug_traceBlock",
    "params": [
      "0xf90217a0...SERIALIZED_BLOCK_PAYLOAD",
      {"tracer": "callTracer"}
    ],
    "id": 1
  }'

Common Use Cases

1. Block-Level Gas Profiling

Analyze gas consumption across all transactions in a block on Plasma:

JavaScript
async function profileBlockGas(provider, blockRlp) {
  const traces = await provider.send('debug_traceBlock', [
    blockRlp,
    { tracer: 'callTracer' }
  ]);

  let totalGas = 0;
  const txGas = [];

  for (const trace of traces) {
    const gasUsed = parseInt(trace.result.gasUsed, 16);
    totalGas += gasUsed;
    txGas.push({
      txHash: trace.txHash,
      gasUsed,
      type: trace.result.type,
      hasSubCalls: (trace.result.calls || []).length > 0
    });
  }

  // Sort by gas usage
  txGas.sort((a, b) => b.gasUsed - a.gasUsed);

  console.log(`Block total gas: ${totalGas}`);
  console.log('Top gas consumers:');
  for (const tx of txGas.slice(0, 5)) {
    const pct = ((tx.gasUsed / totalGas) * 100).toFixed(1);
    console.log(`  ${tx.txHash}: ${tx.gasUsed} gas (${pct}%)`);
  }

  return { totalGas, txGas };
}

2. MEV Detection and Analysis

Detect sandwich attacks and arbitrage in Plasma blocks:

JavaScript
async function detectMEVPatterns(provider, blockRlp) {
  const traces = await provider.send('debug_traceBlock', [
    blockRlp,
    { tracer: 'callTracer' }
  ]);

  const dexInteractions = [];

  for (let i = 0; i < traces.length; i++) {
    const trace = traces[i];
    const calls = flattenCalls(trace.result);

    for (const call of calls) {
      // Detect swap-like function selectors (e.g., Uniswap swapExactTokensForTokens)
      if (call.input && call.input.startsWith('0x38ed1739')) {
        dexInteractions.push({
          index: i,
          txHash: trace.txHash,
          to: call.to,
          type: 'swap'
        });
      }
    }
  }

  // Check for sandwich patterns (swap-X-swap by same sender)
  for (let i = 0; i < dexInteractions.length - 2; i++) {
    const first = dexInteractions[i];
    const last = dexInteractions[i + 2];
    if (first.txHash !== last.txHash &&
        traces[first.index].result.from === traces[last.index].result.from) {
      console.log(`Potential sandwich: tx ${first.index} and ${last.index}`);
    }
  }

  return dexInteractions;
}

function flattenCalls(trace) {
  const calls = [trace];
  for (const sub of trace.calls || []) {
    calls.push(...flattenCalls(sub));
  }
  return calls;
}

3. Comparing Block Execution Across Clients

Verify consistent execution by tracing the same block RLP on different clients:

Python
import requests

def trace_on_endpoint(endpoint, block_rlp):
    response = requests.post(endpoint, json={
        'jsonrpc': '2.0',
        'method': 'debug_traceBlock',
        'params': [block_rlp, {'tracer': 'callTracer'}],
        'id': 1
    })
    return response.json()['result']

# Compare traces from two different endpoints
block_rlp = '0xf90217a0...'
traces_a = trace_on_endpoint('https://api-plasma-mainnet.n.dwellir.com/YOUR_API_KEY', block_rlp)
traces_b = trace_on_endpoint('https://other-endpoint.example.com', block_rlp)

# Verify same number of traces
assert len(traces_a) == len(traces_b), 'Transaction count mismatch'

# Compare gas usage per transaction
for i, (a, b) in enumerate(zip(traces_a, traces_b)):
    gas_a = int(a['result']['gasUsed'], 16)
    gas_b = int(b['result']['gasUsed'], 16)
    if gas_a != gas_b:
        print(f'Gas mismatch at tx {i}: {gas_a} vs {gas_b}')
    else:
        print(f'Tx {i}: {gas_a} gas (consistent)')

Error Handling

Common errors and solutions:

Error CodeDescriptionSolution
-32000Invalid RLP dataVerify the block RLP encoding is correct and complete
-32000Missing trie nodeNode is not an archive node or state has been pruned - use an archive endpoint
-32601Method not foundDebug namespace is not enabled on the node
-32603Internal errorBlock may be too large to trace - try increasing timeout or use disableStorage
-32005Rate limit exceededReduce request frequency or upgrade your plan
-32002Resource not foundThe block data could not be resolved - check the RLP encoding
JavaScript
async function safeTraceBlock(provider, blockRlp, options = {}) {
  const defaultOptions = {
    tracer: 'callTracer',
    timeout: '60s',
    ...options
  };

  try {
    return await provider.send('debug_traceBlock', [blockRlp, defaultOptions]);
  } catch (error) {
    if (error.code === -32601) {
      throw new Error('debug_traceBlock not available - ensure archive node with debug API');
    }
    if (error.message?.includes('timeout')) {
      console.warn('Trace timed out - retrying with reduced detail');
      return await provider.send('debug_traceBlock', [
        blockRlp,
        { ...defaultOptions, disableStorage: true, disableStack: true }
      ]);
    }
    throw error;
  }
}

Related Methods

  • debug_traceBlockByHash - Trace all transactions in a block by hash (more commonly used)
  • debug_traceBlockByNumber - Trace all transactions in a block by number
  • debug_traceTransaction - Trace a single transaction by hash
  • debug_traceCall - Trace a call without creating a transaction

eth_newPendingTransactionFilter

Create a filter for pending transaction notifications on Plasma. Essential for mempool monitoring, transaction tracking, and MEV opportunity detection for stablecoin transfers, payment apps, and wallets that need 1 second confirmation.

debug_traceBlockByHash

Trace all transactions in a block by hash on Plasma. Investigate specific blocks, analyze execution order, and debug reverts with detailed traces.

On this page

When to Use This MethodBest PracticesCode ExamplesCommon Use Cases1. Block-Level Gas Profiling2. MEV Detection and Analysis3. Comparing Block Execution Across ClientsError HandlingRelated Methods