Simulating Bundles via RPC
The Signet node provides an RPC endpoint for simulating signet bundles, and uses flashbots-style bundles with an additional field. You will need a fully synced Signet node with the eth namespace enabled, which will in turn automatically enable the signet namespace as well.
The SignetBundle in JSON
SignetBundle in JSONThe JSON-RPC representation will look like this:
{
"jsonrpc": "2.0",
"id": 1,
"method": "signet_simBundle",
"params": [
{
txs, // Array[String], A list of signed transactions to execute in an atomic bundle
blockNumber, // String, a hex encoded block number for which this bundle is valid on
stateBlockNumber, // String, either a hex encoded number or a block tag for which state to base this simulation on. Can use "latest"
timestamp, // (Optional) Number, the timestamp to use for this bundle simulation, in seconds since the unix epoch
gas_limit, // (Optional) Number, the gas limit of the block to use for this simulation.
difficulty, // (Optional) U256, the difficulty of the block to use for this simulation.
base_fee, // (Optional) Number, basefee of the block to use for this simulation.
host_fills, // Map<Address, Map<Address, Number>>, Host fills to be applied to the bundle for simulation.
}
]
}Alloy already contains implementations for flashbots bundles. Signet just adds the host_fills field.
Simulating a bundle with "signet_simBundle"
"signet_simBundle"POST RPC method signet_simBundle
This signet node endpoint takes in a SignetCallBundle (as illustrated in the example JSON-RPC above) and returns the results of the simulation. This endpoint works exactly like flashbots's eth_callBundle
Response
{
"jsonrpc": "2.0",
"id": "123",
"result": {
"bundleGasPrice": "476190476193",
"bundleHash": "0x73b1e258c7a42fd0230b2fd05529c5d4b6fcb66c227783f8bece8aeacdd1db2e",
"coinbaseDiff": "20000000000126000",
"ethSentToCoinbase": "20000000000000000",
"gasFees": "126000",
"results": [
{
"coinbaseDiff": "10000000000063000",
"ethSentToCoinbase": "10000000000000000",
"fromAddress": "0x02A727155aeF8609c9f7F2179b2a1f560B39F5A0",
"gasFees": "63000",
"gasPrice": "476190476193",
"gasUsed": 21000,
"toAddress": "0x73625f59CAdc5009Cb458B751b3E7b6b48C06f2C",
"txHash": "0x669b4704a7d993a946cdd6e2f95233f308ce0c4649d2e04944e8299efcaa098a",
"value": "0x"
},
{
"coinbaseDiff": "10000000000063000",
"ethSentToCoinbase": "10000000000000000",
"fromAddress": "0x02A727155aeF8609c9f7F2179b2a1f560B39F5A0",
"gasFees": "63000",
"gasPrice": "476190476193",
"gasUsed": 21000,
"toAddress": "0x73625f59CAdc5009Cb458B751b3E7b6b48C06f2C",
"txHash": "0xa839ee83465657cac01adc1d50d96c1b586ed498120a84a64749c0034b4f19fa",
"value": "0x"
}
],
"stateBlockNumber": 5221585,
"totalGasUsed": 42000
}
}Calculating the bundleHash
bundleHashFlashbots bundle hashes are calculated as keccak256(tx1 || tx2 || ... || txN), where txN is the transaction hash of the N transaction in the bundle. Signet bundles must also commit to the host fills, otherwise bundles with different host fills would evaluate to the same hash.
For Signet bundles, we need to include both the flashbots bundle hash (tx_preimage), and a hash for the fills (host_preimage). As a result, the Signet bundle hash is calculated as keccak256(tx_preimage || host_preimage).
The host_preimage is calculated by sorting the asset map and each asset submap. Then serialzied as follows: keccak(NUM_OF_ASSETS_LE_U256 + asset1 + NUM_OF_FILLS_LE_U256 + asset1_user1 + asset1_amount_le1 + ... + asset1_usern + asset1_amount_len + ...).
Last updated