Skip to content

Latest commit

 

History

History
107 lines (74 loc) · 3.2 KB

File metadata and controls

107 lines (74 loc) · 3.2 KB

Reference Test Execution and Tracing Guide

This document explains how to run Ethereum reference tests in Besu and how to enable JSON tracing during test and block execution. This is useful for debugging EVM behavior, inspecting opcode execution, and verifying correctness against official test vectors.

Running the Reference Tests

To run the Ethereum reference tests included in the Besu codebase, use the following Gradle task:

./gradlew referenceTests

This will execute the available test suites (such as GeneralStateTests) and validate Besu's EVM behavior.

Note:

  • Out-of-memory (OOM) errors are common due to the size and number of tests. You may need to increase the heap size using -Xmx (e.g., ./gradlew referenceTests -Dorg.gradle.jvmargs="-Xmx8g")

Enabling JSON Tracing

Besu supports detailed opcode-level JSON tracing. You can enable it using either a JVM system property or an environment variable.

Option 1: JVM System Property

-Dbesu.debug.traceBlocks=true

Option 2: Environment Variable

export BESU_TRACE_BLOCKS=true

This enables a fallback implementation of BlockAwareOperationTracer if no plugin is configured. The default tracer used is BlockAwareJsonTracer.

JSON trace output does not appear in the console. To view it, open the associated Gradle test report (usually located in build/reports/tests/test/index.html) and find the specific test case output.

Trace Contents

When enabled, tracing includes:

  • Opcode execution and names
  • Stack state
  • Gas remaining and gas cost
  • Memory size
  • Precompile execution
  • Contract creation and call frames
  • Transaction lifecycle events (start, prepare, end)
  • Exceptional halts

Each traced operation emits structured JSON data representing the EVM state at that point.

Output Format

The tracer prints a complete JSON trace of each block’s execution to standard output at the end of the block:

==== JSON Trace for Block <BLOCK_NUMBER> (<BLOCK_HASH>) ====
<trace entries>

Example:

{
  "pc": 0,
  "op": "0x60",
  "opName": "PUSH1",
  "gas": 999999,
  "gasCost": 3,
  "stack": [],
  "memSize": 0,
  "depth": 1,
  "refund": 0
}

Tracer Implementation

The tracer is implemented in:

org.hyperledger.besu.ethereum.mainnet.BlockAwareJsonTracer

It uses a StringWriter and a StandardJsonTracer to collect and format execution traces. Output is flushed during the traceEndBlock(...) callback.

The BlockAwareJsonTracer is enabled automatically when no plugin provides a custom tracer and one of the tracing flags is set:

if (Boolean.getBoolean("besu.debug.traceBlocks")
    || "true".equalsIgnoreCase(System.getenv("BESU_TRACE_BLOCKS"))) {
  return new BlockAwareJsonTracer();
}

Notes

  • Tracing is for debugging purposes only and should not be enabled in production environments.
  • Trace output can become large, especially for blocks with many transactions.
  • Tracing does not affect EVM execution semantics.

Resources