Skip to content
You are reading Hyperledger Besu development version documentation and some displayed features may not be available in the stable release. You can switch to stable version using the version box at screen bottom.
Date of last update: August 8, 2022

Use the Engine API

After The Merge, consensus and execution clients communicate with each other using the Engine API. These API methods are a separate subsection of the JSON-RPC API.

Configure the Engine API

To configure the Engine API:

Example Engine API configuration

besu --rpc-http-enabled --engine-rpc-port=8551 --engine-host-allowlist=localhost,127.0.0.1 --engine-jwt-secret=jwt.hex

Service ports

To specify the port the Engine API service listens on for HTTP and WebSocket, use the --engine-rpc-port option. The default is 8551.

Host allowlist

To prevent DNS rebinding attacks, Besu checks incoming HTTP request host headers, WebSocket connections, and GraphQL requests. Besu accepts requests only when hostnames specified using the --engine-host-allowlist option matches the request host headers. By default, Besu accepts requests and connections from localhost and 127.0.0.1.

Important

This isn’t a permissioning feature. If you want to restrict access to the Engine API, we recommend using authentication.

If your application publishes RPC ports, specify the hostnames when starting Besu.

Specify “*” for --engine-host-allowlist to effectively disable host protection.

Caution

Specifying “*” for --engine-host-allowlist is not recommended for production code.

Authentication

By default, authentication for the Engine API is enabled. To disable, set the --engine-jwt-disabled option to true.

Warning

Don’t disable JWT authentication in production environments. Disable only for testing purposes.

Set the JWT secret by using the --engine-jwt-secret option.

Send a payload using the Engine API

1. Prepare a payload

Prepare to send a payload using engine_forkchoiceUpdatedV1.

Example

curl -X POST --data '{"jsonrpc":"2.0","method":"engine_forkchoiceUpdatedV1","params":[{"headBlockHash": "0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a", "safeBlockHash": "0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a", "finalizedBlockHash": "0x0000000000000000000000000000000000000000000000000000000000000000"},{"timestamp": "0x5","prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000","suggestedFeeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"}],"id":67}' http://127.0.0.1:8550
{
    "jsonrpc": "2.0",
    "id": 67,
    "result": {
      "payloadStatus": {
        "status": "VALID",
        "latestValidHash": "0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a",
        "validationError": null
    },
    "payloadId": "0x0000000021f32cc1"
  }
}

2. Get the payload

Get the payload using engine_getPayloadV1

Example

curl -X POST --data '{"jsonrpc":"2.0","method":"engine_getPayloadV1","params":["0x1"],"id":1}' http://127.0.0.1:8550
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "parentHash": "0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a",
      "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
      "stateRoot": "0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45",
      "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
      "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
      "blockNumber": "0x1",
      "gasLimit": "0x1c9c380",
      "gasUsed": "0x0",
      "timestamp": "0x5",
      "extraData": "0x",
      "baseFeePerGas": "0x7",
      "blockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858",
      "transactions": []
    }
}

3. Execute the payload

Execute the payload using engine_newPayloadV1

Example

curl -X POST --data '{"jsonrpc":"2.0","method":"engine_newPayloadV1","params":[
  {
    "parentHash": "0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a",
    "feeRecipient": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b",
    "stateRoot": "0xca3149fa9e37db08d1cd49c9061db1002ef1cd58db2210f2115c8c989b2bdf45",
    "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
    "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "blockNumber": "0x1",
    "gasLimit": "0x1c9c380",
    "gasUsed": "0x0",
    "timestamp": "0x5",
    "extraData": "0x",
    "baseFeePerGas": "0x7",
    "blockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858",
    "transactions": []
  }
],"id":67}' http://127.0.0.1:8550
{
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
      "status": "VALID",
      "latestValidHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858",
      "validationError": null
    }
}

4. Update the fork choice

Update the fork choice using engine_forkchoiceUpdatedV1 again.

Example

curl -X POST --data '{"jsonrpc":"2.0","method":"engine_forkchoiceUpdatedV1","params":[{"headBlockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", "safeBlockHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858", "finalizedBlockHash": "0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a"},null],"id":67}' http://127.0.0.1:8550
{
    "jsonrpc": "2.0",
    "id": 67,
    "result": {
      "payloadStatus": {
        "status": "VALID",
        "latestValidHash": "0x3559e851470f6e7bbed1db474980683e8c315bfce99b2a6ef47c057c04de7858",
        "validationError": null
    },
    "payloadId": null
  }
}