From 08205f27335927bb53cf4e569cbed13e0d95e76f Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 21 Oct 2025 14:48:15 -0600 Subject: [PATCH 01/14] docs: update README with Flashbots architecture changes --- README.md | 63 ++++++++++++++++++------------------------------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 5f7cf29..6566a6e 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,9 @@ The Builder orchestrates a series of asynchronous actors that work together to b 1. **Env** - watches the latest host and rollup blocks to monitor gas rates and block updates. 2. **Cache** - polls bundle and transaction caches and adds them to the cache. 3. **Simulator** - simulates transactions and bundles against rollup state and block environment to build them into a cohesive block. -5. **Submit** - creates a blob transaction from the built block and sends it to Ethereum L1. +5. **Submit** - creates a blob transaction from the built block and sends it to the configured submit task. + 1. Flashbots - builds a Flashbots bundle out of the Signet block which contains Signet transactions, host transactions, and host fills, and submits it to the configured Flashbots endpoint. + 2. Builder Helper - builds a transaction call with the builder helper contract and submits that as a transaction. 6. **Metrics** - records block and tx data over time. ```mermaid @@ -30,6 +32,7 @@ flowchart TD MetricsTaskActor["šŸ“ Metrics Task"] SubmitTaskActor["šŸ“” Submit Task "] SimulatorTaskActor["šŸ’¾ Simulator Task"] + Submitter["šŸ“¤ Submitter"] Quincey["šŸ–Šļø Quincey"] SubmitTaskActor -.block hash.-> Quincey @@ -39,6 +42,7 @@ flowchart TD %% ────────────── CONNECTIONS & DATA FLOW ────────────── A2_BuilderConfig -.host_provider.-> MetricsTaskActor A2_BuilderConfig -.host_provider.->SubmitTaskActor + A2_BuilderConfig -.host_provider.-> SimulatorTaskActor A2_BuilderConfig -.ru_provider.-> SimulatorTaskActor A2_BuilderConfig -.ru_provider.-> EnvTaskActor @@ -47,21 +51,32 @@ flowchart TD EnvTaskActor ==block_env==> SimulatorTaskActor CacheSystem ==sim_cache ==> SimulatorTaskActor + SubmitTaskActor ==tx receipt==> MetricsTaskActor SimulatorTaskActor ==built block==> SubmitTaskActor - SubmitTaskActor ==>|"signet block (blob tx)"| C1["ā›“ļø Ethereum L1"] + SubmitTaskActor ==signet_block==> Submitter + Submitter ==>|"signet block"| C2["āš”šŸ¤– Flashbots"] + Submitter ==>|"signet block"| C1["ā›“ļø Ethereum L1"] ``` -The block building loop waits until a new block has been received, and then kicks off the next attempt. +### Simulation Task + +The block building loop waits until a new block environment has been received, and then kicks off the next attempt. When the Builder receives a new block, it takes a reference to the transaction cache, calculates a simulation deadline for the current slot with a buffer of 1.5 seconds, and begins constructing a block for the current slot. Transactions enter through the cache, and then they're sent to the simulator, where they're run against the latest chain state and block environment. If they're successfully applied, they're added to the block. If a transaction fails to be applied, it is simply ignored. -When the deadline is reached, the simulator is stopped, and all open simulation threads and cancelled. The block is then bundled with the block environment and the previous host header that it was simulated against, and passes all three along to the submit task. +When the deadline is reached, the simulator is stopped, and all open simulation threads are cancelled. The built block is then bundled with the block environment and the previous host header that it was simulated against, and all three are passed along to the submit task. + +### Submit Task + +If Flashbots endpoint has been configured the Flashbots submit task will prepare a Flashbots bundle out of that Signet block, and then submits that bundle to the Flashbots endpoint. + +If a Flashbots endpoint has _not_ been configured, the Builder will create a raw contract call and submits the transaction to the default mempool. This is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. -If no transactions in the cache are valid and the resulting block is empty, the submit task will ignore it. +If the block received from simulation is empty, the submit task will ignore it. Finally, if it's non-empty, the submit task attempts to get a signature for the block, and if it fails due to a 403 error, it will skip the current slot and begin waiting for the next block. @@ -140,44 +155,6 @@ If it fails, it will retry up to 3 times with a 12.5% bump on each retry. The previous header's basefee is tracked through the build loop and used for gas estimation purposes in the Submit Task. ---- - -## šŸ“¤ Transaction Sender - -A binary (`bin/submit_transaction.rs`) for continously sending very small transactions for testing block construction. - -The following values are available for configuring the transaction sender: - -| Key | Required | Description | -| ------------------- | -------- | --------------------------------------------- | -| `RPC_URL` | Yes | RPC endpoint used for sending the transaction | -| `RECIPIENT_ADDRESS` | Yes | Address to which the transaction is sent | -| `SLEEP_TIME` | Yes | Optional delay (in ms) between transactions | -| `SIGNER_CHAIN_ID` | Yes | Chain ID used for signing | -| `SIGNER_KEY` | Yes | Signing key used to sign the transaction | - -The transaction submitter is located at `bin/submit_transaction.rs`. - -Run the transaction submitter with `cargo run --bin transaction-submitter` - ---- - -## šŸ“¤ Order Submitter - -A binary (`bin/submit_order.rs`) for continuously sending small example orders for testing block construction with fills. - -The following values need to be configured: - -| Key | Required | Description | -| ----------------- | -------- | -------------------------------------------------------------- | -| `RPC_URL` | Yes | RPC endpoint used for sending the transaction | -| `SEND_TO_ROLLUP` | Yes | Whether to make a rollup order (RU-RU) or host order (RU-HOST) | -| `SLEEP_TIME` | Yes | Optional delay (in ms) between transactions | -| `SIGNER_CHAIN_ID` | Yes | Chain ID used for signing | -| `SIGNER_KEY` | Yes | Signing key used to sign the transaction | - -Run the order submitter with `cargo run --bin order-submitter` - ## šŸ› ļø Development ### Requirements From 7576fc31311c79a165cee1bea6193a4c9f850dcc Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 21 Oct 2025 16:15:15 -0600 Subject: [PATCH 02/14] docs: clarify submit task and add Flashbots path to architecture diagram --- CHANGELOG.md | 5 +++ README.md | 113 +++++++++++++++++++++++++++------------------------ 2 files changed, 64 insertions(+), 54 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3b35866 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## Unreleased + +- docs: update architecture diagram and Submit Task description to show optional Flashbots bundle submission path and clarify Builder Helper (L1) flow. diff --git a/README.md b/README.md index 6566a6e..99462f8 100644 --- a/README.md +++ b/README.md @@ -8,77 +8,82 @@ Bundles are treated as Flashbots-style bundles, meaning that the Builder should ## šŸš€ System Design -The Builder orchestrates a series of asynchronous actors that work together to build blocks for every assigned slot. +The Builder orchestrates a set of asynchronous actors that collaborate to build and submit Signet rollup blocks for every assigned slot. The core components are: -1. **Env** - watches the latest host and rollup blocks to monitor gas rates and block updates. -2. **Cache** - polls bundle and transaction caches and adds them to the cache. -3. **Simulator** - simulates transactions and bundles against rollup state and block environment to build them into a cohesive block. -5. **Submit** - creates a blob transaction from the built block and sends it to the configured submit task. - 1. Flashbots - builds a Flashbots bundle out of the Signet block which contains Signet transactions, host transactions, and host fills, and submits it to the configured Flashbots endpoint. - 2. Builder Helper - builds a transaction call with the builder helper contract and submits that as a transaction. -6. **Metrics** - records block and tx data over time. +1. **Env** — watches host and rollup chain headers and maintains the block environment used for simulation. +2. **Cache** — ingests transactions and bundles from configured sources and exposes a simulation view. +3. **Simulator** — applies transactions and bundles against the rollup state and block environment to assemble a candidate Signet block. +4. **Submit** — takes a successfully built block and routes it to the configured submission path (either a private MEV bundle relay or direct L1 broadcast via the builder helper). +5. **Metrics** — records runtime metrics, submit receipts, and block statistics. + +Below is a high-level architecture diagram that shows both submission options: direct L1 submission (Builder Helper) and private MEV bundle submission (Flashbots relay). ```mermaid -%%{ init : { "theme" : "dark" } }%% +%%{ init : { "theme" : "dark", "flowchart": {"curve":"basis"} } }%% flowchart TD - %% ────────────── INITIALIZATION ────────────── - A0(["Start main"]) --> A1[Init tracing & logging] - A1 --> A2_BuilderConfig[Load BuilderConfig from env] - - %% ────────────── CORE TASK SPAWNS ────────────── - subgraph Tasks_Spawned["Spawned Actors"] - EnvTaskActor["šŸ”¢ Env Task"] ==block_env==> CacheSystem - CacheSystem["šŸŖ Cache System"] - MetricsTaskActor["šŸ“ Metrics Task"] - SubmitTaskActor["šŸ“” Submit Task "] - SimulatorTaskActor["šŸ’¾ Simulator Task"] - Submitter["šŸ“¤ Submitter"] - Quincey["šŸ–Šļø Quincey"] - - SubmitTaskActor -.block hash.-> Quincey - Quincey -.block signature.-> SubmitTaskActor + %% Initialization + start(["Start main"]) --> init["Init tracing & logging"] + init --> cfg["Load BuilderConfig from env"] + + %% Spawned actors + subgraph Actors["Spawned Actors"] + Env["šŸ”¢ Env Task"] + Cache["šŸŖ Cache System"] + Simulator["ļæ½ Simulator Task"] + SubmitBH["šŸ“” Submit Task (BuilderHelper)"] + SubmitFB["ļæ½ļø Submit Task (Flashbots)"] + Metrics["šŸ“ Metrics Task"] + Quincey["šŸ–Šļø Quincey (Signer)"] end - %% ────────────── CONNECTIONS & DATA FLOW ────────────── - A2_BuilderConfig -.host_provider.-> MetricsTaskActor - A2_BuilderConfig -.host_provider.->SubmitTaskActor - A2_BuilderConfig -.host_provider.-> SimulatorTaskActor - A2_BuilderConfig -.ru_provider.-> SimulatorTaskActor - A2_BuilderConfig -.ru_provider.-> EnvTaskActor - - A3["šŸ“„ Transactions & - šŸ“¦ Bundles"] --> CacheSystem - - EnvTaskActor ==block_env==> SimulatorTaskActor - CacheSystem ==sim_cache ==> SimulatorTaskActor - - SubmitTaskActor ==tx receipt==> MetricsTaskActor - SimulatorTaskActor ==built block==> SubmitTaskActor - - SubmitTaskActor ==signet_block==> Submitter - Submitter ==>|"signet block"| C2["āš”šŸ¤– Flashbots"] - Submitter ==>|"signet block"| C1["ā›“ļø Ethereum L1"] + %% Config wiring + cfg -.-> Metrics + cfg -.-> SubmitBH + cfg -.-> Simulator + cfg -.-> Env + cfg -. "flashbots_endpoint" -> SubmitFB + + %% Data flow + inbound["šŸ“„ Transactions & Bundles"] --> Cache + Env ==block_env==> Simulator + Cache ==sim_cache==> Simulator + Simulator ==built_block==> SubmitBH + Simulator ==built_block==> SubmitFB + + SubmitBH ==tx_receipt==> Metrics + SubmitFB ==bundle_receipt==> Metrics + + %% Signing interactions + SubmitBH -.block_hash.-> Quincey + Quincey -.block_signature.-> SubmitBH + SubmitFB -.bundle_hash.-> Quincey + Quincey -.bundle_signature.-> SubmitFB + + %% External targets + SubmitBH -->|"signet block (blob tx)"| L1["ā›“ļø Ethereum L1"] + SubmitFB -->|"MEV bundle"| Relay["šŸ›”ļø Flashbots Relay"] + + classDef ext fill:#111,stroke:#bbb,color:#fff; + class L1,Relay ext ``` ### Simulation Task -The block building loop waits until a new block environment has been received, and then kicks off the next attempt. - -When the Builder receives a new block, it takes a reference to the transaction cache, calculates a simulation deadline for the current slot with a buffer of 1.5 seconds, and begins constructing a block for the current slot. +The simulation loop waits for a new block environment from the host chain, then starts a simulation window for the current slot. The Builder takes a reference to the transaction cache and computes a deadline (default: slot end minus 1.5s buffer) to stop simulating and finalize the block. -Transactions enter through the cache, and then they're sent to the simulator, where they're run against the latest chain state and block environment. If they're successfully applied, they're added to the block. If a transaction fails to be applied, it is simply ignored. - -When the deadline is reached, the simulator is stopped, and all open simulation threads are cancelled. The built block is then bundled with the block environment and the previous host header that it was simulated against, and all three are passed along to the submit task. +Transactions flow from the cache into the simulator. Applied transactions are kept and assembled into the candidate block; failing transactions are ignored. When the simulation deadline arrives, the simulator cancels remaining work, captures the built block and the block environment it was simulated against, and forwards them to the Submit task. ### Submit Task -If Flashbots endpoint has been configured the Flashbots submit task will prepare a Flashbots bundle out of that Signet block, and then submits that bundle to the Flashbots endpoint. +The Submit task will route the built block to one of two paths, depending on configuration: + +- Flashbots (private MEV relay): when `FLASHBOTS_ENDPOINT` is configured, the Submit task prepares an MEV-style bundle containing the Signet block (plus any host transactions/fills as needed) and submits it to the configured relay. The builder expects a bundle hash in the response and records it in metrics. -If a Flashbots endpoint has _not_ been configured, the Builder will create a raw contract call and submits the transaction to the default mempool. This is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. +- Builder Helper (direct L1 broadcast): when no Flashbots endpoint is configured, the Submit task composes a builder-helper contract call and broadcasts it to the mempool as a normal transaction. This path is intended for testing and private deployments; broadcasting raw Signet block data publicly may leak sensitive information. -If the block received from simulation is empty, the submit task will ignore it. +If the simulated block is empty, the Submit task will drop it and continue. -Finally, if it's non-empty, the submit task attempts to get a signature for the block, and if it fails due to a 403 error, it will skip the current slot and begin waiting for the next block. +If the submit path requires a signature (Quincey), the submit task requests one; on an authorization failure (e.g. 403) the submit task will skip the slot and resume on the next. --- From 8643ec7894b4f3a9d8c19b87de843eb9b00b7df8 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 21 Oct 2025 16:17:27 -0600 Subject: [PATCH 03/14] docs(readme): fix mermaid diagram parse issues (emoji & arrow syntax) --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 99462f8..72b3f0a 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,9 @@ flowchart TD inbound["šŸ“„ Transactions & Bundles"] --> Cache Env ==block_env==> Simulator Cache ==sim_cache==> Simulator - Simulator ==built_block==> SubmitBH + Simulator["šŸ’¾ Simulator Task"] Simulator ==built_block==> SubmitFB - + SubmitFB["šŸ›”ļø Submit Task (Flashbots)"] SubmitBH ==tx_receipt==> Metrics SubmitFB ==bundle_receipt==> Metrics @@ -60,7 +60,7 @@ flowchart TD Quincey -.bundle_signature.-> SubmitFB %% External targets - SubmitBH -->|"signet block (blob tx)"| L1["ā›“ļø Ethereum L1"] + cfg -."flashbots_endpoint".-> SubmitFB SubmitFB -->|"MEV bundle"| Relay["šŸ›”ļø Flashbots Relay"] classDef ext fill:#111,stroke:#bbb,color:#fff; From d87f6fd8e0a2acfc750c39f83dcff2523eaccd86 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 21 Oct 2025 16:29:05 -0600 Subject: [PATCH 04/14] cleanup --- CHANGELOG.md | 5 -- README.md | 128 +++++++++++++++++++++++++++------------------------ 2 files changed, 67 insertions(+), 66 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 3b35866..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,5 +0,0 @@ -# Changelog - -## Unreleased - -- docs: update architecture diagram and Submit Task description to show optional Flashbots bundle submission path and clarify Builder Helper (L1) flow. diff --git a/README.md b/README.md index 72b3f0a..5f3d235 100644 --- a/README.md +++ b/README.md @@ -8,82 +8,88 @@ Bundles are treated as Flashbots-style bundles, meaning that the Builder should ## šŸš€ System Design -The Builder orchestrates a set of asynchronous actors that collaborate to build and submit Signet rollup blocks for every assigned slot. The core components are: +The Builder orchestrates a series of asynchronous actors that work together to build blocks for every assigned slot. -1. **Env** — watches host and rollup chain headers and maintains the block environment used for simulation. -2. **Cache** — ingests transactions and bundles from configured sources and exposes a simulation view. -3. **Simulator** — applies transactions and bundles against the rollup state and block environment to assemble a candidate Signet block. -4. **Submit** — takes a successfully built block and routes it to the configured submission path (either a private MEV bundle relay or direct L1 broadcast via the builder helper). -5. **Metrics** — records runtime metrics, submit receipts, and block statistics. - -Below is a high-level architecture diagram that shows both submission options: direct L1 submission (Builder Helper) and private MEV bundle submission (Flashbots relay). +1. **Env** - watches the latest host and rollup blocks to monitor gas rates and block updates. +2. **Cache** - polls bundle and transaction caches and adds them to the cache. +3. **Simulator** - simulates transactions and bundles against rollup state and block environment to build them into a cohesive block. +5. **Submit** - creates a blob transaction from the built block and sends it to the configured submit task. + 1. Flashbots - builds a Flashbots bundle out of the Signet block which contains Signet transactions, host transactions, and host fills, and submits it to the configured Flashbots endpoint. + 2. Builder Helper - builds a transaction call with the builder helper contract and submits that as a transaction. +6. **Metrics** - records block and tx data over time. ```mermaid -%%{ init : { "theme" : "dark", "flowchart": {"curve":"basis"} } }%% +%%{ init : { "theme" : "dark" } }%% flowchart TD - %% Initialization - start(["Start main"]) --> init["Init tracing & logging"] - init --> cfg["Load BuilderConfig from env"] - - %% Spawned actors - subgraph Actors["Spawned Actors"] - Env["šŸ”¢ Env Task"] - Cache["šŸŖ Cache System"] - Simulator["ļæ½ Simulator Task"] - SubmitBH["šŸ“” Submit Task (BuilderHelper)"] - SubmitFB["ļæ½ļø Submit Task (Flashbots)"] - Metrics["šŸ“ Metrics Task"] - Quincey["šŸ–Šļø Quincey (Signer)"] - end - - %% Config wiring - cfg -.-> Metrics - cfg -.-> SubmitBH - cfg -.-> Simulator - cfg -.-> Env - cfg -. "flashbots_endpoint" -> SubmitFB - - %% Data flow - inbound["šŸ“„ Transactions & Bundles"] --> Cache - Env ==block_env==> Simulator - Cache ==sim_cache==> Simulator - Simulator["šŸ’¾ Simulator Task"] - Simulator ==built_block==> SubmitFB - SubmitFB["šŸ›”ļø Submit Task (Flashbots)"] - SubmitBH ==tx_receipt==> Metrics - SubmitFB ==bundle_receipt==> Metrics - - %% Signing interactions - SubmitBH -.block_hash.-> Quincey - Quincey -.block_signature.-> SubmitBH - SubmitFB -.bundle_hash.-> Quincey - Quincey -.bundle_signature.-> SubmitFB - - %% External targets - cfg -."flashbots_endpoint".-> SubmitFB - SubmitFB -->|"MEV bundle"| Relay["šŸ›”ļø Flashbots Relay"] - - classDef ext fill:#111,stroke:#bbb,color:#fff; - class L1,Relay ext + %% ────────────── INITIALIZATION ────────────── + A0(["Start main"]) --> A1[Init tracing & logging] + A1 --> A2_BuilderConfig[Load BuilderConfig from env] + + A4_Quincey["šŸ–Šļø Quincey"] + + A3["šŸ“„ Transactions & + šŸ“¦ Bundles"] --> CacheTask + + %% ────────────── CORE TASK SPAWNS ────────────── + subgraph Tasks_Spawned["Spawned Actors"] + EnvTaskActor["šŸ”¢ Env Task"] ==block env==>CacheTask + CacheTask["šŸŖ Cache Task"] + MetricsTaskActor["šŸ“ Metrics Task"] + SubmitTaskActor["šŸ“” Submit Task "] + SimulatorTaskActor["šŸ’¾ Simulator Task"] + + %% ────────────── Transaction Preparation ────────────── + subgraph TxPrep["Transaction Prep"] + Bumpable["⛽ Bumpable Tx"] + end + end + + %% ────────────── CONNECTIONS & DATA FLOW ────────────── + A2_BuilderConfig -.host rpc.-> MetricsTaskActor + A2_BuilderConfig -.host rpc.->SubmitTaskActor + A2_BuilderConfig -.host rpc.-> SimulatorTaskActor + A2_BuilderConfig -.host rpc.-> TxPrep + A2_BuilderConfig -.rollup rpc.-> SimulatorTaskActor + A2_BuilderConfig -.rollup rpc.-> EnvTaskActor + + + SubmitTaskActor ==tx receipt==> MetricsTaskActor + SubmitTaskActor ==> TxPrep + + C2 == "tx bundle" ==> C1 + + TxPrep -.block hash.-> A4_Quincey + A4_Quincey -.block signature.-> TxPrep + + + EnvTaskActor ==block env==> SimulatorTaskActor + CacheTask ==sim cache ==> SimulatorTaskActor + SimulatorTaskActor ==built block==> SubmitTaskActor + + TxPrep ==>|"signet block"| C1["ā›“ļø Ethereum L1"] + TxPrep ==>|"signet block"| C2["āš”šŸ¤– Flashbots"] + ``` ### Simulation Task -The simulation loop waits for a new block environment from the host chain, then starts a simulation window for the current slot. The Builder takes a reference to the transaction cache and computes a deadline (default: slot end minus 1.5s buffer) to stop simulating and finalize the block. +The block building loop waits until a new block environment has been received, and then kicks off the next attempt. -Transactions flow from the cache into the simulator. Applied transactions are kept and assembled into the candidate block; failing transactions are ignored. When the simulation deadline arrives, the simulator cancels remaining work, captures the built block and the block environment it was simulated against, and forwards them to the Submit task. +When the Builder receives a new block, it takes a reference to the transaction cache, calculates a simulation deadline for the current slot with a buffer of 1.5 seconds, and begins constructing a block for the current slot. -### Submit Task +Transactions enter through the cache, and then they're sent to the simulator, where they're run against the latest chain state and block environment. If they're successfully applied, they're added to the block. If a transaction fails to be applied, it is simply ignored. -The Submit task will route the built block to one of two paths, depending on configuration: +When the deadline is reached, the simulator is stopped, and all open simulation threads are cancelled. The built block is then bundled with the block environment and the previous host header that it was simulated against, and all three are passed along to the submit task. + +### Submit Task -- Flashbots (private MEV relay): when `FLASHBOTS_ENDPOINT` is configured, the Submit task prepares an MEV-style bundle containing the Signet block (plus any host transactions/fills as needed) and submits it to the configured relay. The builder expects a bundle hash in the response and records it in metrics. +If Flashbots endpoint has been configured the Flashbots submit task will prepare a Flashbots bundle out of that Signet block, and then submits that bundle to the Flashbots endpoint. -- Builder Helper (direct L1 broadcast): when no Flashbots endpoint is configured, the Submit task composes a builder-helper contract call and broadcasts it to the mempool as a normal transaction. This path is intended for testing and private deployments; broadcasting raw Signet block data publicly may leak sensitive information. +If a Flashbots endpoint has _not_ been configured, the Builder will create a raw contract call and submits the transaction to the default mempool. This is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. -If the simulated block is empty, the Submit task will drop it and continue. +If the block received from simulation is empty, the submit task will ignore it. -If the submit path requires a signature (Quincey), the submit task requests one; on an authorization failure (e.g. 403) the submit task will skip the slot and resume on the next. +Finally, if it's non-empty, the submit task attempts to get a signature for the block, and if it fails due to a 403 error, it will skip the current slot and begin waiting for the next block. --- From 2c802e39f18c8bc4245131543ee71230359bff95 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 21 Oct 2025 17:01:05 -0600 Subject: [PATCH 05/14] docs(readme): clean up mermaid architecture diagram --- README.md | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 5f3d235..685a919 100644 --- a/README.md +++ b/README.md @@ -25,49 +25,47 @@ flowchart TD A0(["Start main"]) --> A1[Init tracing & logging] A1 --> A2_BuilderConfig[Load BuilderConfig from env] - A4_Quincey["šŸ–Šļø Quincey"] - - A3["šŸ“„ Transactions & - šŸ“¦ Bundles"] --> CacheTask + A3["šŸ“„ Transactions &\nšŸ“¦ Bundles"] --> B1_CacheTask %% ────────────── CORE TASK SPAWNS ────────────── - subgraph Tasks_Spawned["Spawned Actors"] - EnvTaskActor["šŸ”¢ Env Task"] ==block env==>CacheTask - CacheTask["šŸŖ Cache Task"] - MetricsTaskActor["šŸ“ Metrics Task"] - SubmitTaskActor["šŸ“” Submit Task "] - SimulatorTaskActor["šŸ’¾ Simulator Task"] - - %% ────────────── Transaction Preparation ────────────── - subgraph TxPrep["Transaction Prep"] - Bumpable["⛽ Bumpable Tx"] + subgraph Block_Builder_Loop["Block Building Loop"] + B0_EnvTaskActor["šŸ”¢ Env Task"] + B1_CacheTask["šŸŖ Cache Task"] + B2_MetricsTaskActor["šŸ“ Metrics Task"] + B4_SimulatorTaskActor["šŸ’¾ Simulator Task"] + + subgraph SubmitTask["Submit Task"] + B5_TxPrep["⛽ Bumpable Tx"] + B3_SubmitFlashbots["āš”šŸ¤– Submit Flashbots"] + B6_SubmitBuilderHelper["šŸ—ļø Submit Builder Helper"] end end %% ────────────── CONNECTIONS & DATA FLOW ────────────── - A2_BuilderConfig -.host rpc.-> MetricsTaskActor - A2_BuilderConfig -.host rpc.->SubmitTaskActor - A2_BuilderConfig -.host rpc.-> SimulatorTaskActor - A2_BuilderConfig -.host rpc.-> TxPrep - A2_BuilderConfig -.rollup rpc.-> SimulatorTaskActor - A2_BuilderConfig -.rollup rpc.-> EnvTaskActor + A2_BuilderConfig -.host_rpc.-> B2_MetricsTaskActor + A2_BuilderConfig -.host_rpc.-> B3_SubmitFlashbots + A2_BuilderConfig -.host_rpc.-> B6_SubmitBuilderHelper + A2_BuilderConfig -.rollup_rpc.-> B0_EnvTaskActor - - SubmitTaskActor ==tx receipt==> MetricsTaskActor - SubmitTaskActor ==> TxPrep - - C2 == "tx bundle" ==> C1 - - TxPrep -.block hash.-> A4_Quincey - A4_Quincey -.block signature.-> TxPrep + SubmitTask -- "host & rollup txns" --> B5_TxPrep - - EnvTaskActor ==block env==> SimulatorTaskActor - CacheTask ==sim cache ==> SimulatorTaskActor - SimulatorTaskActor ==built block==> SubmitTaskActor + B5_TxPrep --> B3_SubmitFlashbots + B5_TxPrep --> B6_SubmitBuilderHelper - TxPrep ==>|"signet block"| C1["ā›“ļø Ethereum L1"] - TxPrep ==>|"signet block"| C2["āš”šŸ¤– Flashbots"] + B0_EnvTaskActor ==block_env==> B4_SimulatorTaskActor + B1_CacheTask ==sim_cache==> B4_SimulatorTaskActor + B4_SimulatorTaskActor ==built_block==> B5_TxPrep + + B5_TxPrep -.block_hash.-> A4_Quincey + A4_Quincey -.block_signature.-> B5_TxPrep + + B3_SubmitFlashbots -->|"tx bundle"| C2_Flashbots["āš”šŸ¤– Flashbots"] + B6_SubmitBuilderHelper -->|"signet block (blob tx)"| C1_Ethereum["ā›“ļø Ethereum L1"] + + B3_SubmitFlashbots ==tx_receipt==> B2_MetricsTaskActor + B6_SubmitBuilderHelper ==tx_receipt==> B2_MetricsTaskActor + + A4_Quincey["šŸ–Šļø Quincey"] ``` From 115ba22a232c33811dae05f1c8c6bbe166555e9c Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 22 Oct 2025 12:00:10 -0600 Subject: [PATCH 06/14] docs(readme): polish mermaid architecture graph and add flashbots routing decision --- README.md | 90 +++++++++++++++++++++++++++---------------------------- 1 file changed, 44 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 685a919..9b0eee5 100644 --- a/README.md +++ b/README.md @@ -21,52 +21,50 @@ The Builder orchestrates a series of asynchronous actors that work together to b ```mermaid %%{ init : { "theme" : "dark" } }%% flowchart TD - %% ────────────── INITIALIZATION ────────────── - A0(["Start main"]) --> A1[Init tracing & logging] - A1 --> A2_BuilderConfig[Load BuilderConfig from env] - - A3["šŸ“„ Transactions &\nšŸ“¦ Bundles"] --> B1_CacheTask - - %% ────────────── CORE TASK SPAWNS ────────────── - subgraph Block_Builder_Loop["Block Building Loop"] - B0_EnvTaskActor["šŸ”¢ Env Task"] - B1_CacheTask["šŸŖ Cache Task"] - B2_MetricsTaskActor["šŸ“ Metrics Task"] - B4_SimulatorTaskActor["šŸ’¾ Simulator Task"] - - subgraph SubmitTask["Submit Task"] - B5_TxPrep["⛽ Bumpable Tx"] - B3_SubmitFlashbots["āš”šŸ¤– Submit Flashbots"] - B6_SubmitBuilderHelper["šŸ—ļø Submit Builder Helper"] - end - end - - %% ────────────── CONNECTIONS & DATA FLOW ────────────── - A2_BuilderConfig -.host_rpc.-> B2_MetricsTaskActor - A2_BuilderConfig -.host_rpc.-> B3_SubmitFlashbots - A2_BuilderConfig -.host_rpc.-> B6_SubmitBuilderHelper - A2_BuilderConfig -.rollup_rpc.-> B0_EnvTaskActor - - SubmitTask -- "host & rollup txns" --> B5_TxPrep - - B5_TxPrep --> B3_SubmitFlashbots - B5_TxPrep --> B6_SubmitBuilderHelper - - B0_EnvTaskActor ==block_env==> B4_SimulatorTaskActor - B1_CacheTask ==sim_cache==> B4_SimulatorTaskActor - B4_SimulatorTaskActor ==built_block==> B5_TxPrep - - B5_TxPrep -.block_hash.-> A4_Quincey - A4_Quincey -.block_signature.-> B5_TxPrep - - B3_SubmitFlashbots -->|"tx bundle"| C2_Flashbots["āš”šŸ¤– Flashbots"] - B6_SubmitBuilderHelper -->|"signet block (blob tx)"| C1_Ethereum["ā›“ļø Ethereum L1"] - - B3_SubmitFlashbots ==tx_receipt==> B2_MetricsTaskActor - B6_SubmitBuilderHelper ==tx_receipt==> B2_MetricsTaskActor - - A4_Quincey["šŸ–Šļø Quincey"] - + %% Initialization + Start(["Start main"]) --> Init["Init tracing & logging"] + Init --> Config["Load BuilderConfig from env"] + + Inbound["šŸ“„ Transactions &\nšŸ“¦ Bundles"] --> Cache["šŸŖ Cache Task"] + Quincey["šŸ–Šļø Quincey (Signer)"] + + %% Block building loop + subgraph BuilderLoop["Block Building Loop"] + Env["šŸ”¢ Env Task"] + Cache + Simulator["šŸ’¾ Simulator Task"] + TxPrep["⛽ Built Signet Block / Tx Prep"] + end + + %% Config wiring + Config -.rollup_rpc.-> Env + Config -.host_rpc.-> Simulator + Config -.host_rpc.-> Metrics["šŸ“ Metrics Task"] + + %% Core flow + Env ==block_env==> Simulator + Cache ==sim_cache==> Simulator + Simulator ==built_block==> TxPrep + + %% Signing + TxPrep -.block_hash.-> Quincey + Quincey -.block_signature.-> TxPrep + + %% Decision: route to Flashbots or Builder Helper + Decision{ "FLASHBOTS_ENDPOINT\nconfigured?" } + TxPrep --> Decision + Decision -->|Yes| FlashbotsSubmit["āš”šŸ¤– Flashbots Submit"] + Decision -->|No| HelperSubmit["šŸ—ļø Builder Helper Submit"] + + FlashbotsSubmit -->|"bundle"| FlashbotsRelay["šŸ›”ļø Flashbots Relay"] + HelperSubmit -->|"blob tx"| Ethereum["ā›“ļø Ethereum L1"] + + %% Metrics + FlashbotsSubmit ==tx_receipt==> Metrics + HelperSubmit ==tx_receipt==> Metrics + + classDef ext fill:#111,stroke:#bbb,color:#fff; + class FlashbotsRelay,Ethereum ext ``` ### Simulation Task From e57f3aff2dddceb27f06abc79278c7da1939726f Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 22 Oct 2025 12:24:53 -0600 Subject: [PATCH 07/14] more cleanup --- README.md | 216 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 113 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index 9b0eee5..36a1797 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The Builder simulates bundles and transactions against the latest chain state to Bundles are treated as Flashbots-style bundles, meaning that the Builder should respect transaction ordering, bundle atomicity, and the specified revertability. ---- +-------------------------------------------------------------------------------- ## šŸš€ System Design @@ -13,126 +13,131 @@ The Builder orchestrates a series of asynchronous actors that work together to b 1. **Env** - watches the latest host and rollup blocks to monitor gas rates and block updates. 2. **Cache** - polls bundle and transaction caches and adds them to the cache. 3. **Simulator** - simulates transactions and bundles against rollup state and block environment to build them into a cohesive block. -5. **Submit** - creates a blob transaction from the built block and sends it to the configured submit task. - 1. Flashbots - builds a Flashbots bundle out of the Signet block which contains Signet transactions, host transactions, and host fills, and submits it to the configured Flashbots endpoint. - 2. Builder Helper - builds a transaction call with the builder helper contract and submits that as a transaction. -6. **Metrics** - records block and tx data over time. +4. **Submit** - creates a blob transaction from the built block and sends it to the configured submit task. + + 1. Flashbots - builds a Flashbots bundle out of the Signet block which contains Signet transactions, host transactions, and host fills, and submits it to the configured Flashbots endpoint. + 2. Builder Helper - builds a transaction call with the builder helper contract and submits that as a transaction. + +5. **Metrics** - records block and tx data over time. ```mermaid %%{ init : { "theme" : "dark" } }%% flowchart TD - %% Initialization - Start(["Start main"]) --> Init["Init tracing & logging"] - Init --> Config["Load BuilderConfig from env"] - - Inbound["šŸ“„ Transactions &\nšŸ“¦ Bundles"] --> Cache["šŸŖ Cache Task"] - Quincey["šŸ–Šļø Quincey (Signer)"] - - %% Block building loop - subgraph BuilderLoop["Block Building Loop"] - Env["šŸ”¢ Env Task"] - Cache - Simulator["šŸ’¾ Simulator Task"] - TxPrep["⛽ Built Signet Block / Tx Prep"] - end - - %% Config wiring - Config -.rollup_rpc.-> Env - Config -.host_rpc.-> Simulator - Config -.host_rpc.-> Metrics["šŸ“ Metrics Task"] - - %% Core flow - Env ==block_env==> Simulator - Cache ==sim_cache==> Simulator - Simulator ==built_block==> TxPrep - - %% Signing - TxPrep -.block_hash.-> Quincey - Quincey -.block_signature.-> TxPrep - - %% Decision: route to Flashbots or Builder Helper - Decision{ "FLASHBOTS_ENDPOINT\nconfigured?" } - TxPrep --> Decision - Decision -->|Yes| FlashbotsSubmit["āš”šŸ¤– Flashbots Submit"] - Decision -->|No| HelperSubmit["šŸ—ļø Builder Helper Submit"] - - FlashbotsSubmit -->|"bundle"| FlashbotsRelay["šŸ›”ļø Flashbots Relay"] - HelperSubmit -->|"blob tx"| Ethereum["ā›“ļø Ethereum L1"] - - %% Metrics - FlashbotsSubmit ==tx_receipt==> Metrics - HelperSubmit ==tx_receipt==> Metrics - - classDef ext fill:#111,stroke:#bbb,color:#fff; - class FlashbotsRelay,Ethereum ext + %% Initialization + Start(["Start"]) --> Init["Init tracing & logging"] + Init --> Config["Load BuilderConfig from env"] + + Inbound["šŸ“„ Transactions & + šŸ“¦ Bundles"] --> Cache["šŸŖ Cache Task"] + Quincey["šŸ–Šļø Quincey (Signer)"] + + %% Block building loop + subgraph BuilderLoop["Block Building Loop"] + Env["šŸ”¢ Env Task"] + Cache["šŸŖ Cache Task"] + Simulator["šŸ’¾ Simulator Task"] + Metrics["šŸ“ Metrics Task"] + + %% Decision: route to Flashbots or Builder Helper + FB@{ shape: hex, label: "FLASHBOTS_ENDPOINT\nconfigured?" } + FB --> | Yes | FlashbotsSubmit["āš”šŸ¤– Flashbots Submit"] + FB --> | No | HelperSubmit["šŸ—ļø Builder Helper Submit"] + + end + + %% Signing + FlashbotsSubmit -- block hash --> Quincey + Quincey -- block signature --> FlashbotsSubmit + HelperSubmit -- block hash --> Quincey + Quincey -- block signature --> HelperSubmit + + %% Config wiring + Config -.rollup rpc.-> Env + Config -.host rpc.-> Simulator + Config -.host rpc.-> Metrics + + %% Core flow + Env ==block_env==> Simulator + Cache ==sim_cache==> Simulator + Simulator ==built_block==> FB + + FlashbotsSubmit -->|"bundle"| FlashbotsRelay["šŸ›”ļø Flashbots Relay"] + FlashbotsRelay --> Ethereum + HelperSubmit -->|"blob tx"| Ethereum["ā›“ļø Ethereum L1"] + + %% Metrics + FlashbotsSubmit ==bundle hash==> Metrics + HelperSubmit ==tx hash==> Metrics + + class FlashbotsRelay,Ethereum ext ``` ### Simulation Task -The block building loop waits until a new block environment has been received, and then kicks off the next attempt. +The block building loop waits until a new block environment has been received, and then kicks off the next attempt. When the Builder receives a new block, it takes a reference to the transaction cache, calculates a simulation deadline for the current slot with a buffer of 1.5 seconds, and begins constructing a block for the current slot. -Transactions enter through the cache, and then they're sent to the simulator, where they're run against the latest chain state and block environment. If they're successfully applied, they're added to the block. If a transaction fails to be applied, it is simply ignored. +Transactions enter through the cache, and then they're sent to the simulator, where they're run against the latest chain state and block environment. If they're successfully applied, they're added to the block. If a transaction fails to be applied, it is simply ignored. -When the deadline is reached, the simulator is stopped, and all open simulation threads are cancelled. The built block is then bundled with the block environment and the previous host header that it was simulated against, and all three are passed along to the submit task. +When the deadline is reached, the simulator is stopped, and all open simulation threads are cancelled. The built block is then bundled with the block environment and the previous host header that it was simulated against, and all three are passed along to the submit task. ### Submit Task If Flashbots endpoint has been configured the Flashbots submit task will prepare a Flashbots bundle out of that Signet block, and then submits that bundle to the Flashbots endpoint. -If a Flashbots endpoint has _not_ been configured, the Builder will create a raw contract call and submits the transaction to the default mempool. This is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. +If a Flashbots endpoint has _not_ been configured, the Builder will create a raw contract call and submits the transaction to the default mempool. This mode of operation is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. If the block received from simulation is empty, the submit task will ignore it. -Finally, if it's non-empty, the submit task attempts to get a signature for the block, and if it fails due to a 403 error, it will skip the current slot and begin waiting for the next block. +Finally, if it's non-empty, the submit task attempts to get a signature for the block, and if it fails due to a 403 error, it will skip the current slot and begin waiting for the next block. ---- +-------------------------------------------------------------------------------- ## āš™ļø Configuration The Builder is configured via environment variables. The following values are supported for configuration. -| Key | Required | Description | -| ----------------------------- | -------- | ---------------------------------------------------------------------- | -| `HOST_CHAIN_ID` | Yes | Host-chain ID (e.g. `3151908`) | -| `RU_CHAIN_ID` | Yes | Rollup-chain ID (e.g. `14174`) | -| `HOST_RPC_URL` | Yes | RPC endpoint for the host chain | -| `ROLLUP_RPC_URL` | Yes | RPC endpoint for the rollup chain | -| `TX_POOL_URL` | Yes | Transaction pool URL (must end with `/`) | -| `TX_BROADCAST_URLS` | No | Additional endpoints for blob txs (comma-separated, slash required) | -| `FLASHBOTS_ENDPOINT` | No | Flashbots API to submit blocks to. | -| `ZENITH_ADDRESS` | Yes | Zenith contract address | -| `BUILDER_HELPER_ADDRESS` | Yes | Builder helper contract address | -| `QUINCEY_URL` | Yes | Remote sequencer signing endpoint | -| `BUILDER_PORT` | Yes | HTTP port for the Builder (default: `8080`) | -| `SEQUENCER_KEY` | Yes | AWS KMS key ID _or_ local private key for sequencer signing | -| `BUILDER_KEY` | Yes | AWS KMS key ID _or_ local private key for builder signing | -| `BUILDER_REWARDS_ADDRESS` | Yes | Address receiving builder rewards | -| `ROLLUP_BLOCK_GAS_LIMIT` | No | Override for block gas limit | -| `CONCURRENCY_LIMIT` | No | Max concurrent tasks the simulator uses | -| `OAUTH_CLIENT_ID` | Yes | Oauth client ID for the builder | -| `OAUTH_CLIENT_SECRET` | Yes | Oauth client secret for the builder | -| `OAUTH_AUTHENTICATE_URL` | Yes | Oauth authenticate URL for the builder for performing OAuth logins | -| `OAUTH_TOKEN_URL` | Yes | Oauth token URL for the builder to get an Oauth2 access token | -| `AUTH_TOKEN_REFRESH_INTERVAL` | Yes | The OAuth token refresh interval in seconds. | -| `CHAIN_NAME` | No | The chain name ("pecorino", or the corresponding name) | -| `SLOT_OFFSET` | No | Slot timing offset in seconds. Required if `CHAIN_NAME` is not present | -| `SLOT_DURATION` | No | Slot duration in seconds. Required if `CHAIN_NAME` is not present | -| `START_TIMESTAMP` | No | UNIX timestamp for slot 0. Required if `CHAIN_NAME` is not present | - ---- +Key | Required | Description +----------------------------- | -------- | ---------------------------------------------------------------------- +`HOST_CHAIN_ID` | Yes | Host-chain ID (e.g. `3151908`) +`RU_CHAIN_ID` | Yes | Rollup-chain ID (e.g. `14174`) +`HOST_RPC_URL` | Yes | RPC endpoint for the host chain +`ROLLUP_RPC_URL` | Yes | RPC endpoint for the rollup chain +`TX_POOL_URL` | Yes | Transaction pool URL (must end with `/`) +`TX_BROADCAST_URLS` | No | Additional endpoints for blob txs (comma-separated, slash required) +`FLASHBOTS_ENDPOINT` | No | Flashbots API to submit blocks to. +`ZENITH_ADDRESS` | Yes | Zenith contract address +`BUILDER_HELPER_ADDRESS` | Yes | Builder helper contract address +`QUINCEY_URL` | Yes | Remote sequencer signing endpoint +`BUILDER_PORT` | Yes | HTTP port for the Builder (default: `8080`) +`SEQUENCER_KEY` | Yes | AWS KMS key ID _or_ local private key for sequencer signing +`BUILDER_KEY` | Yes | AWS KMS key ID _or_ local private key for builder signing +`BUILDER_REWARDS_ADDRESS` | Yes | Address receiving builder rewards +`ROLLUP_BLOCK_GAS_LIMIT` | No | Override for block gas limit +`CONCURRENCY_LIMIT` | No | Max concurrent tasks the simulator uses +`OAUTH_CLIENT_ID` | Yes | Oauth client ID for the builder +`OAUTH_CLIENT_SECRET` | Yes | Oauth client secret for the builder +`OAUTH_AUTHENTICATE_URL` | Yes | Oauth authenticate URL for the builder for performing OAuth logins +`OAUTH_TOKEN_URL` | Yes | Oauth token URL for the builder to get an Oauth2 access token +`AUTH_TOKEN_REFRESH_INTERVAL` | Yes | The OAuth token refresh interval in seconds. +`CHAIN_NAME` | No | The chain name ("pecorino", or the corresponding name) +`SLOT_OFFSET` | No | Slot timing offset in seconds. Required if `CHAIN_NAME` is not present +`SLOT_DURATION` | No | Slot duration in seconds. Required if `CHAIN_NAME` is not present +`START_TIMESTAMP` | No | UNIX timestamp for slot 0\. Required if `CHAIN_NAME` is not present + +-------------------------------------------------------------------------------- ## šŸ’» Recommended Specs -| Key | Minimum | Recommended | -| ------------------ | ------------------ | ----------------- | -| CPU | 0.1 vCPU | 0.5 vCPU | -| Memory | 256MB | 512MB | +Key | Minimum | Recommended +------ | -------- | ----------- +CPU | 0.1 vCPU | 0.5 vCPU +Memory | 256MB | 512MB **Note: Builder prefers clock speed over core count, recommended 2.8Ghz+** ---- +-------------------------------------------------------------------------------- ## šŸ’¾ EVM Behavior @@ -149,16 +154,15 @@ prevrandao: Some(B256::random()), Blob gas values `excess_blob_gas` and `blob_gasprice` are also set to 0 for all Signet blocks. -### šŸ”¢ Disabled Opcodes +### šŸ”¢ Disabled Opcodes -`BLOBHASH` - EIP-4844 is not supported on Signet. -`BLOBBASEFEE` - EIP4844 is not supported. +`BLOBHASH` - EIP-4844 is not supported on Signet. `BLOBBASEFEE` - EIP4844 is not supported. ## ⛽ Transaction Submission -When a completed, non-empty Signet block is received by the Submit task, it prepares the block data into a blob transaction and submits it to the network. +When a completed, non-empty Signet block is received by the Submit task, it prepares the block data into a blob transaction and submits it to the network. -If it fails, it will retry up to 3 times with a 12.5% bump on each retry. +If it fails, it will retry up to 3 times with a 12.5% bump on each retry. The previous header's basefee is tracked through the build loop and used for gas estimation purposes in the Submit Task. @@ -170,22 +174,28 @@ The previous header's basefee is tracked through the build loop and used for gas - **AWS CLI** - A private key or AWS KMS key for signing transactions ---- +-------------------------------------------------------------------------------- ## āœ… Testing 1. Build the Docker image: - ```bash - docker build -t builder:latest . - ``` + + ```bash + docker build -t builder:latest . + ``` + 2. Push to your container registry: - ```bash - docker push /builder:latest - ``` + + ```bash + docker push /builder:latest + ``` + 3. Update your deployment manifests with the new image. + 4. Verify expected behavior in your target network. - - This should typically include sending a test transaction and verifying it is simulated and built into a block. - + + - This should typically include sending a test transaction and verifying it is simulated and built into a block. + ## 🪪 License This project is licensed under the [MIT License](https://opensource.org/licenses/MIT). From f7e2b3d43cd0473603a79407845fc8db4fb7913b Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 22 Oct 2025 12:26:57 -0600 Subject: [PATCH 08/14] moar cleanup --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 36a1797..b5cf87e 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ flowchart TD Config -.rollup rpc.-> Env Config -.host rpc.-> Simulator Config -.host rpc.-> Metrics + Config -.host rpc.-> FlashbotsSubmit + Config -.host rpc.-> HelperSubmit + Config -.rollup rpc.-> Simulator %% Core flow Env ==block_env==> Simulator From 1db9173bd1aca9271afe9bd283a1db4cd618117c Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 22 Oct 2025 12:34:31 -0600 Subject: [PATCH 09/14] moar --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b5cf87e..354aa94 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ flowchart TD %% Config wiring Config -.rollup rpc.-> Env + Config -.host rpc.-> Env Config -.host rpc.-> Simulator Config -.host rpc.-> Metrics Config -.host rpc.-> FlashbotsSubmit From 1a8835f8b94e621b2b5bb5de89d842fc5f2ccb77 Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 22 Oct 2025 12:59:20 -0600 Subject: [PATCH 10/14] fix line widths --- README.md | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 354aa94..437cb3c 100644 --- a/README.md +++ b/README.md @@ -40,40 +40,40 @@ flowchart TD %% Decision: route to Flashbots or Builder Helper FB@{ shape: hex, label: "FLASHBOTS_ENDPOINT\nconfigured?" } - FB --> | Yes | FlashbotsSubmit["āš”šŸ¤– Flashbots Submit"] - FB --> | No | HelperSubmit["šŸ—ļø Builder Helper Submit"] + FB ==> | Yes | FlashbotsSubmit["āš”šŸ¤– Flashbots Submit"] + FB ==> | No | HelperSubmit["šŸ—ļø Builder Helper Submit"] end %% Signing - FlashbotsSubmit -- block hash --> Quincey - Quincey -- block signature --> FlashbotsSubmit - HelperSubmit -- block hash --> Quincey - Quincey -- block signature --> HelperSubmit + FlashbotsSubmit --hash--> Quincey + Quincey -- signature --> FlashbotsSubmit + + HelperSubmit -- hash --> Quincey + Quincey -- signature --> HelperSubmit %% Config wiring Config -.rollup rpc.-> Env Config -.host rpc.-> Env Config -.host rpc.-> Simulator + Config -.rollup rpc.-> Simulator Config -.host rpc.-> Metrics Config -.host rpc.-> FlashbotsSubmit Config -.host rpc.-> HelperSubmit - Config -.rollup rpc.-> Simulator %% Core flow - Env ==block_env==> Simulator - Cache ==sim_cache==> Simulator - Simulator ==built_block==> FB + Env ==block env==> Simulator + Cache ==sim cache==> Simulator + Simulator ==built block==> FB - FlashbotsSubmit -->|"bundle"| FlashbotsRelay["šŸ›”ļø Flashbots Relay"] - FlashbotsRelay --> Ethereum - HelperSubmit -->|"blob tx"| Ethereum["ā›“ļø Ethereum L1"] + %% Network submission + FlashbotsSubmit ==>|"tx bundle"| FlashbotsRelay["šŸ›”ļø Flashbots Relay"] + FlashbotsRelay ==> Ethereum + HelperSubmit ==>|"blob tx"| Ethereum["ā›“ļø Ethereum L1"] %% Metrics FlashbotsSubmit ==bundle hash==> Metrics HelperSubmit ==tx hash==> Metrics - - class FlashbotsRelay,Ethereum ext ``` ### Simulation Task From b6890b378f34c809b22769477fb42265eac791d8 Mon Sep 17 00:00:00 2001 From: dylan Date: Wed, 22 Oct 2025 17:41:40 -0600 Subject: [PATCH 11/14] clean up and link to builder helper --- README.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 437cb3c..4eccca7 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,7 @@ The Builder orchestrates a series of asynchronous actors that work together to b 1. **Env** - watches the latest host and rollup blocks to monitor gas rates and block updates. 2. **Cache** - polls bundle and transaction caches and adds them to the cache. 3. **Simulator** - simulates transactions and bundles against rollup state and block environment to build them into a cohesive block. -4. **Submit** - creates a blob transaction from the built block and sends it to the configured submit task. - - 1. Flashbots - builds a Flashbots bundle out of the Signet block which contains Signet transactions, host transactions, and host fills, and submits it to the configured Flashbots endpoint. - 2. Builder Helper - builds a transaction call with the builder helper contract and submits that as a transaction. - +4. **Submit** - handles preparing and submitting the simulated block. 5. **Metrics** - records block and tx data over time. ```mermaid @@ -40,9 +36,8 @@ flowchart TD %% Decision: route to Flashbots or Builder Helper FB@{ shape: hex, label: "FLASHBOTS_ENDPOINT\nconfigured?" } - FB ==> | Yes | FlashbotsSubmit["āš”šŸ¤– Flashbots Submit"] + FB ==> | Yes | FlashbotsSubmit["šŸ¤– Flashbots Submit"] FB ==> | No | HelperSubmit["šŸ—ļø Builder Helper Submit"] - end %% Signing @@ -76,7 +71,7 @@ flowchart TD HelperSubmit ==tx hash==> Metrics ``` -### Simulation Task +### šŸ’¾ Simulation Task The block building loop waits until a new block environment has been received, and then kicks off the next attempt. @@ -86,11 +81,11 @@ Transactions enter through the cache, and then they're sent to the simulator, wh When the deadline is reached, the simulator is stopped, and all open simulation threads are cancelled. The built block is then bundled with the block environment and the previous host header that it was simulated against, and all three are passed along to the submit task. -### Submit Task +### ✨ Submit Task If Flashbots endpoint has been configured the Flashbots submit task will prepare a Flashbots bundle out of that Signet block, and then submits that bundle to the Flashbots endpoint. -If a Flashbots endpoint has _not_ been configured, the Builder will create a raw contract call and submits the transaction to the default mempool. This mode of operation is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. +If a Flashbots endpoint has _not_ been configured, the Builder uses the [builder helper contract] and to craft a rollup block transaction and submits that to the default mempool. This mode of operation is only for testing on private networks and should not be used in production, since it can leak sensitive transaction data from the Signet block. If the block received from simulation is empty, the submit task will ignore it. @@ -103,14 +98,14 @@ Finally, if it's non-empty, the submit task attempts to get a signature for the The Builder is configured via environment variables. The following values are supported for configuration. Key | Required | Description ------------------------------ | -------- | ---------------------------------------------------------------------- +----------------------------- | -------- | ------------------------------------------------------------------------------------------ `HOST_CHAIN_ID` | Yes | Host-chain ID (e.g. `3151908`) `RU_CHAIN_ID` | Yes | Rollup-chain ID (e.g. `14174`) `HOST_RPC_URL` | Yes | RPC endpoint for the host chain `ROLLUP_RPC_URL` | Yes | RPC endpoint for the rollup chain `TX_POOL_URL` | Yes | Transaction pool URL (must end with `/`) `TX_BROADCAST_URLS` | No | Additional endpoints for blob txs (comma-separated, slash required) -`FLASHBOTS_ENDPOINT` | No | Flashbots API to submit blocks to. +`FLASHBOTS_ENDPOINT` | No | Flashbots API to submit blocks to. Defaults to the BuilderHelper submit task if not set. `ZENITH_ADDRESS` | Yes | Zenith contract address `BUILDER_HELPER_ADDRESS` | Yes | Builder helper contract address `QUINCEY_URL` | Yes | Remote sequencer signing endpoint @@ -203,3 +198,5 @@ The previous header's basefee is tracked through the build loop and used for gas ## 🪪 License This project is licensed under the [MIT License](https://opensource.org/licenses/MIT). + +[builder helper contract]: https://github.com/init4tech/helper-contracts/blob/main/src/BuilderHelper.sol From db07bb8967110e32a4464d2f03dca66ec30c1ce5 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 4 Nov 2025 21:37:43 -0700 Subject: [PATCH 12/14] removes builder helper mentions entirely since deprecation --- README.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4eccca7..648a3fd 100644 --- a/README.md +++ b/README.md @@ -33,20 +33,13 @@ flowchart TD Cache["šŸŖ Cache Task"] Simulator["šŸ’¾ Simulator Task"] Metrics["šŸ“ Metrics Task"] - - %% Decision: route to Flashbots or Builder Helper - FB@{ shape: hex, label: "FLASHBOTS_ENDPOINT\nconfigured?" } - FB ==> | Yes | FlashbotsSubmit["šŸ¤– Flashbots Submit"] - FB ==> | No | HelperSubmit["šŸ—ļø Builder Helper Submit"] + FlashbotsSubmit["šŸ“„ Flashbots Submit Task"] end %% Signing FlashbotsSubmit --hash--> Quincey Quincey -- signature --> FlashbotsSubmit - HelperSubmit -- hash --> Quincey - Quincey -- signature --> HelperSubmit - %% Config wiring Config -.rollup rpc.-> Env Config -.host rpc.-> Env @@ -54,21 +47,18 @@ flowchart TD Config -.rollup rpc.-> Simulator Config -.host rpc.-> Metrics Config -.host rpc.-> FlashbotsSubmit - Config -.host rpc.-> HelperSubmit %% Core flow Env ==block env==> Simulator Cache ==sim cache==> Simulator - Simulator ==built block==> FB + Simulator ==built block==> FlashbotsSubmit %% Network submission FlashbotsSubmit ==>|"tx bundle"| FlashbotsRelay["šŸ›”ļø Flashbots Relay"] FlashbotsRelay ==> Ethereum - HelperSubmit ==>|"blob tx"| Ethereum["ā›“ļø Ethereum L1"] %% Metrics FlashbotsSubmit ==bundle hash==> Metrics - HelperSubmit ==tx hash==> Metrics ``` ### šŸ’¾ Simulation Task From 381f90dddc85fd60a8ba80d96c206e7bca2351c9 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 4 Nov 2025 21:39:55 -0700 Subject: [PATCH 13/14] moar cleanup --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 648a3fd..2061ff1 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ flowchart TD FlashbotsRelay ==> Ethereum %% Metrics - FlashbotsSubmit ==bundle hash==> Metrics + FlashbotsSubmit ==rollup block tx hash==> Metrics ``` ### šŸ’¾ Simulation Task @@ -88,7 +88,7 @@ Finally, if it's non-empty, the submit task attempts to get a signature for the The Builder is configured via environment variables. The following values are supported for configuration. Key | Required | Description ------------------------------ | -------- | ------------------------------------------------------------------------------------------ +----------------------------- | -------- | ---------------------------------------------------------------------------------------- `HOST_CHAIN_ID` | Yes | Host-chain ID (e.g. `3151908`) `RU_CHAIN_ID` | Yes | Rollup-chain ID (e.g. `14174`) `HOST_RPC_URL` | Yes | RPC endpoint for the host chain From 6d3a389dcba21aa2eeda65940dc4abef550c42a3 Mon Sep 17 00:00:00 2001 From: dylan Date: Tue, 4 Nov 2025 21:40:50 -0700 Subject: [PATCH 14/14] moar --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2061ff1..0bb5ecd 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The Builder orchestrates a series of asynchronous actors that work together to b 1. **Env** - watches the latest host and rollup blocks to monitor gas rates and block updates. 2. **Cache** - polls bundle and transaction caches and adds them to the cache. 3. **Simulator** - simulates transactions and bundles against rollup state and block environment to build them into a cohesive block. -4. **Submit** - handles preparing and submitting the simulated block. +4. **FlashbotsSubmit** - handles preparing and submitting the simulated block to a private Flashbots relay. 5. **Metrics** - records block and tx data over time. ```mermaid