1"use strict";(globalThis.webpackChunkkurtosis_docs=globalThis.webpackChunkkurtosis_docs||[]).push([[553],{9074(e,t,n){n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>c});const o=JSON.parse('{"id":"guides/how-to-full-mev-with-eth2-package","title":"How to launch a private Ethereum testnet with Flashbot\'s MEV Boost implementation of Proposer Builder Separation (PBS)","description":"Here are some quick short-cuts for folks who would prefer:","source":"@site/docs/guides/how-to-full-mev-with-eth2-package.md","sourceDirName":"guides","slug":"/how-to-full-mev-with-ethereum-package","permalink":"/how-to-full-mev-with-ethereum-package","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":12,"frontMatter":{"title":"How to launch a private Ethereum testnet with Flashbot\'s MEV Boost implementation of Proposer Builder Separation (PBS)","sidebar_label":"Launch a testnet with MEV infra","slug":"/how-to-full-mev-with-ethereum-package","toc_max_heading_level":2,"sidebar_position":12},"sidebar":"main","previous":{"title":"Build your own testnet from scratch","permalink":"/how-to-compose-your-own-testnet"},"next":{"title":"Running Docker Compose","permalink":"/docker-compose"}}');var s=n(4848),i=n(8453);const r={title:"How to launch a private Ethereum testnet with Flashbot's MEV Boost implementation of Proposer Builder Separation (PBS)",sidebar_label:"Launch a testnet with MEV infra",slug:"/how-to-full-mev-with-ethereum-package",toc_max_heading_level:2,sidebar_position:12},a=void 0,l={},c=[{value:"Why <code>ethereum-package</code>?",id:"why-ethereum-package",level:4},{value:"What if I only want the MEV parts?",id:"what-if-i-only-want-the-mev-parts",level:4},{value:"Brief overview of the architecture",id:"brief-overview-of-the-architecture",level:2},{value:"Caveats:",id:"caveats",level:4},{value:"Quickstart",id:"quickstart",level:2},{value:"Install dependencies",id:"install-dependencies",level:4},{value:"Configure your network",id:"configure-your-network",level:4},{value:"Launch the network with <code>full MEV</code>",id:"launch-the-network-with-full-mev",level:4},{value:"Visit the website to see registered validators and delivered payloads",id:"visit-the-website-to-see-registered-validators-and-delivered-payloads",level:4},{value:"Roadmap",id:"roadmap",level:2},{value:"Conclusion",id:"conclusion",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.admonition,{type:"tip",children:[(0,s.jsx)(t.p,{children:"Here are some quick short-cuts for folks who would prefer:"}),(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["To get going right away: install Kurtosis & Docker and then run: ",(0,s.jsx)(t.code,{children:'kurtosis run github.com/ethpandaops/ethereum-package \'{"mev_type": "full"}\''})]}),"\n",(0,s.jsxs)(t.li,{children:["To dive into the code example: visit the repository ",(0,s.jsx)(t.a,{href:"https://github.com/ethpandaops/ethereum-package",children:"here"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["Not to run this package on their local machine: try it out on the ",(0,s.jsx)(t.a,{href:"https://gitpod.io/?autoStart=true&editor=code#https://github.com/ethpandaops/ethereum-package",children:"Kurtosis playground"})]}),"\n"]})]}),"\n",(0,s.jsxs)(t.p,{children:["We're elated to share that the ",(0,s.jsx)(t.a,{href:"https://github.com/ethpandaops/ethereum-package",children:(0,s.jsx)(t.code,{children:"ethereum-package"})})," now supports the Flashbot's implementation of ",(0,s.jsx)(t.a,{href:"https://ethereum.org/en/roadmap/pbs/",children:"Proposer-Builder Separation (PBS)"})," using ",(0,s.jsx)(t.a,{href:"https://boost.flashbots.net",children:"MEV-Boost"})," protocol."]}),"\n",(0,s.jsx)(t.p,{children:"This milestone marks a huge step forward in the journey towards a full, in-protocol PBS implementation for Proof-of-Stake Ethereum as developers across the ecosystem now have a way to instantiate fully functioning testnets to validate functionality, behvaior, and scales across all client combinations with a Builder API implementation (Flashbots', in this case)."}),"\n",(0,s.jsxs)(t.p,{children:["Keep reading to learn ",(0,s.jsx)(t.a,{href:"#brief-overview-of-the-architecture",children:"how it all works"})," & ",(0,s.jsxs)(t.a,{href:"#quickstart",children:["how to get started with the ",(0,s.jsx)(t.code,{children:"ethereum-package"})]}),"."]}),"\n",(0,s.jsxs)(t.h4,{id:"why-ethereum-package",children:["Why ",(0,s.jsx)(t.code,{children:"ethereum-package"}),"?"]}),"\n",(0,s.jsxs)(t.p,{children:["As a reminder, the ",(0,s.jsx)(t.a,{href:"https://github.com/ethpandaops/ethereum-package",children:(0,s.jsx)(t.code,{children:"ethereum-package"})})," is a reproducible and portable environment definition that should be used to bootstrap & deploy private testnets. The package will function the exact same way locally or in the cloud over Docker or Kubernetes, supports all major Execution Layer (EL) and Consensus Layer (CL) client implementations, and can be scaled to whatever size your team needs - limited only by your underlying hardware/backend."]}),"\n",(0,s.jsx)(t.h4,{id:"what-if-i-only-want-the-mev-parts",children:"What if I only want the MEV parts?"}),"\n",(0,s.jsxs)(t.p,{children:["And if that wasn't enough, Kurtosis environment definitions (known as ",(0,s.jsx)(t.a,{href:"https://docs.kurtosis.com/advanced-concepts/packages/",children:"Packages"}),") are entirely composable, meaning you can define and build-your-own private testnet using only the parts you need and with the option of adding your own services (e.g. MEV searcher tools). Feel free to check out the following ",(0,s.jsx)(t.a,{href:"https://github.com/kurtosis-tech/2-el-cl-mev-package/blob/main/main.star",children:"code example"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"brief-overview-of-the-architecture",children:"Brief overview of the architecture"}),"\n",(0,s.jsxs)(t.p,{children:["Explicitly, the ",(0,s.jsx)(t.a,{href:"https://github.com/ethpandaops/ethereum-package",children:(0,s.jsx)(t.code,{children:"ethereum-package"})})," supports two modes: ",(0,s.jsx)(t.code,{children:"full-mev"})," and ",(0,s.jsx)(t.code,{children:"mock-mev"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The former mode is valuable for validating behavior between the protocol and out-of-protocol middle-ware infrastru
1cture (e.g. searchers, relayer) and instantiates ",(0,s.jsx)(t.a,{href:"https://github.com/flashbots/mev-boost",children:(0,s.jsx)(t.code,{children:"mev-boost"})}),", ",(0,s.jsx)(t.a,{href:"https://github.com/flashbots/mev-boost-relay",children:(0,s.jsx)(t.code,{children:"mev-relay"})}),", ",(0,s.jsx)(t.a,{href:"https://github.com/flashbots/mev-flood",children:(0,s.jsx)(t.code,{children:"mev-flood"})})," and Flashbot's Geth-based block builder called ",(0,s.jsx)(t.a,{href:"https://github.com/flashbots/builder",children:(0,s.jsx)(t.code,{children:"mev-builder"})}),". The latter mode will only spin up ",(0,s.jsx)(t.a,{href:"https://github.com/flashbots/mev-boost",children:(0,s.jsx)(t.code,{children:"mev-boost"})})," and a ",(0,s.jsx)(t.a,{href:"https://github.com/marioevz/mock-builder",children:(0,s.jsx)(t.code,{children:"mock-builder"})}),", which is useful for testing in-protocol behavior like testing if clients are able to call the relayer for a payload via ",(0,s.jsx)(t.code,{children:"mev-boost"}),", reject invalid payloads, or trigger the ",(0,s.jsx)(t.a,{href:"https://hackmd.io/@ralexstokes/BJn9N6Thc",children:"circuit breaker"})," to ensure functionality of the beacon chain."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"ethereum-package"})," with MEV emulation are already in use by client teams to help uncover bugs (examples ",(0,s.jsx)(t.a,{href:"https://github.com/prysmaticlabs/prysm/pull/12736",children:"here"})," and ",(0,s.jsx)(t.a,{href:"https://github.com/NethermindEth/nethermind/commit/4d805769159dc0717aa1ba38cc3ebc53f9a375cf",children:"here"}),")."]}),"\n",(0,s.jsx)(t.p,{children:"Everything you see below in the architecture diagram gets configured, initialized, and bootstrapped together by Kurtosis."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"mev-arch",src:n(1897).A+"",width:"1618",height:"1168"})}),"\n",(0,s.jsx)(t.h4,{id:"caveats",children:"Caveats:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.code,{children:"mev-boost-relay"})," service requires Capella at an epoch of non-zero. For the ethereum-package, the Capella fork is set to happen after the first epoch to be started up and fully connected to the CL client."]}),"\n",(0,s.jsxs)(t.li,{children:["Validators (64 per node by default, so 128 in the example in this guide) will get registered with the relay automatically after the 2nd epoch. This registration process is simply a configuration addition to the mev-boost config - which Kurtosis will automatically take care of as part of the set up. This means that the ",(0,s.jsx)(t.code,{children:"mev-relay"})," infrastructure only becomes aware of the existence of the validators after the 2nd epoch."]}),"\n",(0,s.jsxs)(t.li,{children:["After the 3rd epoch, the ",(0,s.jsx)(t.code,{children:"mev-relay"})," service will begin to receive execution payloads (",(0,s.jsx)(t.code,{children:"eth_sendPayload"}),", which does not contain transaction content) from the ",(0,s.jsx)(t.code,{children:"mev-builder"})," service (or ",(0,s.jsx)(t.code,{children:"mock-builder"})," in ",(0,s.jsx)(t.code,{children:"mock-mev"})," mode)."]}),"\n",(0,s.jsxs)(t.li,{children:["Validators will then start to receive validated execution payload headers from the ",(0,s.jsx)(t.code,{children:"mev-relay"})," service (via ",(0,s.jsx)(t.code,{children:"mev-boost"}),") after the 4th epoch. The validator selects the most valuable header, signs the payload, and returns the signed header to the relay - effectively proposing the payload of transactions to be included in the soon-to-be-proposed block. Once the relay verifies the block proposer's signature, the relay will respond with the full execution payload body (incl. the transaction contents) for the validator to use when proposing a ",(0,s.jsx)(t.code,{children:"SignedBeaconBlock"})," to the network."]}),"\n",(0,s.jsxs)(t.li,{children:["You may notice in the ",(0,s.jsx)(t.code,{children:"mev-flood"})," logs that there may be transactions that fail to get processed by the node(s) in your devnet with the following errors: ",(0,s.jsx)(t.code,{children:"Error: replacement fee too low [ See: https://links.ethers.org/v5-errors-REPLACEMENT_UNDERPRICED ]"}),". Don't be alarmed: this can happen when transactions are sent too quickly to the network, resulting in the node receiving transactions with the same nonce. When this happens, the node rejects the transactions becauase the node assumes you're trying to replace the old pending transaction with a new one. You can change the frequency using ",(0,s.jsx)(t.code,{children:"mev-flood"}),"'s ",(0,s.jsx)(t.code,{children:"--secondsPerBundle (-p )"})," flag in the ",(0,s.jsxs)(t.a,{href:"https://github.com/flashbots/mev-flood#send-swaps",children:[(0,s.jsx)(t.code,{children:"spam"})," command"]}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Quick aside on what ",(0,s.jsx)(t.code,{children:"mev-flood"})," does:\nOnce the network is online, ",(0,s.jsx)(t.code,{children:"mev-flood"})," will deploy UniV2 smart contracts, provision liquidity on UniV2 pairs, & begin to send a constant stream of UniV2 swap transactions to the network's public mempool. Depending on the mode you're running, either the ",(0,s.jsx)(t.code,{children:"mock-builder"})," or Flashbot's ",(0,s.jsx)(t.code,{children:"mev-builder"}),", the transactions will be bundled into payloads for downstream use by the relayer or by validators themselves. It is important to note that ",(0,s.jsx)(t.code,{children:"mev-flood"})," will only be initialized with the ",(0,s.jsx)(t.code,{children:"full-mev"})," set up and will send transactions with a non-zero block value. Read more about ",(0,s.jsxs)(t.a,{href:"https://github.com/flashbots/mev-flood",children:[(0,s.jsx)(t.code,{children:"mev-flood"})," here"]}),"."]})}
1),"\n",(0,s.jsx)(t.h2,{id:"quickstart",children:"Quickstart"}),"\n",(0,s.jsxs)(t.p,{children:["Leveraging the ",(0,s.jsx)(t.a,{href:"https://github.com/ethpandaops/ethereum-package",children:(0,s.jsx)(t.code,{children:"ethereum-package"})})," is simple. In this short quickstart, you will:"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Install Docker & Kurtosis locally."}),"\n",(0,s.jsxs)(t.li,{children:["Configure your network using a ",(0,s.jsx)(t.code,{children:".yaml"})," file."]}),"\n",(0,s.jsxs)(t.li,{children:["Run a single command to launch your network with ",(0,s.jsx)(t.code,{children:"full MEV"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["Visit the website to witness payloads being delivered from the Relayer to the ",(0,s.jsx)(t.code,{children:"mev-boost"})," sidecar connected to each validator (for block proposals)."]}),"\n"]}),"\n",(0,s.jsx)(t.h4,{id:"install-dependencies",children:"Install dependencies"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://docs.docker.com/get-docker/",children:"Install Docker"})," and ensure the Docker Daemon is running on your machine (e.g. open Docker Desktop). You can quickly check if Docker is running by running: ",(0,s.jsx)(t.code,{children:"docker image ls"})," from your terminal to see all your Docker images."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://docs.kurtosis.com/install/#ii-install-the-cli",children:"Install Kurtosis"})," or ",(0,s.jsx)(t.a,{href:"https://docs.kurtosis.com/upgrade",children:"upgrade Kurtosis to the latest version"}),". You can check if Kurtosis is running using the command: ",(0,s.jsx)(t.code,{children:"kurtosis version"}),", which will print your current Kurtosis engine version and CLI version."]}),"\n"]}),"\n",(0,s.jsx)(t.h4,{id:"configure-your-network",children:"Configure your network"}),"\n",(0,s.jsxs)(t.p,{children:["Next, create a file titled: ",(0,s.jsx)(t.code,{children:"ethereum-package-params.yaml"})," in your working directory and populate it with:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-yaml",children:"participants:\n\t- el_client_type: geth\n\t\tel_client_image: ethereum/client-go:latest\n\t\tel_client_log_level: ''\n\t\tel_extra_params: []\n\t\tcl_client_type: lighthouse\n\t\tcl_client_image: sigp/lighthouse:latest\n\t\tcl_client_log_level: ''\n\t\tbeacon_extra_params: []\n\t\tvalidator_extra_params: []\n\t\tbuilder_network_params: null\nnetwork_params:\n network_id: '3151908'\n deposit_contract_address: '0x4242424242424242424242424242424242424242'\n seconds_per_slot: 12\n slots_per_epoch: 32\n num_validator_keys_per_node: 64\n preregistered_validator_keys_mnemonic: 'giant issue aisle success illegal bike spike\n question tent bar rely arctic volcano long crawl hungry vocal artwork sniff fantasy\n very lucky have athlete'\n deneb_for_epoch: 500\nverifications_epoch_limit: 5\nglobal_client_log_level: info\nmev_type: full\n"})}),"\n",(0,s.jsx)(t.p,{children:"You will use the above file by passing it in at runtime, effectively enabling you to define the way your network should look using parameters."}),"\n",(0,s.jsxs)(t.h4,{id:"launch-the-network-with-full-mev",children:["Launch the network with ",(0,s.jsx)(t.code,{children:"full MEV"})]}),"\n",(0,s.jsx)(t.p,{children:"Great! You're now ready to bring up your own network. Simply run:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'kurtosis run --enclave eth-network github.com/ethpandaops/ethereum-package "$(cat ~/ethereum-package-params.yaml)"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Kurtosis will then begin to spin up your private Ethereum testnet with ",(0,s.jsx)(t.code,{children:"full MEV"}),". You will see a stream of text get printed in your terminal as Kurtosis begins to generate genesis files, configure the Ethereum nodes, launch a Grafana and Prometheus instance, and bootstrap the network together with the full suite of MEV products from Flashbots. In ~2 minutes, you should see the following output at the end:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'Starlark code successfully run. Output was:\n{\n\t"grafana_info": {\n\t\t"dashboard_path": "/d/QdTOwy-nz/ethereum-merge-kurtosis-module-dashboard?orgId=1",\n\t\t"password": "admin",\n\t\t"user": "admin"\n\t}\n}\n\nINFO[2023-08-03T11:16:00+02:00] ====================================================\nINFO[2023-08-03T11:16:00+02:00] || Created enclave: eth-network ||\nINFO[2023-08-03T11:16:00+02:00] ====================================================\nName: eth-network\nUUID: 1d467f353496\nStatus: RUNNING\nCreation Time: Thu, 03 Aug 2023 11:06:50 CEST\n\n========================================= Files Artifacts =========================================\nUUID Name\n004cb2a16def 1-lighthouse
1-geth-0-63\ne98eee4d8a99 2-lighthouse-geth-64-127\n601b49f6e437 cl-forkmon-config\n21192db4c9b4 cl-genesis-data\nfcdd39be227b el-forkmon-config\n38905cf9e831 el-genesis-data\n0ba35b186c20 genesis-generation-config-cl\nb477313c48f4 genesis-generation-config-el\nb119fb95bd44 geth-prefunded-keys\nc4fd103c5447 grafana-config\n122cfb453ebe grafana-dashboards\nb86556fccf74 prometheus-config\n2d2d99849ff0 prysm-password\n\n========================================== User Services ==========================================\nUUID Name Ports Status\n1bde5712f965 cl-1-lighthouse-geth http: 4000/tcp -> http://127.0.0.1:62873 RUNNING\n metrics: 5054/tcp -> http://127.0.0.1:62874\n tcp-discovery: 9000/tcp -> 127.0.0.1:62875\n udp-discovery: 9000/udp -> 127.0.0.1:53993\n57f94044300c cl-1-lighthouse-geth-validator http: 5042/tcp -> 127.0.0.1:62876 RUNNING\n metrics: 5064/tcp -> http://127.0.0.1:62877\nae2d5b824656 cl-2-lighthouse-geth http: 4000/tcp -> http://127.0.0.1:62879 RUNNING\n metrics: 5054/tcp -> http://127.0.0.1:62880\n tcp-discovery: 9000/tcp -> 127.0.0.1:62878\n udp-discovery: 9000/udp -> 127.0.0.1:65058\nc1eb34a91b7e cl-2-lighthouse-geth-validator http: 5042/tcp -> 127.0.0.1:62882 RUNNING\n metrics: 5064/tcp -> http://127.0.0.1:62881\n65e1ae6652c9 cl-forkmon http: 80/tcp -> http://127.0.0.1:62933 RUNNING\ne7f673086384 el-1-geth-lighthouse engine-rpc: 8551/tcp -> 127.0.0.1:62861 RUNNING\n rpc: 8545/tcp -> 127.0.0.1:62863\n tcp-discovery: 30303/tcp -> 127.0.0.1:62862\n udp-discovery: 30303/udp -> 127.0.0.1:56858\n ws: 8546/tcp -> 127.0.0.1:62860\n3048d9aafc12 el-2-geth-lighthouse engine-rpc: 8551/tcp -> 127.0.0.1:62866 RUNNING\n rpc: 8545/tcp -> 127.0.0.1:62864\n tcp-discovery: 30303/tcp -> 127.0.0.1:62867\n udp-discovery: 30303/udp -> 127.0.0.1:62287\n ws: 8546/tcp -> 127.0.0.1:62865\n70e19424c664 el-forkmon http: 8080/tcp -> http://127.0.0.1:62934 RUNNING\nf4bebfdc819b grafana http: 3000/tcp -> http://127.0.0.1:62937 RUNNING\n219954ae8f7e mev-boost-0 api: 18550/tcp -> 127.0.0.1:62931 RUNNING\n287c555090c6 mev-boost-1 api: 18550/tcp -> 127.0.0.1:62932 RUNNING\n2fedae36a1f8 mev-flood <none> RUNNING\nbb163cad3912 mev-relay-api api: 9062/tcp -> 127.0.0.1:62929 RUNNING\n5591d1d17ec5 mev-relay-housekeeper <none> RUNNING\n026f3744c98f mev-relay-website api: 9060/tcp -> 127.0.0.1:62930 RUNNING\n096fdfb33909 postgres postgresql: 5432/tcp -> postgresql://127.0.0.1:62928 RUNNING\nf283002d8c77 prelaunch-data-generator-cl-genesis-data <none> RUNNING\naf010cabc0ce prelaunch-data-generator-el-genesis-data <none> RUNNING\n3fcd033e1d38 prometheus http: 9090/tcp -> http://127.0.0.1:62936 RUNNING\n145b673410f9 redis client: 6379/tcp -> 127.0.0.1:62927 RUNNING\n2172a3e173f8 testnet-verifier <none> RUNNING\nf833b940ae5b transaction-spammer <none> RUNNING\n'})}),"\n",(0,s.jsxs)(t.p,{children:["As you can see above, there is ",(0,s.jsx)(t.em,{children:"a lot"})," going on in your enclave - but don't worry, let's go through everything together."]}),"\n",(0,s.jsxs)(t.p,{children:["The first section that gets printed contains some basic metadata about the enclave that was spun up. This includes the name of the enclave ",(0,s.jsx)(t.code,{children:"eth-network"}),", its ",(0,s.jsx)(t.a,{href:"https://docs.kurtosis.com/advanced-concepts/resource-identifier/",children:"Resource Idenfitier"}),", your enclave's status, and the time it was created."]}),"\n",(0,s.jsxs)(t.p,{children:["Next, you'll see a section dedicated to ",(0,s.jsx)(t.a,{href:"https://docs.kurtosis.com/advanced-concepts/files-artifacts/",children:"Files Artifacts"}),", which are Kurtosis' first-class representation of data inside your enclave, stored as compressed TGZ files. You'll notice there are configuration files for the nodes, grafana, and prometheus as well as private keys for pre-funded accounts and genesis-related data. These files artifacts were generated and used by Kurtosis to start the network and abstracts away the complexities and overhead that come with generating validator keys and getting genesis and node config files produced and mounted to the right containers yourself."]}
1),"\n",(0,s.jsxs)(t.p,{children:["Lastly, there is a section called ",(0,s.jsx)(t.code,{children:"User Services"})," which display the number of services (running in Docker containers) that make up your network. You will notice that there are 2 Ethereum nodes, each with a ",(0,s.jsx)(t.code,{children:"MEV-Boost"})," instance spun up & connected to it. In addition to this, you will see the rest of the Flashbots MEV infrastructure including the ",(0,s.jsx)(t.code,{children:"mev-relay"})," suite of services (read more about the ",(0,s.jsx)(t.code,{children:"mev-relay"})," services ",(0,s.jsx)(t.a,{href:"https://github.com/flashbots/mev-boost-relay/blob/main/ARCHITECTURE.md",children:"here"}),") and ",(0,s.jsx)(t.code,{children:"mev-flood"}),". By default, the ",(0,s.jsx)(t.code,{children:"ethereum-package"})," also comes with supporting services which include a fork monitor, redis, postgres, grafana, prometheus, a transaction spammer, a testnet-verifier, and the services used to generate genesis data. Both of the Redis and Postgres instances are required for ",(0,s.jsx)(t.code,{children:"mev-relay"})," to function properly. Each of these services are running in Docker containers inside your local enclave & Kurtosis has automatically mapped each container port to your machine's ephemeral ports for seamless interaction with the services running in your enclave."]}),"\n",(0,s.jsx)(t.h4,{id:"visit-the-website-to-see-registered-validators-and-delivered-payloads",children:"Visit the website to see registered validators and delivered payloads"}),"\n",(0,s.jsxs)(t.p,{children:["Now that your network is online, you can visit the relay website using the local port mapped to that endpoint. For this example, it will be ",(0,s.jsx)(t.code,{children:"127.0.0.1:62930"}),", but it will be different for you."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"flashbots-website",src:n(2408).A+"",width:"2434",height:"2394"})}),"\n",(0,s.jsxs)(t.p,{children:["The screenshot above is what the website looks like after the 4th epoch. You can see that all 128 validators (2 nodes, each with 64 validators) are registered. The table below will display recently delivered and verified payloads from ",(0,s.jsx)(t.code,{children:"mev-relay"})," to the ",(0,s.jsx)(t.code,{children:"mev-boost"})," sidecar on each node."]}),"\n",(0,s.jsx)(t.p,{children:"And there you have it! You've now spun up a private Ethereum testnet over Docker with the Flashbot's implementation of PBS!"}),"\n",(0,s.jsx)(t.h2,{id:"roadmap",children:"Roadmap"}),"\n",(0,s.jsx)(t.p,{children:"The inclusion of a Proposer Builder Separation (PBS) implemention was in support of the Ethereum Foundation's efforts to validate functionality and behavior in end-to-end testing (between in-protocol and out-of-protocol infrastructure), as well as the functionality of the beacon chain for in-protocol code paths (e.g. can clients: call for payloads reject invalid payloads, and trigger the circuit breaker when necessary)."}),"\n",(0,s.jsxs)(t.p,{children:["The next immediate thing we hope to do is to ",(0,s.jsx)(t.em,{children:"decompose"})," the environment definition into smaller pieces, enabling developers to build-their-own MEV-enabled systems by simply importing only the parts of the MEV infrastructure that they need. We've begun working on this already with ",(0,s.jsx)(t.a,{href:"https://github.com/kurtosis-tech/eth-kurtosis",children:"eth-kurtosis"}),", which contains an index of composable building blocks to define your own testnet."]}),"\n",(0,s.jsxs)(t.p,{children:["If there are other use cases you had in mind (e.g. fuzzing the network at the protocol level) or have questions about ",(0,s.jsx)(t.code,{children:"eth-kurtosis"})," or this ",(0,s.jsx)(t.code,{children:"ethereum-package"}),", please don't hesitate to reach out!"]}),"\n",(0,s.jsx)(t.h2,{id:"conclusion",children:"Conclusion"}),"\n",(0,s.jsx)(t.p,{children:"This guide was meant to be quick - we hope it was. To recap, you:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Installed Kurtosis and Docker"}),"\n",(0,s.jsxs)(t.li,{children:["Created a ",(0,s.jsx)(t.code,{children:".yaml"})," file that contains the necessary parameters for the network"]}),"\n",(0,s.jsx)(t.li,{children:"Ran a single command to spin up a private Ethereum testnet with MEV infrastru
1cture"}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"ethereum-package"})," is available for anyone to use, will work the same way on your local machine or in the cloud, and will run on Docker or Kubernetes."]}),"\n",(0,s.jsx)(t.p,{children:"You saw first-hand how packages, effectively environment definitions, are written once and then can be used by anyone in a very trivial way to reproduce the environment. This accelerates developer velocity by enabling engineers to spend less time on configuring and setting up development and testing frameworks, and more time instead on building the unique features and capabilities for their projects."}),"\n",(0,s.jsxs)(t.p,{children:["Additionally, we hope you also enjoyed the parameterizability aspect of Kurtosis Packages. By changing the ",(0,s.jsx)(t.code,{children:"ethereum-package-params.yaml"}),", you can get a fine-tune your testnet however you see fit."]}),"\n",(0,s.jsxs)(t.p,{children:["We hope this guide was helpful and we'd love to hear from you. Please don't hesitate to share with us what went well, and what didn't, using ",(0,s.jsx)(t.a,{href:"/feedback",children:(0,s.jsx)(t.code,{children:"kurtosis feedback"})})," from the CLI to file an issue in our ",(0,s.jsx)(t.a,{href:"https://github.com/kurtosis-tech/eth-kurtosis/issues",children:"Github"})," or post your question in our ",(0,s.jsx)(t.a,{href:"https://github.com/kurtosis-tech/kurtosis/discussions",children:"Github Discussions"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"Thank you!"})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},2408(e,t,n){n.d(t,{A:()=>o});const o=n.p+"assets/images/full-mev-flashbots-website-30cc561411ed5babf6029d5a4d7fe4e9.png"},1897(e,t,n){n.d(t,{A:()=>o});const o=n.p+"assets/images/full-mev-infra-arch-diagram-ee260244eb30c7ba12e3013f9775d88e.png"},8453(e,t,n){n.d(t,{R:()=>r,x:()=>a});var o=n(6540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.