diff --git a/Cargo.lock b/Cargo.lock index 789ae78..3f75dc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,9 +97,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f07ea118327e6ff9a1cba5ae26c0a9a9744bec1dd6734ed75b5b46fc9be6d077" +checksum = "c62f44203459c0fdeae67338c2b264c761c614d460feca0b0a230058435e3c1d" dependencies = [ "alloy-consensus", "alloy-contract", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86debde32d8dbb0ab29e7cc75ae1a98688ac7a4c9da54b3a9b14593b9b3c46d3" +checksum = "c622b1418d86afba7116e2617280859d4a2737e06e6e4dd4694a7a96ae8aff79" dependencies = [ "alloy-eips", "alloy-primitives", @@ -167,9 +167,9 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d6cb2e7efd385b333f5a77b71baaa2605f7e22f1d583f2879543b54cbce777c" +checksum = "90eeb45e8554a35ade97344552df4f6cdb000a53da955916f573b1998a81f791" dependencies = [ "alloy-consensus", "alloy-eips", @@ -182,9 +182,9 @@ dependencies = [ [[package]] name = "alloy-contract" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668859fcdb42eee289de22a9d01758c910955bb6ecda675b97276f99ce2e16b0" +checksum = "363d9d618d98952b07e50defdf3f8bc59ae24b7ba6161397a2e380370fd3ebf3" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -296,9 +296,9 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be47bf1b91674a5f394b9ed3c691d764fb58ba43937f1371550ff4bc8e59c295" +checksum = "2cbd6558e8a2fe9de811faae7ccc0b3d2a4c71b1cd77e57e5c89cba20693420b" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a59f6f520c323111650d319451de1edb1e32760029a468105b9d7b0f7c11bdf2" +checksum = "91dd00b84d8c9b9fd055254a147e4521cca0a8f19da808fd3376e4bd6f292d43" dependencies = [ "alloy-eips", "alloy-primitives", @@ -398,9 +398,9 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a24c81a56d684f525cd1c012619815ad3a1dd13b0238f069356795d84647d3c" +checksum = "95ae5cbb425b6e72f99e24860506809e4908113b76ede8de1333996edccbf38c" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -413,9 +413,9 @@ dependencies = [ [[package]] name = "alloy-network" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786c5b3ad530eaf43cda450f973fe7fb1c127b4c8990adf66709dafca25e3f6f" +checksum = "5abea24fba6bfb859954d1ebfaaebf77886b802ec559cbe7fd16f992a31d41ec" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -439,9 +439,9 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ed40adf21ae4be786ef5eb62db9c692f6a30f86d34452ca3f849d6390ce319" +checksum = "905f7628888eed587274dbea536168f64f6a401b377cd77b9fe91866ce1478a0" dependencies = [ "alloy-consensus", "alloy-eips", @@ -452,9 +452,9 @@ dependencies = [ [[package]] name = "alloy-node-bindings" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0f15cffc63c421d33d77f6d30d7d18ef090a44ecf32205f5bfa12d4e565360a" +checksum = "d60ff34bfb17d2401381b8f177257bcda467d77eb26c7f4084695923d41b5821" dependencies = [ "alloy-genesis", "alloy-hardforks 0.2.13", @@ -505,9 +505,9 @@ dependencies = [ [[package]] name = "alloy-provider" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ca4c15818be7ac86208aff3a91b951d14c24e1426e66624e75f2215ba5e2cc" +checksum = "991d0ccc0ed7a1d083e96f251627ad6d551769cff7ad2d07b0d0b335e99cba63" dependencies = [ "alloy-chains", "alloy-consensus", @@ -554,9 +554,9 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9eb9c9371738ac47f589e40aae6e418cb5f7436ad25b87575a7f94a60ccf43b" +checksum = "295dba19c629c431554f4e2918b43bf02bce7464990631e67304e2a3362d9c3f" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -598,9 +598,9 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe0addad5b8197e851062b49dc47157444bced173b601d91e3f9b561a060a50" +checksum = "edc1343d06dd354cee121763e7fb243db3b7962d747df0c231ce13c249f48efd" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -624,9 +624,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d17d4645a717f0527e491f44f6f7a75c221b9c00ccf79ddba2d26c8e0df4c3" +checksum = "03c4079f59cc4753389e2eb0e20cd2a98ddfc58f8bcec33b98d86e8d8c701f82" dependencies = [ "alloy-primitives", "alloy-rpc-types-anvil", @@ -643,9 +643,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-admin" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded79e60d8fd0d7c851044f8b2f2dd7fa8dfa467c577d620595d4de3c31eff7e" +checksum = "ebf8f659abddbafb74dab174204aa4e9e2785425bd3899eb948d1d9fae2c9bfd" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -655,9 +655,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-anvil" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593ce5e1fd416e3b094e7671ef361f22e6944545e0e62ee309b6dfbd702225d" +checksum = "a816be17cfbcb36a08a8b88bc2157ee1aa2ea258fb2c48a5ba6a3e3729a7f031" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -667,9 +667,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0e98aabb013a71a4b67b52825f7b503e5bb6057fb3b7b2290d514b0b0574b57" +checksum = "8405d1a23dbd570679196289c9c6ea23e8f3d69f24a9a942002a45bb4b2a844c" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -678,9 +678,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-beacon" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a647a4e3acf49182135c2333d6f9b11ab8684559ff43ef1958ed762cfe9fe0e" +checksum = "645d3eafd5b909d23e6248ecaadbaf66f464db5097a5794615784c1370df12bf" dependencies = [ "alloy-eips", "alloy-primitives", @@ -698,9 +698,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-debug" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a1dd760b6a798ee045ab6a7bbd1a02ad8bd6a64d8e18d6e41732f4fc4a4fe5c" +checksum = "4ca2e88ed4e5e88955d5988eb32b9c5483912a3af7936436b0e5f5f3da512880" dependencies = [ "alloy-primitives", "derive_more", @@ -710,9 +710,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-engine" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc871ae69688e358cf242a6a7ee6b6e0476a03fd0256434c68daedaec086ec4" +checksum = "fc7bf1ae6bf74b82e033888db62466cde2cd279ca9ff601b601f5b315314fb4e" dependencies = [ "alloy-consensus", "alloy-eips", @@ -731,9 +731,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5899af8417dcf89f40f88fa3bdb2f3f172605d8e167234311ee34811bbfdb0bf" +checksum = "9be559930a667c9343b1f21179be4f1a5a345c8caf7ef506eb216ad507de4ffb" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -753,9 +753,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-mev" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4c9229424e77bd97e629fba44dbfdadebe5bfadbb1e53ad4acbc955610b6c7" +checksum = "da494d19924be84bbeeacd1c77ce117b67f8db46fd784a046db2cc26f3ffa407" dependencies = [ "alloy-consensus", "alloy-eips", @@ -768,9 +768,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-trace" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410a80e9ac786a2d885adfd7da3568e8f392da106cb5432f00eb4787689d281a" +checksum = "2fc955f47f331437ee9072a486088bdd2ee8230eea4df059566108fc900896ca" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -782,9 +782,9 @@ dependencies = [ [[package]] name = "alloy-rpc-types-txpool" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8074654c0292783d504bfa1f2691a69f420154ee9a7883f9212eaf611e60cd" +checksum = "3820522d80137bac38db35ad7af40c275fdce107c7ba25fd94659b53e3d46768" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -794,9 +794,9 @@ dependencies = [ [[package]] name = "alloy-serde" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb73325ee881e42972a5a7bc85250f6af89f92c6ad1222285f74384a203abeb" +checksum = "617076af047ac9ffec0e8a3ef48fccbf6eb9d5aee6b302476346f729e469c804" dependencies = [ "alloy-primitives", "arbitrary", @@ -806,9 +806,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bea4c8f30eddb11d7ab56e83e49c814655daa78ca708df26c300c10d0189cbc" +checksum = "3540dd7ff91763cd60760438442a10392f8f04f41fb3c4981323f3c34d96ccb2" dependencies = [ "alloy-primitives", "async-trait", @@ -821,9 +821,9 @@ dependencies = [ [[package]] name = "alloy-signer-aws" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f6ae79701edb2c21b5f9ff007ae0228168b36e5ca25a20873b2db2cda4ad31" +checksum = "6c9cdc832ab4353af07656e4dfc2c2bc59264a424f90f4a6cee6bd1caa0a8af4" dependencies = [ "alloy-consensus", "alloy-network", @@ -840,9 +840,9 @@ dependencies = [ [[package]] name = "alloy-signer-local" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28bd71507db58477151a6fe6988fa62a4b778df0f166c3e3e1ef11d059fe5fa" +checksum = "a382f4fc60d1155fa684fe68870e18a265043b0f3a11c7a2b5072447cb5fbafc" dependencies = [ "alloy-consensus", "alloy-network", @@ -932,9 +932,9 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b321f506bd67a434aae8e8a7dfe5373bf66137c149a5f09c9e7dfb0ca43d7c91" +checksum = "6ac0e7b6ebe03a97143d0bae318212b876306d669cc9b25071184d2e85877b4a" dependencies = [ "alloy-json-rpc", "auto_impl", @@ -955,12 +955,13 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bf12879a20e1261cd39c3b101856f52d18886907a826e102538897f0d2b66e" +checksum = "a19f6f46ab490750059b0d32ce74323ebe7bb6d8137073523dfef754c3af2252" dependencies = [ "alloy-json-rpc", "alloy-transport", + "itertools 0.14.0", "reqwest", "serde_json", "tower", @@ -970,9 +971,9 @@ dependencies = [ [[package]] name = "alloy-transport-ipc" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75f2334d400249e9672a1ec402536bab259e27a66201a94c3c9b3f1d3bae241" +checksum = "8e0b477248bf29d1a990a10bc8ab494a7f39c3d1720bb1d6c8eae4649a28df56" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -990,9 +991,9 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a0d9c8bbc5c3215b03ad465d4ae8775384ff5faec7c41f033f087c851a9f9" +checksum = "4feacef4309079e77763aaa6581090c748500a56faae3edb5928464ec3c0f769" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -1028,9 +1029,9 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.6.1" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a91d6b4c2f6574fdbcb1611e460455c326667cf5b805c6bd1640dad8e8ee4d2" +checksum = "5f5bfa1887d55418bd22c922c5ae679f2c0dbda5cba03d1300bd7299e9602350" dependencies = [ "darling 0.21.3", "proc-macro2", @@ -4949,9 +4950,9 @@ dependencies = [ [[package]] name = "init4-bin-base" -version = "0.18.0-rc.8" +version = "0.18.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185fbd1b6320603134ec222356f6014806e589a1ef73532882609fa23766b5cd" +checksum = "9fe89ed003118f165bd3a1a9dc49b25417766b7f52fd87c380d425b8ea0ff60f" dependencies = [ "alloy", "async-trait", @@ -7185,9 +7186,9 @@ dependencies = [ [[package]] name = "rapidhash" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71ec30b38a417407efe7676bad0ca6b78f995f810185ece9af3bd5dc561185a9" +checksum = "84816e4c99c467e92cf984ee6328caa976dfecd33a673544489d79ca2caaefe5" dependencies = [ "rand 0.9.2", "rustversion", @@ -10543,9 +10544,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "ryu-js" @@ -12289,9 +12290,9 @@ checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" [[package]] name = "unicode-segmentation" @@ -13376,9 +13377,9 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445" +checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 43c7034..da5b0eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ name = "zenith-builder-example" path = "bin/builder.rs" [dependencies] -init4-bin-base = { version = "0.18.0-rc.8", features = ["perms", "aws"] } +init4-bin-base = { version = "0.18.0-rc.9", features = ["perms", "aws", "pylon"] } signet-constants = { version = "0.16.0-rc.8" } signet-sim = { version = "0.16.0-rc.8" } diff --git a/src/config.rs b/src/config.rs index 1296ccc..79c125a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -12,7 +12,7 @@ use alloy::{ }; use eyre::Result; use init4_bin_base::{ - perms::{Authenticator, OAuthConfig, SharedToken}, + perms::{Authenticator, OAuthConfig, SharedToken, pylon}, utils::{ calc::SlotCalculator, from_env::FromEnv, @@ -25,6 +25,9 @@ use signet_zenith::Zenith; use std::borrow::Cow; use tokio::join; +/// Pylon client type for blob sidecar submission. +pub type PylonClient = pylon::PylonClient; + /// Type alias for the provider used to simulate against rollup state. pub type RuProvider = RootProvider; @@ -168,6 +171,10 @@ pub struct BuilderConfig { /// The signet system constants. pub constants: SignetSystemConstants, + + /// URL for the Pylon blob server API. + #[from_env(var = "PYLON_URL", desc = "URL for the Pylon blob server API")] + pub pylon_url: url::Url, } impl BuilderConfig { @@ -285,4 +292,9 @@ impl BuilderConfig { ((gas_limit as u128 * (self.max_host_gas_coefficient.unwrap_or(80) as u128)) / 100u128) as u64 } + + /// Connect to the Pylon blob server. + pub fn connect_pylon(&self) -> PylonClient { + PylonClient::new(self.pylon_url.clone(), self.oauth_token()) + } } diff --git a/src/tasks/block/sim.rs b/src/tasks/block/sim.rs index 3963dc4..ea3cfe3 100644 --- a/src/tasks/block/sim.rs +++ b/src/tasks/block/sim.rs @@ -5,7 +5,7 @@ use crate::{ config::{BuilderConfig, HostProvider, RuProvider}, tasks::env::SimEnv, }; -use alloy::consensus::Header; +use alloy::{consensus::Header, eips::Encodable2718, primitives::Bytes}; use init4_bin_base::{ deps::metrics::{counter, histogram}, utils::calc::SlotCalculator, @@ -62,6 +62,21 @@ impl SimResult { pub fn clone_span(&self) -> Span { self.sim_env.clone_span() } + + /// Constructs the MEV bundle body from host transactions and the submission transaction. + /// + /// Combines all host transactions from the rollup block with the prepared rollup block + /// submission transaction, wrapping each as a non-revertible bundle item. + /// + /// The rollup block transaction is always included and placed last in the bundle. + pub fn build_bundle_body(&self, block_tx_bytes: Bytes) -> Vec { + self.block + .host_transactions() + .iter() + .map(|tx| tx.encoded_2718().into()) + .chain(std::iter::once(block_tx_bytes)) + .collect() + } } /// A task that builds blocks based on incoming [`SimEnv`]s and a simulation diff --git a/src/tasks/cache/bundle.rs b/src/tasks/cache/bundle.rs index eed8850..7039581 100644 --- a/src/tasks/cache/bundle.rs +++ b/src/tasks/cache/bundle.rs @@ -1,6 +1,6 @@ //! Bundler service responsible for fetching bundles and sending them to the simulator. use crate::config::BuilderConfig; -use init4_bin_base::perms::tx_cache::BuilderTxCache; +use init4_bin_base::perms::tx_cache::{BuilderTxCache, BuilderTxCacheError}; use signet_tx_cache::{TxCacheError, types::TxCacheBundle}; use tokio::{ sync::mpsc::{UnboundedReceiver, UnboundedSender, unbounded_channel}, @@ -51,7 +51,7 @@ impl BundlePoller { } /// Checks the bundle cache for new bundles. - pub async fn check_bundle_cache(&self) -> Result, TxCacheError> { + pub async fn check_bundle_cache(&self) -> Result, BuilderTxCacheError> { let res = self.tx_cache.get_bundles(None).await; match res { @@ -59,12 +59,12 @@ impl BundlePoller { trace!(count = ?bundles.bundles.len(), "found bundles"); Ok(bundles.bundles) } - Err(TxCacheError::NotOurSlot) => { - trace!("Not our slot to fetch bundles"); - Err(TxCacheError::NotOurSlot) - } Err(err) => { - error!(?err, "Failed to fetch bundles from tx-cache"); + if matches!(&err, BuilderTxCacheError::TxCache(TxCacheError::NotOurSlot)) { + trace!("Not our slot to fetch bundles"); + } else { + error!(?err, "Failed to fetch bundles from tx-cache"); + } Err(err) } } diff --git a/src/tasks/submit/flashbots.rs b/src/tasks/submit/flashbots.rs index 6b3d998..8e70f66 100644 --- a/src/tasks/submit/flashbots.rs +++ b/src/tasks/submit/flashbots.rs @@ -1,15 +1,12 @@ //! Flashbots Task receives simulated blocks from an upstream channel and //! submits them to the Flashbots relay as bundles. use crate::{ - config::{BuilderConfig, FlashbotsProvider, HostProvider, ZenithInstance}, + config::{BuilderConfig, FlashbotsProvider, HostProvider, PylonClient, ZenithInstance}, quincey::Quincey, tasks::{block::sim::SimResult, submit::SubmitPrep}, }; use alloy::{ - consensus::TxEnvelope, - eips::Encodable2718, - primitives::{Bytes, TxHash}, - providers::ext::MevApi, + consensus::TxEnvelope, eips::Encodable2718, primitives::TxHash, providers::ext::MevApi, rpc::types::mev::EthSendBundle, }; use init4_bin_base::{deps::metrics::counter, utils::signer::LocalOrAws}; @@ -32,6 +29,8 @@ pub struct FlashbotsTask { signer: LocalOrAws, /// Channel for sending hashes of outbound transactions. outbound: mpsc::UnboundedSender, + /// Pylon client for blob sidecar submission. + pylon: PylonClient, } impl FlashbotsTask { @@ -48,8 +47,9 @@ impl FlashbotsTask { )?; let zenith = config.connect_zenith(host_provider); + let pylon = config.connect_pylon(); - Ok(Self { config, quincey, zenith, flashbots, signer: builder_key, outbound }) + Ok(Self { config, quincey, zenith, flashbots, signer: builder_key, outbound, pylon }) } /// Prepares a MEV bundle from a simulation result. @@ -81,7 +81,7 @@ impl FlashbotsTask { let tx_bytes = block_tx.encoded_2718().into(); // Build the bundle body with the block_tx bytes as the last transaction in the bundle. - let txs = self.build_bundle_body(sim_result, tx_bytes); + let txs = sim_result.build_bundle_body(tx_bytes); // Create the MEV bundle (valid only in the specific host block) Ok(EthSendBundle { @@ -90,7 +90,6 @@ impl FlashbotsTask { ..Default::default() }) } - /// Prepares and signs the submission transaction for the rollup block. /// /// Creates a `SubmitPrep` instance to build the transaction, then fills @@ -130,26 +129,6 @@ impl FlashbotsTask { } } - /// Constructs the MEV bundle body from host transactions and the submission transaction. - /// - /// Combines all host transactions from the rollup block with the prepared rollup block - /// submission transaction, wrapping each as a non-revertible bundle item. - /// - /// The rollup block transaction is placed last in the bundle. - fn build_bundle_body( - &self, - sim_result: &SimResult, - tx_bytes: alloy::primitives::Bytes, - ) -> Vec { - sim_result - .block - .host_transactions() - .iter() - .map(|tx| tx.encoded_2718().into()) - .chain(std::iter::once(tx_bytes)) - .collect() - } - /// Main task loop that processes simulation results and submits bundles to Flashbots. /// /// Receives `SimResult`s from the inbound channel, prepares MEV bundles, and submits @@ -176,7 +155,6 @@ impl FlashbotsTask { // Prepare a MEV bundle with the configured call type from the sim result let result = self.prepare(&sim_result).instrument(span.clone()).await; - let bundle = match result { Ok(bundle) => bundle, Err(error) => { @@ -186,6 +164,10 @@ impl FlashbotsTask { } }; + // Due to the way the bundle is built, the block transaction is the last transaction in the bundle, and will always exist. + // We'll use this to forward the tx to pylon, which will preload the sidecar. + let block_tx = bundle.txs.last().unwrap().clone(); + // Make a child span to cover submission, or use the current span // if debug is not enabled. let _guard = span.enter(); @@ -193,9 +175,10 @@ impl FlashbotsTask { // Send the bundle to Flashbots, instrumenting the send future so // all events inside the async send are attributed to the submit - // span. + // span. If Flashbots accepts it, submit the envelope to Pylon. let flashbots = self.flashbots().to_owned(); let signer = self.signer.clone(); + let pylon = self.pylon.clone(); tokio::spawn( async move { @@ -209,6 +192,19 @@ impl FlashbotsTask { hash = resp.map(|r| r.bundle_hash.to_string()), "Submitted MEV bundle to Flashbots, received OK response" ); + + match pylon.post_blob_tx(block_tx).await { + Ok(()) => { + counter!("signet.builder.pylon.sidecars_submitted") + .increment(1); + debug!("posted sidecar to pylon"); + } + Err(err) => { + counter!("signet.builder.pylon.submission_failures") + .increment(1); + error!(%err, "pylon submission failed"); + } + } } Err(err) => { counter!("signet.builder.flashbots.submission_failures").increment(1); diff --git a/src/test_utils.rs b/src/test_utils.rs index cb9d3e7..20119f4 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -56,6 +56,7 @@ pub fn setup_test_config() -> &'static BuilderConfig { block_query_cutoff_buffer: 3000, max_host_gas_coefficient: Some(80), constants: SignetSystemConstants::parmigiana(), + pylon_url: "http://localhost:8081".parse().unwrap(), } }) }