From 60f8147d27615d1bbc95faeb2905d5849a37566c Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Thu, 19 Oct 2023 18:04:05 -0600 Subject: [PATCH 1/2] add utility to get a recent signed bid from a relay --- Cargo.lock | 13 +++++++++++++ Cargo.toml | 9 ++++++++- bin/utils/Cargo.toml | 19 +++++++++++++++++++ bin/utils/LICENSE-APACHE | 1 + bin/utils/LICENSE-MIT | 1 + bin/utils/src/main.rs | 28 ++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 bin/utils/Cargo.toml create mode 120000 bin/utils/LICENSE-APACHE create mode 120000 bin/utils/LICENSE-MIT create mode 100644 bin/utils/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 35f6dfed..68794300 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4418,6 +4418,19 @@ dependencies = [ "url", ] +[[package]] +name = "mev-utils" +version = "0.3.0" +dependencies = [ + "beacon-api-client", + "ethereum-consensus", + "mev-rs", + "serde", + "serde_json", + "tokio", + "url", +] + [[package]] name = "mime" version = "0.3.17" diff --git a/Cargo.toml b/Cargo.toml index 5b87a762..878edf16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,13 @@ [workspace] resolver = "2" -members = ["bin/mev", "mev-boost-rs", "mev-relay-rs", "mev-build-rs", "mev-rs"] +members = [ + "bin/mev", + "bin/utils", + "mev-boost-rs", + "mev-relay-rs", + "mev-build-rs", + "mev-rs", +] default-members = ["bin/mev"] [workspace.package] diff --git a/bin/utils/Cargo.toml b/bin/utils/Cargo.toml new file mode 100644 index 00000000..478f2948 --- /dev/null +++ b/bin/utils/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "mev-utils" +version.workspace = true +edition = "2021" +license = "MIT OR Apache-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tokio = { version = "1.0", features = ["full"] } +url = { version = "2.2.2", default-features = false } + +mev-rs = { path = "../../mev-rs" } + +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1.0.92" } + +ethereum-consensus = { workspace = true } +beacon-api-client = { workspace = true } diff --git a/bin/utils/LICENSE-APACHE b/bin/utils/LICENSE-APACHE new file mode 120000 index 00000000..9419c222 --- /dev/null +++ b/bin/utils/LICENSE-APACHE @@ -0,0 +1 @@ +../mev/LICENSE-APACHE \ No newline at end of file diff --git a/bin/utils/LICENSE-MIT b/bin/utils/LICENSE-MIT new file mode 120000 index 00000000..4b882429 --- /dev/null +++ b/bin/utils/LICENSE-MIT @@ -0,0 +1 @@ +../mev/LICENSE-MIT \ No newline at end of file diff --git a/bin/utils/src/main.rs b/bin/utils/src/main.rs new file mode 100644 index 00000000..c02cff31 --- /dev/null +++ b/bin/utils/src/main.rs @@ -0,0 +1,28 @@ +use beacon_api_client::{mainnet::Client, BlockId}; +use mev_rs::{types::BidRequest, BlindedBlockRelayer, Relay, RelayEndpoint}; +use url::Url; + +#[tokio::main] +async fn main() { + let endpoint = Url::parse("http://localhost:5052").unwrap(); + let beacon_node = Client::new(endpoint); + let id = BlockId::Head; + let signed_block = beacon_node.get_beacon_block(id).await.unwrap(); + let slot = signed_block.message().slot() + 1; + let parent_hash = + signed_block.message().body().execution_payload().unwrap().block_hash().clone(); + + let url = Url::parse("https://0x845bd072b7cd566f02faeb0a4033ce9399e42839ced64e8b2adcfc859ed1e8e1a5a293336a49feac6d9a5edb779be53a@boost-relay-sepolia.flashbots.net/").unwrap(); + let relay_endpoint = RelayEndpoint::try_from(url).unwrap(); + let relay = Relay::try_from(relay_endpoint).unwrap(); + let schedules = relay.get_proposal_schedule().await.unwrap(); + for schedule in schedules { + if schedule.slot == slot { + let public_key = schedule.entry.message.public_key; + let bid_request = BidRequest { slot, parent_hash: parent_hash.clone(), public_key }; + let signed_bid = relay.fetch_best_bid(&bid_request).await.unwrap(); + let signed_bid_str = serde_json::to_string_pretty(&signed_bid).unwrap(); + println!("{signed_bid_str}"); + } + } +} From c9e58957ee0d7c613cb0828875fe8917d6e41f99 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Thu, 19 Oct 2023 18:04:53 -0600 Subject: [PATCH 2/2] update dep for bug fix and add test for signature verification --- Cargo.lock | 4 +-- Cargo.toml | 4 +-- mev-rs/src/types/builder_bid.rs | 59 +++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68794300..138fdad2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -713,7 +713,7 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "beacon-api-client" version = "0.1.0" -source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=c84f44ee7ec04613adf5f2be845df35e05de1efc#c84f44ee7ec04613adf5f2be845df35e05de1efc" +source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=69d1a14585ef190bf32979a972a9794e863ee18d#69d1a14585ef190bf32979a972a9794e863ee18d" dependencies = [ "clap", "ethereum-consensus", @@ -2392,7 +2392,7 @@ dependencies = [ [[package]] name = "ethereum-consensus" version = "0.1.1" -source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=c84f44ee7ec04613adf5f2be845df35e05de1efc#c84f44ee7ec04613adf5f2be845df35e05de1efc" +source = "git+https://github.com/ralexstokes/ethereum-consensus?rev=69d1a14585ef190bf32979a972a9794e863ee18d#69d1a14585ef190bf32979a972a9794e863ee18d" dependencies = [ "async-stream", "blst", diff --git a/Cargo.toml b/Cargo.toml index 878edf16..9dfc7683 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,8 +14,8 @@ default-members = ["bin/mev"] version = "0.3.0" [workspace.dependencies] -ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "c84f44ee7ec04613adf5f2be845df35e05de1efc" } -beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "c84f44ee7ec04613adf5f2be845df35e05de1efc" } +ethereum-consensus = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "69d1a14585ef190bf32979a972a9794e863ee18d" } +beacon-api-client = { git = "https://github.com/ralexstokes/ethereum-consensus", rev = "69d1a14585ef190bf32979a972a9794e863ee18d" } reth-payload-builder = { git = "https://github.com/paradigmxyz/reth", rev = "5dd5555c5c7d8e43420e273e7005b8af63a847a5" } reth-primitives = { git = "https://github.com/paradigmxyz/reth", rev = "5dd5555c5c7d8e43420e273e7005b8af63a847a5" } diff --git a/mev-rs/src/types/builder_bid.rs b/mev-rs/src/types/builder_bid.rs index 87b6e293..3e2aaf72 100644 --- a/mev-rs/src/types/builder_bid.rs +++ b/mev-rs/src/types/builder_bid.rs @@ -57,3 +57,62 @@ impl SignedBuilderBid { verify_signature(public_key, signing_root.as_ref(), &self.signature) } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::signing::sign_builder_message; + use ethereum_consensus::{crypto::SecretKey, state_transition::Context}; + use rand::prelude::*; + + const SIGNED_BUILDER_BID_JSON: &str = r#" + { + "message": { + "header": { + "parent_hash": "0xac6e636151a5c90dd7179b5ca62c1e759dd75505ba95d060b9ea2a8e342f88f4", + "fee_recipient": "0x1e2cd78882b12d3954a049fd82ffd691565dc0a5", + "state_root": "0x223c37043a5c9ab328fef7d2a58bc01da7f994252eb552343b97faf6e647d633", + "receipts_root": "0x8b0f90f0a7ad8e3135f9b95d9234c84a4a0440ab8df18327bab6bbc6a5d9efe5", + "logs_bloom": "0x40000008081200020008100002000000042040100420000000000000000000000004000800240000040001000008400010820400004000000801210800648120000100504002042000000008080180020000100000244200080000000004002808100040020008000281008000000810100500000010000000000010000000000080000000a0000020020080404060000001001800800810081000028c50002102084000080000020000030000040018100060000040000000401010240000000400000a0000101000020000008060002008100000a0000002008400000060000096000000200010000000000000980010804508000000080000010200200840", + "prev_randao": "0x5e93d21bf689fd1c293a85dbb93681383867abe057375890a251404bda3417f9", + "block_number": "4522537", + "gas_limit": "30000000", + "gas_used": "4483564", + "timestamp": "1697757948", + "extra_data": "0x496c6c756d696e61746520446d6f63726174697a6520447374726962757465", + "base_fee_per_gas": "9", + "block_hash": "0xf0029e1f18f5bc8944c9ce4453d93f1772e3ac6626470024c8def699271def2e", + "transactions_root": "0xbf12054777b89c3a25b78281604fc99d5e55cb9fedafcce4dc688779f65197ee", + "withdrawals_root": "0xa427d204f34246cdec36b4db9a94f25e08a5be2f7e670ff3072ceb241e8934f6" + }, + "value": "2591493712581794", + "pubkey": "0x845bd072b7cd566f02faeb0a4033ce9399e42839ced64e8b2adcfc859ed1e8e1a5a293336a49feac6d9a5edb779be53a" + }, + "signature": "0xafb17f2861b808f4728bbc31aeaa36e9b86465ff08fc3a4ccfd302403b48dfe8fc12cfe30349d95822142668187882f0000fc1ea5ae30ea0c6f44d8d3a535f1945d10b7954642a52dec65fbe929e6b09b626c19318e88cea99c38b414589c6f1" + } + "#; + + #[test] + fn test_builder_bid_signature() { + let mut rng = thread_rng(); + let key = SecretKey::random(&mut rng).unwrap(); + let public_key = key.public_key(); + let mut builder_bid = BuilderBid { + header: ExecutionPayloadHeader::Deneb(Default::default()), + value: U256::from(234234), + public_key, + }; + let context = Context::for_holesky(); + let signature = sign_builder_message(&mut builder_bid, &key, &context).unwrap(); + let mut signed_builder_bid = SignedBuilderBid { message: builder_bid, signature }; + signed_builder_bid.verify_signature(&context).expect("is valid signature"); + } + + #[test] + fn test_builder_bid_signature_from_relay() { + let mut signed_builder_bid: SignedBuilderBid = + serde_json::from_str(SIGNED_BUILDER_BID_JSON.trim()).unwrap(); + let context = Context::for_sepolia(); + signed_builder_bid.verify_signature(&context).expect("is valid signature"); + } +}