{"id":21531976,"url":"https://github.com/chainbound/bolt-builder","last_synced_at":"2026-01-28T18:02:08.786Z","repository":{"id":261219115,"uuid":"878430936","full_name":"chainbound/bolt-builder","owner":"chainbound","description":"Reference implementation of the constraints-API based on Flashbots' Go Builder","archived":false,"fork":false,"pushed_at":"2024-11-26T15:48:42.000Z","size":17041,"stargazers_count":1,"open_issues_count":2,"forks_count":3,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-24T02:12:43.424Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://boltprotocol.xyz","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chainbound.png","metadata":{"files":{"readme":"README.flashbots.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-10-25T11:33:46.000Z","updated_at":"2024-11-26T15:49:27.000Z","dependencies_parsed_at":"2024-11-05T11:53:18.308Z","dependency_job_id":null,"html_url":"https://github.com/chainbound/bolt-builder","commit_stats":null,"previous_names":["chainbound/bolt-builder"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainbound%2Fbolt-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainbound%2Fbolt-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainbound%2Fbolt-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainbound%2Fbolt-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainbound","download_url":"https://codeload.github.com/chainbound/bolt-builder/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248134793,"owners_count":21053532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-24T02:18:23.037Z","updated_at":"2026-01-28T18:02:03.659Z","avatar_url":"https://github.com/chainbound.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[geth readme](README.original.md)\n\n# Flashbots Block Builder\n\nThis project implements the Flashbots block builder, based on go-ethereum (geth).\n\nSee also: https://docs.flashbots.net/flashbots-mev-boost/block-builders\n\nRun on your favorite network, including Mainnet, Goerli, Sepolia and local devnet. Instructions for running a pos local devnet can be found [here](https://github.com/avalonche/eth-pos-devnet).\n\nYou will need to run a modified beacon node that sends a custom rpc call to trigger block building. You can use the modified [prysm fork](https://github.com/flashbots/prysm) for this.\n\nTest with [mev-boost](https://github.com/flashbots/mev-boost) and [mev-boost test cli](https://github.com/flashbots/mev-boost/tree/main/cmd/test-cli).\n\nBuilding `geth` requires both a Go (version 1.19 or later) and a C compiler. You can install\nthem using your favourite package manager. Once the dependencies are installed, run\n\n## How it works\n\n* Builder polls relay for the proposer registrations for the next epoch when block building is triggered\n* If both local relay and remote relay are enabled, local relay will overwrite remote relay data. This is only meant for the testnets!\n\n## Limitations\n\n* Does not accept external blocks\n* Does not have payload cache, only the latest block is available\n\n# Usage\n\nConfigure geth for your network, it will become the block builder.\n\nBuilder-related options:\n```\n$ geth --help\n\n   BUILDER\n\n    --builder                      (default: false)\n          Enable the builder\n\n    --builder.algotype value       (default: \"mev-geth\")\n          Block building algorithm to use [=mev-geth] (mev-geth, greedy, greedy-buckets)\n   \n    --builder.beacon_endpoints value (default: \"http://127.0.0.1:5052\")\n          Comma separated list of beacon endpoints to connect to for beacon chain data\n          [$BUILDER_BEACON_ENDPOINTS]\n\n    --builder.bellatrix_fork_version value (default: \"0x02000000\")\n          Bellatrix fork version. [$BUILDER_BELLATRIX_FORK_VERSION]\n\n    --builder.blacklist value     \n          Path to file containing blacklisted addresses, json-encoded list of strings.\n          Builder will ignore transactions that touch mentioned addresses.\n   \n    --builder.block_resubmit_interval value (default: \"500ms\")\n          Determines the interval at which builder will resubmit block submissions\n          [$FLASHBOTS_BUILDER_RATE_LIMIT_RESUBMIT_INTERVAL]\n\n    --builder.cancellations        (default: false)\n          Enable cancellations for the builder\n\n    --builder.discard_revertible_tx_on_error (default: false)\n          When enabled, if a transaction submitted as part of a bundle in a send bundle\n          request has error on commit, and its hash is specified as one that can revert in\n          the request body, the builder will discard the hash of the failed transaction\n          from the submitted bundle.For additional details on the structure of the request\n          body, see\n          https://docs.flashbots.net/flashbots-mev-share/searchers/understanding-bundles#bundle-definition\n          [$FLASHBOTS_BUILDER_DISCARD_REVERTIBLE_TX_ON_ERROR]\n\n    --builder.dry-run              (default: false)\n          Builder only validates blocks without submission to the relay\n\n    --builder.genesis_fork_version value (default: \"0x00000000\")\n          Gensis fork version. [$BUILDER_GENESIS_FORK_VERSION]\n\n    --builder.genesis_validators_root value (default: \"0x0000000000000000000000000000000000000000000000000000000000000000\")\n          Genesis validators root of the network. [$BUILDER_GENESIS_VALIDATORS_ROOT]\n\n    --builder.ignore_late_payload_attributes (default: false)\n          Builder will ignore all but the first payload attributes. Use if your CL sends\n          non-canonical head updates.\n\n    --builder.listen_addr value    (default: \":28545\")\n          Listening address for builder endpoint [$BUILDER_LISTEN_ADDR]\n\n    --builder.local_relay          (default: false)\n          Enable the local relay\n\n    --builder.no_bundle_fetcher    (default: false)\n          Disable the bundle fetcher\n\n    --builder.price_cutoff_percent value (default: 50)\n          flashbots - The minimum effective gas price threshold used for bucketing\n          transactions by price. For example if the top transaction in a list has an\n          effective gas price of 1000 wei and price_cutoff_percent is 10 (i.e. 10%), then\n          the minimum effective gas price included in the same bucket as the top\n          transaction is (1000 * 10%) = 100 wei.\n          NOTE: This flag is only used when\n          builder.algotype=greedy-buckets [$FLASHBOTS_BUILDER_PRICE_CUTOFF_PERCENT]\n\n    --builder.rate_limit_duration value (default: \"500ms\")\n          Determines rate limit of events processed by builder. For example, a value of\n          \"500ms\" denotes that the builder processes events every 500ms. A duration string\n          is a possibly signed sequence of decimal numbers, each with optional fraction\n          and a unit suffix, such as \"300ms\", \"-1.5h\" or \"2h45m\"\n          [$FLASHBOTS_BUILDER_RATE_LIMIT_DURATION]\n\n    --builder.rate_limit_max_burst value (default: 10)\n          Determines the maximum number of burst events the builder can accommodate at any\n          given point in time. [$FLASHBOTS_BUILDER_RATE_LIMIT_MAX_BURST]\n\n    --builder.relay_secret_key value (default: \"0x2fc12ae741f29701f8e30f5de6350766c020cb80768a0ff01e6838ffd2431e11\")\n          Builder local relay API key used for signing headers [$BUILDER_RELAY_SECRET_KEY]\n\n    --builder.remote_relay_endpoint value\n          Relay endpoint to connect to for validator registration data, if not provided\n          will expose validator registration locally [$BUILDER_REMOTE_RELAY_ENDPOINT]\n\n    --builder.secondary_remote_relay_endpoints value\n          Comma separated relay endpoints to connect to for validator registration data\n          missing from the primary remote relay, and to push blocks for registrations\n          missing from or matching the primary [$BUILDER_SECONDARY_REMOTE_RELAY_ENDPOINTS]\n\n    --builder.seconds_in_slot value (default: 12)\n          Set the number of seconds in a slot in the local relay\n\n    --builder.secret_key value     (default: \"0x2fc12ae741f29701f8e30f5de6350766c020cb80768a0ff01e6838ffd2431e11\")\n          Builder key used for signing blocks [$BUILDER_SECRET_KEY]\n\n    --builder.slots_in_epoch value (default: 32)\n          Set the number of slots in an epoch in the local relay\n\n    --builder.submission_offset value (default: 3s)\n          Determines the offset from the end of slot time that the builder will submit\n          blocks. For example, if a slot is 12 seconds long, and the offset is 2 seconds,\n          the builder will submit blocks at 10 seconds into the slot.\n          [$FLASHBOTS_BUILDER_SUBMISSION_OFFSET]\n\n    --builder.validation_blacklist value\n          Path to file containing blacklisted addresses, json-encoded list of strings\n          \n    --builder.validation_use_balance_diff (default: false)\n          Block validation API will use fee recipient balance difference for profit\n          calculation.\n   \n    --builder.validator_checks     (default: false)\n          Enable the validator checks\n\n    MINER\n\n    --miner.algotype value         (default: \"mev-geth\")\n          [NOTE: Deprecated, please use builder.algotype instead] Block building algorithm\n          to use [=mev-geth] (mev-geth, greedy, greedy-buckets)\n\n    --miner.blocklist value       \n          [NOTE: Deprecated, please use builder.blacklist] flashbots - Path to JSON file with\n          list of blocked addresses. Miner will ignore txs that touch mentioned addresses.\n\n    --miner.extradata value\n          Block extra data set by the miner (default = client version)\n\n    --miner.price_cutoff_percent value (default: 50)\n          flashbots - The minimum effective gas price threshold used for bucketing\n          transactions by price. For example if the top transaction in a list has an\n          effective gas price of 1000 wei and price_cutoff_percent is 10 (i.e. 10%), then\n          the minimum effective gas price included in the same bucket as the top\n          transaction is (1000 * 10%) = 100 wei.\n          NOTE: This flag is only used when\n          miner.algotype=greedy-buckets\n\n   METRICS\n\n   --metrics.builder value          (default: false)\n            Enable builder metrics collection and reporting\n```\n\nEnvironment variables:\n```\nBUILDER_TX_SIGNING_KEY - private key of the builder used to sign payment transaction, must be the same as the coinbase address\n\nFLASHBOTS_BUILDER_RATE_LIMIT_DURATION - determines rate limit of events processed by builder; a duration string is a \npossibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as \"300ms\", \"-1.5h\" or \"2h45m\".\n\nFLASHBOTS_BUILDER_RATE_LIMIT_MAX_BURST - determines the maximum number of events the builder can accommodate at any point in time\n\nFLASHBOTS_BUILDER_RATE_LIMIT_RESUBMIT_INTERVAL - determines the interval at which builder will resubmit block submissions\n```\n\n## Metrics\n\nTo enable metrics on the builder you will need to enable metrics with the flags `--metrics --metrics.addr 127.0.0.1 --metrics.builder` which will run\na metrics server serving at `127.0.0.1:6060/debug/metrics`. This will record performance metrics such as block profit and block building times.\nThe full list of metrics can be found in `miner/metrics.go`.\n\nSee the [metrics docs](https://geth.ethereum.org/docs/monitoring/metrics) for geth for more documentation.\n\n## Blacklisting addresses\n\nIf you want to reject transactions interacting with certain addresses, save the addresses in json file with an array of strings. Deciding whether to use such a list, as well as maintaining it, is your own responsibility.\n\n- for block building and validation, use `--builder.blacklist`\n\n--\n\n## Details of the implementation\n\nThere are two parts of the builder.\n\n1. `./builder` responsible for communicating with the relay\n2. `./miner` responsible for producing blocks\n\n### `builder` module\n\nMain logic of the builder is in the `builder.go` file.\n\nBuilder is driven by the consensus client SSE events that sends payload attribute events, triggering the `OnPayloadAttribute` call.\nAfter requesting additional validator data from the relay builder starts building job with `runBuildingJob`.\nBuilding job continuously makes a request to the `miner` with the correct parameters and submits produced block.\n\n* Builder retries build block requests every second on average.\n* If the job is running but a new one is submitted for a different slot we cancel previous job.\n* All jobs have 12s deadline.\n* If new request is submitted for the same slot as before but with different parameters, we run these jobs in parallel.\n  It is possible to receive multiple requests from CL for the same slot but for different parent blocks if there is a possibility\n  of a missed block.\n* All submissions to the relay are rate limited at 2 req/s\n* Only blocks that have more profit than the previous best submissions for the particular job are submitted.\n\nAdditional features of the builder:\n* Builder can submit data about build blocks to the database. It stores block data, included bundles, and all considered bundles.\n  Implemented in `flashbotsextra.IDatabaseService`.\n* It's possible to run local relay in the same process\n* It can validate blocks instead of submitting them to the relay. (see `--builder.dry-run`)\n\n### `miner` module\n\nMiner is responsible for block creation. Request from the `builder` is routed to the `worker.go` where\n`generateWork` does the job of creating a block.\n\n* Coinbase of the block is set to the address of the block proposer, fee recipient of the validator receives its eth\n  in the last tx in the block.\n* We reserve gas for the proposer payment using `proposerTxPrepare` and commit proposer payment after txs are added with\n  `proposerTxCommit`. We do it in a way so all fees received by the block builder are sent to the fee recipient.\n* Transaction insertion is done in `fillTransactionsAlgoWorker` \\ `fillTransactions`. Depending on the algorithm selected.\n  Algo worker (greedy) inserts bundles whenever they belong in the block by effective gas price but default method inserts bundles on top of the block.\n  (see `--miner.algotype`)\n* Worker is also responsible for simulating bundles. Bundles are simulated in parallel and results are cached for the particular parent block.\n* `algo_greedy.go` implements logic of the block building. Bundles and transactions are sorted in the order of effective gas price then\n  we try to insert everything into to block until gas limit is reached. Failing bundles are reverted during the insertion but txs are not.\n* Builder can filter transactions touching a particular set of addresses.\n  If a bundle or transaction touches one of the addresses it is skipped. (see `--builder.blacklist` flag)\n\n## Bundle Movement\n\nThere are two ways bundles are moved to builders\n\n1. via API -`sendBundle`\n2. via Database - `flashbotsextra.IDatabaseService`\n\n### `fetcher` service\n* Fetcher service is part of `flashbotsextra.IDatabaseService` which is responsible for fetching the bundles from db and pushing into mev bundles queue which will be processed by builder.\n* Fetcher is a background process which fetches high priority and low priority bundles from db.\n* Fetcher fetches `500` high priority bundles on every head change, and `100` low priority bundles in the interval of every `2 seconds`.\n\n## Block builder diagram\n\n![block builder diagram](docs/builder/builder-diagram.png \"Block builder diagram\")\n\n---\n\n# Security\n\nIf you find a security vulnerability in this project or any other initiative\nrelated to proposer/builder separation in Ethereum, please let us know sending\nan email to security@flashbots.net.\n\n---\n\n# License\n\nThe code in this project is free software under the [LGPL License](COPYING.LESSER).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainbound%2Fbolt-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchainbound%2Fbolt-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainbound%2Fbolt-builder/lists"}