diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f66a480 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +FROM docker.io/library/rust:1.80 AS builder + +# Set the working directory inside the container +WORKDIR /usr/src/taiko_preconf_avs_node + +# Copy the project files +COPY ../Node/src /usr/src/taiko_preconf_avs_node/src +COPY ../Node/Cargo.toml /usr/src/taiko_preconf_avs_node/Cargo.toml +COPY ../Node/Cargo.lock /usr/src/taiko_preconf_avs_node/Cargo.lock + +# Copy the dependency directory +COPY ../p2pNode/p2pNetwork /usr/src/p2pNode/p2pNetwork + +# Build the project in release mode +RUN cargo build -p taiko_preconf_avs_node --release + +# Use ubuntu as the base image +FROM ubuntu:latest + +# Copy the build artifact from the builder stage +COPY --from=builder /usr/src/taiko_preconf_avs_node/target/release/taiko_preconf_avs_node /usr/local/bin/taiko_preconf_avs_node + +# Expose the port that the server will run on +# EXPOSE 9000 + +# Run the binary +ENTRYPOINT ["taiko_preconf_avs_node"] diff --git a/Dockerfile_cache b/Dockerfile_cache new file mode 100644 index 0000000..60e9da2 --- /dev/null +++ b/Dockerfile_cache @@ -0,0 +1,29 @@ +FROM docker.io/library/rust:1.80 AS builder + +# Set the working directory inside the container +WORKDIR /usr/src/taiko_preconf_avs_node + +# Copy the project files +COPY ../Node/src /usr/src/taiko_preconf_avs_node/src +COPY ../Node/Cargo.toml /usr/src/taiko_preconf_avs_node/Cargo.toml +COPY ../Node/Cargo.lock /usr/src/taiko_preconf_avs_node/Cargo.lock + +# Copy the dependency directory +COPY ../p2pNode/p2pNetwork /usr/src/p2pNode/p2pNetwork + +# Build the project in release mode +RUN --mount=type=cache,target=/usr/local/cargo/registry --mount=type=cache,target=/usr/src/taiko_preconf_avs_node/target \ + cargo build -p taiko_preconf_avs_node --release && \ + mv /usr/src/taiko_preconf_avs_node/target/release/taiko_preconf_avs_node /root + +# Use ubuntu as the base image +FROM ubuntu:latest + +# Copy the build artifact from the builder stage +COPY --from=builder /root/taiko_preconf_avs_node /usr/local/bin/taiko_preconf_avs_node + +# Expose the port that the server will run on +# EXPOSE 9000 + +# Run the binary +ENTRYPOINT ["taiko_preconf_avs_node"] diff --git a/Node/.env.sample b/Node/.env.sample new file mode 100644 index 0000000..e0a1dbe --- /dev/null +++ b/Node/.env.sample @@ -0,0 +1,21 @@ +AVS_NODE_ECDSA_PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000000000 +VALIDATOR_BLS_PRIVATEKEY=1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef +AVS_PRECONF_TASK_MANAGER_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +AVS_DIRECTORY_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +AVS_SERVICE_MANAGER_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +AVS_PRECONF_REGISTRY_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +EIGEN_LAYER_STRATEGY_MANAGER_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +EIGEN_LAYER_SLASHER_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000 +TAIKO_L1_ADDRESS=0x0000000000000000000000000000000000000000 +TAIKO_CHAIN_ID=167 +L1_CHAIN_ID=3151908 +VALIDATOR_INDEX=1 +TAIKO_PROPOSER_URL=http://127.0.0.1:1234 +TAIKO_DRIVER_URL=http://127.0.0.1:1235 +MEV_BOOST_URL=http://127.0.0.1:33661 +L1_WS_RPC_URL=ws://127.0.0.1:32003 +L1_BEACON_URL=http://127.0.0.1:33001 +ENABLE_P2P=true +ENABLE_PRECONFIRMATION=true +RUST_LOG=debug,reqwest=info,hyper=info,alloy_transport=info,alloy_rpc_client=info,alloy_provider=info + diff --git a/Node/Cargo.lock b/Node/Cargo.lock index d5ac7f8..f3b1c63 100644 --- a/Node/Cargo.lock +++ b/Node/Cargo.lock @@ -143,9 +143,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.32" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf770dad29577cd3580f3dd09005799224a912b8cdfdd6dc04d030d42b3df4e" +checksum = "8158b4878c67837e5413721cc44298e6a2d88d39203175ea025e51892a16ba4c" dependencies = [ "num_enum", "strum", @@ -227,7 +227,7 @@ dependencies = [ "alloy-serde", "c-kzg", "derive_more 0.99.18", - "k256 0.13.3", + "k256 0.13.4", "once_cell", "serde", "sha2 0.10.8", @@ -310,7 +310,7 @@ checksum = "16faebb9ea31a244fd6ce3288d47df4be96797d9c3c020144b8f2c31543a4512" dependencies = [ "alloy-genesis", "alloy-primitives 0.7.7", - "k256 0.13.3", + "k256 0.13.4", "serde_json", "tempfile", "thiserror", @@ -331,7 +331,7 @@ dependencies = [ "derive_more 0.99.18", "hex-literal", "itoa", - "k256 0.13.3", + "k256 0.13.4", "keccak-asm", "proptest", "rand 0.8.5", @@ -342,23 +342,28 @@ dependencies = [ [[package]] name = "alloy-primitives" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411aff151f2a73124ee473708e82ed51b2535f68928b6a1caa8bc1246ae6f7cd" +checksum = "260d3ff3bff0bb84599f032a2f2c6828180b0ea0cd41fdaf44f39cef3ba41861" dependencies = [ "alloy-rlp", "bytes", "cfg-if", "const-hex", "derive_more 1.0.0", + "hashbrown 0.14.5", "hex-literal", + "indexmap 2.5.0", "itoa", - "k256 0.13.3", + "k256 0.13.4", "keccak-asm", + "paste", "proptest", "rand 0.8.5", "ruint", + "rustc-hash", "serde", + "sha3", "tiny-keccak", ] @@ -439,7 +444,7 @@ checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -548,7 +553,7 @@ dependencies = [ "async-trait", "auto_impl", "elliptic-curve 0.13.8", - "k256 0.13.3", + "k256 0.13.4", "thiserror", ] @@ -563,7 +568,7 @@ dependencies = [ "alloy-primitives 0.7.7", "alloy-signer", "async-trait", - "k256 0.13.3", + "k256 0.13.4", "rand 0.8.5", "thiserror", ] @@ -579,7 +584,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -596,7 +601,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "syn-solidity", "tiny-keccak", ] @@ -614,7 +619,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.77", + "syn 2.0.79", "syn-solidity", ] @@ -996,7 +1001,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "synstructure 0.13.1", ] @@ -1008,7 +1013,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1289,7 +1294,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1300,13 +1305,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.82" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1371,14 +1376,14 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -1647,9 +1652,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.21" +version = "1.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" dependencies = [ "shlex", ] @@ -1726,9 +1731,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" dependencies = [ "clap_builder", "clap_derive", @@ -1736,9 +1741,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.17" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" dependencies = [ "anstream", "anstyle", @@ -1748,14 +1753,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -1996,7 +2001,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2020,7 +2025,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2031,7 +2036,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2148,7 +2153,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2168,7 +2173,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "unicode-xid", ] @@ -2232,7 +2237,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2401,7 +2406,7 @@ dependencies = [ "bytes", "ed25519-dalek", "hex", - "k256 0.13.3", + "k256 0.13.4", "log", "rand 0.8.5", "serde", @@ -2418,7 +2423,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2515,7 +2520,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e999563461faea0ab9bc0024e5e66adcee35881f3d5062f52f31a4070fe1522" dependencies = [ - "alloy-primitives 0.8.3", + "alloy-primitives 0.8.5", "itertools 0.13.0", "smallvec", ] @@ -2529,7 +2534,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -2545,7 +2550,7 @@ dependencies = [ "elliptic-curve 0.13.8", "ethabi", "generic-array", - "k256 0.13.3", + "k256 0.13.4", "num_enum", "open-fastrlp", "rand 0.8.5", @@ -2798,7 +2803,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -3371,9 +3376,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ "bytes", "futures-channel", @@ -3384,7 +3389,6 @@ dependencies = [ "pin-project-lite", "socket2 0.5.7", "tokio", - "tower", "tower-service", "tracing", ] @@ -3683,9 +3687,9 @@ dependencies = [ [[package]] name = "jsonrpsee" -version = "0.24.4" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd1ead9fb95614e8dc5556d12a8681c2f6d352d0c1d3efc8708c7ccbba47bc6" +checksum = "126b48a5acc3c52fbd5381a77898cb60e145123179588a29e7ac48f9c06e401b" dependencies = [ "jsonrpsee-core", "jsonrpsee-http-client", @@ -3696,9 +3700,9 @@ dependencies = [ [[package]] name = "jsonrpsee-core" -version = "0.24.4" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff79651479f69ada7bda604ef2acf3f1aa50755d97cc36d25ff04c2664f9d96f" +checksum = "b0e503369a76e195b65af35058add0e6900b794a4e9a9316900ddd3a87a80477" dependencies = [ "async-trait", "bytes", @@ -3719,9 +3723,9 @@ dependencies = [ [[package]] name = "jsonrpsee-http-client" -version = "0.24.4" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ed8b301b19f4dad8ddc66ed956a70fc227def5c19b3898e0a29ce8f0edee06" +checksum = "f2c0caba4a6a8efbafeec9baa986aa22a75a96c29d3e4b0091b0098d6470efb5" dependencies = [ "async-trait", "base64 0.22.1", @@ -3744,9 +3748,9 @@ dependencies = [ [[package]] name = "jsonrpsee-server" -version = "0.24.4" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebe2198e5fd96cf2153ecc123364f699b6e2151317ea09c7bf799c43c2fe1415" +checksum = "af6e6c9b6d975edcb443565d648b605f3e85a04ec63aa6941811a8894cc9cded" dependencies = [ "futures-util", "http 1.1.0", @@ -3771,9 +3775,9 @@ dependencies = [ [[package]] name = "jsonrpsee-types" -version = "0.24.4" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531e386460425e49679587871a056f2895a47dade21457324ad1262cd78ef6d9" +checksum = "d8fb16314327cbc94fdf7965ef7e4422509cd5597f76d137bd104eb34aeede67" dependencies = [ "http 1.1.0", "serde", @@ -3810,9 +3814,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ "cfg-if", "ecdsa 0.16.9", @@ -3858,9 +3862,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.158" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libm" @@ -3885,7 +3889,7 @@ dependencies = [ "libp2p-core 0.41.3", "libp2p-identity", "libp2p-swarm 0.44.2", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "pin-project", "rw-stream-sink", "thiserror", @@ -3933,7 +3937,7 @@ dependencies = [ "libp2p-websocket-websys", "libp2p-webtransport-websys", "libp2p-yamux", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "pin-project", "rw-stream-sink", "thiserror", @@ -4025,7 +4029,7 @@ dependencies = [ "futures", "futures-timer", "libp2p-identity", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "multihash 0.19.1", "multistream-select", "once_cell", @@ -4053,7 +4057,7 @@ dependencies = [ "futures", "futures-timer", "libp2p-identity", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "multihash 0.19.1", "multistream-select", "once_cell", @@ -4333,7 +4337,7 @@ dependencies = [ "futures", "libp2p-core 0.42.0", "libp2p-identity", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "multihash 0.19.1", "once_cell", "quick-protobuf", @@ -4550,7 +4554,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4667,7 +4671,7 @@ dependencies = [ "libp2p-core 0.42.0", "libp2p-identity", "libp2p-noise", - "multiaddr 0.18.1", + "multiaddr 0.18.2", "multihash 0.19.1", "send_wrapper 0.6.0", "thiserror", @@ -4901,7 +4905,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4913,7 +4917,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -4966,9 +4970,9 @@ dependencies = [ [[package]] name = "multiaddr" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" dependencies = [ "arrayref", "byteorder", @@ -4979,7 +4983,7 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint 0.7.2", + "unsigned-varint 0.8.0", "url", ] @@ -5239,7 +5243,7 @@ dependencies = [ "proc-macro-crate 3.2.0", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -5320,7 +5324,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -5450,7 +5454,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.4", + "redox_syscall 0.5.6", "smallvec", "windows-targets 0.52.6", ] @@ -5524,7 +5528,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -5572,9 +5576,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "polling" @@ -5778,7 +5782,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -6024,9 +6028,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" dependencies = [ "bitflags 2.6.0", ] @@ -6416,9 +6420,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] name = "rustls-platform-verifier" @@ -6622,9 +6626,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -6695,7 +6699,7 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7041,7 +7045,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7063,9 +7067,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.77" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -7081,7 +7085,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7119,7 +7123,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7200,7 +7204,7 @@ dependencies = [ "futures-util", "hex", "jsonrpsee", - "k256 0.13.3", + "k256 0.13.4", "lazy_static", "mockall", "mockall_double", @@ -7248,22 +7252,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7366,7 +7370,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7450,9 +7454,9 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.21" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.5.0", "toml_datetime", @@ -7469,7 +7473,6 @@ dependencies = [ "futures-util", "pin-project", "pin-project-lite", - "tokio", "tower-layer", "tower-service", "tracing", @@ -7507,7 +7510,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -7802,7 +7805,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -7836,7 +7839,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8150,9 +8153,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -8306,7 +8309,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] [[package]] @@ -8326,5 +8329,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.77", + "syn 2.0.79", ] diff --git a/Node/src/ethereum_l1/block_proposed.rs b/Node/src/ethereum_l1/block_proposed.rs index b071511..ec06ee6 100644 --- a/Node/src/ethereum_l1/block_proposed.rs +++ b/Node/src/ethereum_l1/block_proposed.rs @@ -1,4 +1,4 @@ -use alloy::{contract::EventPoller, pubsub::PubSubFrontend, sol}; +use alloy::{contract::EventSubscription, sol}; use anyhow::Error; sol!( @@ -30,4 +30,4 @@ impl BlockProposed { } } -pub struct EventPollerBlockProposed(pub EventPoller); +pub struct EventSubscriptionBlockProposed(pub EventSubscription); diff --git a/Node/src/ethereum_l1/el_with_cl_tests.rs b/Node/src/ethereum_l1/el_with_cl_tests.rs index aaf8282..02b2178 100644 --- a/Node/src/ethereum_l1/el_with_cl_tests.rs +++ b/Node/src/ethereum_l1/el_with_cl_tests.rs @@ -30,7 +30,7 @@ mod tests { // .unwrap(); let lookahead_params = Vec::::new(); - el.propose_new_block(0, vec![0; 32], [0; 32], 0, lookahead_params, true) + el.propose_new_block(0, vec![0; 32], 0, lookahead_params, true) .await .unwrap(); } diff --git a/Node/src/ethereum_l1/execution_layer.rs b/Node/src/ethereum_l1/execution_layer.rs index 972ecb9..56ad7dc 100644 --- a/Node/src/ethereum_l1/execution_layer.rs +++ b/Node/src/ethereum_l1/execution_layer.rs @@ -1,6 +1,6 @@ use super::{ avs_contract_error::AVSContractError, - block_proposed::{BlockProposed, EventPollerBlockProposed, TaikoEvents}, + block_proposed::{BlockProposed, EventSubscriptionBlockProposed, TaikoEvents}, slot_clock::SlotClock, }; use crate::{ @@ -213,7 +213,6 @@ impl ExecutionLayer { &self, nonce: u64, tx_list: Vec, - parent_meta_hash: [u8; 32], lookahead_pointer: u64, lookahead_set_params: Vec, send_to_contract: bool, @@ -229,7 +228,7 @@ impl ExecutionLayer { &self.wallet, ), extraData: FixedBytes::from(&[0u8; 32]), - parentMetaHash: FixedBytes::from(&parent_meta_hash), + parentMetaHash: FixedBytes::from(&[0u8; 32]), hookCalls: vec![], signature: Bytes::from(vec![0; 32]), l1StateBlockNumber: 0, @@ -253,15 +252,14 @@ impl ExecutionLayer { ) .chain_id(self.l1_chain_id) .nonce(nonce) - .gas(50_000) + .gas(500_000) .max_fee_per_gas(20_000_000_000) .max_priority_fee_per_gas(1_000_000_000); // Build transaction let tx = builder.as_ref().clone().build_typed_tx(); let Ok(TypedTransaction::Eip1559(mut tx)) = tx else { - // TODO fix - panic!("Not EIP1559 transaction"); + return Err(anyhow::anyhow!("Not EIP1559 transaction")); }; // Sign transaction @@ -280,8 +278,6 @@ impl ExecutionLayer { let pending = self .provider_ws .send_raw_transaction(&buf) - .await? - .register() .await?; tracing::debug!("Proposed new block, with hash {}", pending.tx_hash()); @@ -591,16 +587,23 @@ impl ExecutionLayer { &self, lookahead_set_params: Vec, ) -> Result<(), Error> { + tracing::debug!( + "Force pushing lookahead, {} params", + lookahead_set_params.len() + ); + let contract = PreconfTaskManager::new( self.contract_addresses.avs.preconf_task_manager, &self.provider_ws, ); - let tx = contract.forcePushLookahead(lookahead_set_params); + let tx = contract + .forcePushLookahead(lookahead_set_params) + .nonce(self.get_preconfer_nonce().await?) + .gas(1_000_000); match tx.send().await { Ok(receipt) => { - let tx_hash = receipt.watch().await?; - tracing::info!("Force pushed lookahead: {}", tx_hash); + tracing::debug!("Force push lookahead sent: {}", receipt.tx_hash()); } Err(err) => { return Err(anyhow::anyhow!(err.to_avs_contract_error())); @@ -668,6 +671,64 @@ impl ExecutionLayer { Ok(()) } + pub async fn remove_validator(&self) -> Result<(), Error> { + // Build remove message + // Operation.REMOVE + let operation = 2; + // Message expired after 60 seconds + let expiry = U256::from(self.slot_clock.get_now_plus_minute()?); + + let data = MessageData::from(( + U256::from(self.l1_chain_id), + operation, + expiry, + self.preconfer_address, + )); + let message = data.abi_encode_packed(); + + // Convert bls public key to G1Point + let pk_point = self.bls_service.get_public_key(); + let pubkey = PreconfRegistry::G1Point { + x: BLSService::biguint_to_u256_array(BigUint::from(pk_point.x)), + y: BLSService::biguint_to_u256_array(BigUint::from(pk_point.y)), + }; + + // Sign message and convert to G2Point + let signature_point = self.bls_service.sign_as_point(&message, &vec![]); + + let signature = PreconfRegistry::G2Point { + x: BLSService::biguint_to_u256_array(BigUint::from(signature_point.x.c0)), + x_I: BLSService::biguint_to_u256_array(BigUint::from(signature_point.x.c1)), + y: BLSService::biguint_to_u256_array(BigUint::from(signature_point.y.c0)), + y_I: BLSService::biguint_to_u256_array(BigUint::from(signature_point.y.c1)), + }; + + // Call contract + let params = vec![PreconfRegistry::RemoveValidatorParam { + pubkey, + signature, + signatureExpiry: expiry, + }]; + + let preconf_registry = PreconfRegistry::new( + self.contract_addresses.avs.preconf_registry, + &self.provider_ws, + ); + let tx = preconf_registry.removeValidators(params); + + match tx.send().await { + Ok(receipt) => { + let tx_hash = receipt.watch().await?; + tracing::info!("Validator removed successfully: {:?}", tx_hash); + } + Err(err) => { + return Err(anyhow::anyhow!(err.to_avs_contract_error())); + } + } + + Ok(()) + } + pub async fn subscribe_to_validator_added_event( &self, ) -> Result, Error> { @@ -724,20 +785,28 @@ impl ExecutionLayer { pub async fn subscribe_to_block_proposed_event( &self, - ) -> Result { + ) -> Result { let taiko_events = TaikoEvents::new(self.contract_addresses.taiko_l1, &self.provider_ws); - let block_proposed_filter = taiko_events.BlockProposed_filter().watch().await?; + let block_proposed_filter = taiko_events.BlockProposed_filter().subscribe().await?; tracing::debug!("Subscribed to block proposed event"); - Ok(EventPollerBlockProposed(block_proposed_filter)) + Ok(EventSubscriptionBlockProposed(block_proposed_filter)) } pub async fn get_lookahead_params_for_epoch_using_cl_lookahead( &self, - epoch_begin_timestamp: u64, + epoch: u64, cl_lookahead: &[ProposerDuty], ) -> Result, Error> { + let epoch_begin_timestamp = self.slot_clock.get_epoch_begin_timestamp(epoch)?; + tracing::debug!( + "Epoch {}, timestamp: {}, getting lookahead params for epoch using CL lookahead len: {}", + epoch, + epoch_begin_timestamp, + cl_lookahead.len() + ); + if cl_lookahead.len() != self.slot_clock.get_slots_per_epoch() as usize { return Err(anyhow::anyhow!( "Operator::find_slots_to_preconfirm: unexpected number of proposer duties in the lookahead" @@ -762,7 +831,7 @@ impl ExecutionLayer { .await } - pub async fn get_lookahead_params_for_epoch( + async fn get_lookahead_params_for_epoch( &self, epoch_begin_timestamp: u64, validator_bls_pub_keys: &[BLSCompressedPublicKey; 32], @@ -781,13 +850,21 @@ impl ExecutionLayer { .await? ._0; + tracing::debug!( + "get_lookahead_params_for_epoch params len: {}", + params.len() + ); + Ok(params) } pub async fn get_lookahead_preconfer_addresses_for_epoch( &self, - epoch_begin_timestamp: u64, + epoch: u64, ) -> Result, Error> { + tracing::debug!("Getting lookahead preconfer addresses for epoch: {}", epoch); + let epoch_begin_timestamp = self.slot_clock.get_epoch_begin_timestamp(epoch)?; + let contract = PreconfTaskManager::new( self.contract_addresses.avs.preconf_task_manager, &self.provider_ws, @@ -817,36 +894,25 @@ impl ExecutionLayer { Ok(lookahead) } - pub async fn is_lookahead_required(&self, epoch_begin_timestamp: u64) -> Result { + pub async fn is_lookahead_required(&self, epoch: u64) -> Result { let contract = PreconfTaskManager::new( self.contract_addresses.avs.preconf_task_manager, &self.provider_ws, ); - + let epoch_begin_timestamp = self.slot_clock.get_epoch_begin_timestamp(epoch)?; let is_required = contract .isLookaheadRequired(U256::from(epoch_begin_timestamp)) .call() .await?; + tracing::debug!( + "is_lookahead_required for epoch {}: {}", + epoch, + is_required._0 + ); Ok(is_required._0) } - /* fn create_provider(&self) -> impl Provider> { - ProviderBuilder::new() - .with_recommended_fillers() - .wallet(self.wallet.clone()) - .on_http(self.rpc_url.clone()) - } - - async fn create_provider_ws(&self) -> impl Provider { - ProviderBuilder::new() - .with_recommended_fillers() - .wallet(self.wallet.clone()) - .on_ws(self.ws.clone()) - .await - .unwrap() - }*/ - #[cfg(test)] pub async fn new_from_pk( ws_rpc_url: String, @@ -967,7 +1033,7 @@ mod tests { .await .unwrap(); - el.propose_new_block(0, vec![0; 32], [0; 32], 0, vec![], true) + el.propose_new_block(0, vec![0; 32], 0, vec![], true) .await .unwrap(); } diff --git a/Node/src/ethereum_l1/mod.rs b/Node/src/ethereum_l1/mod.rs index 69120bb..7fce3bb 100644 --- a/Node/src/ethereum_l1/mod.rs +++ b/Node/src/ethereum_l1/mod.rs @@ -74,11 +74,9 @@ impl EthereumL1 { // Get lookahead params for contract call let lookahead_params = self .execution_layer - .get_lookahead_params_for_epoch_using_cl_lookahead( - self.slot_clock.get_epoch_begin_timestamp(next_epoch)?, - &cl_lookahead, - ) + .get_lookahead_params_for_epoch_using_cl_lookahead(next_epoch, &cl_lookahead) .await?; + tracing::debug!("Got {} lookahead params.", lookahead_params.len()); // Force push lookahead to the contract self.execution_layer .force_push_lookahead(lookahead_params) diff --git a/Node/src/ethereum_l1/slot_clock.rs b/Node/src/ethereum_l1/slot_clock.rs index 3c55748..9ccee01 100644 --- a/Node/src/ethereum_l1/slot_clock.rs +++ b/Node/src/ethereum_l1/slot_clock.rs @@ -20,6 +20,11 @@ impl SlotClock { slot_duration_sec: u64, slots_per_epoch: u64, ) -> Self { + tracing::info!( + "SlotClock: genesis_timestamp_sec: {}, genesis_slot: {}", + genesis_timestamp_sec, + genesis_slot + ); Self { genesis_slot, genesis_duration: Duration::from_secs(genesis_timestamp_sec), @@ -124,10 +129,6 @@ impl SlotClock { Ok(now.as_secs() + 60) } - pub fn get_epoch_duration_secs(&self) -> u64 { - self.slot_duration.as_secs() * self.slots_per_epoch - } - pub fn get_current_slot_of_epoch(&self) -> Result { let now = SystemTime::now().duration_since(UNIX_EPOCH)?; let cur_slot = self.slot_of(now)?; @@ -201,11 +202,11 @@ mod tests { } #[test] - fn test_get_epoch_duration_secs() { + fn test_get_epoch_begin_timestamp() { let genesis_slot = Slot::from(0u64); let slot_clock = SlotClock::new(genesis_slot, 0, 12, 32); - let epoch_duration = slot_clock.get_epoch_duration_secs(); - assert_eq!(epoch_duration, 384); // 12 slots per epoch * 32 seconds per slot + let epoch_begin_timestamp = slot_clock.get_epoch_begin_timestamp(1).unwrap(); + assert_eq!(epoch_begin_timestamp, 384); } } diff --git a/Node/src/main.rs b/Node/src/main.rs index a0cbda4..323122f 100644 --- a/Node/src/main.rs +++ b/Node/src/main.rs @@ -24,6 +24,8 @@ struct Cli { register: bool, #[clap(long, help = "Add validator to preconfer")] add_validator: bool, + #[clap(long, help = "Remove validator for preconfer")] + remove_validator: bool, #[clap(long, help = "Force Push lookahead to the PreconfTaskManager contract")] force_push_lookahead: bool, } @@ -31,6 +33,9 @@ struct Cli { #[tokio::main] async fn main() -> Result<(), Error> { init_logging(); + + tracing::info!("Starting AVS Node"); + let args = Cli::parse(); let config = utils::config::Config::read_env_variables(); @@ -61,6 +66,12 @@ async fn main() -> Result<(), Error> { return Ok(()); } + if args.remove_validator { + let registration = registration::Registration::new(ethereum_l1); + registration.remove_validator().await?; + return Ok(()); + } + if args.force_push_lookahead { ethereum_l1.force_push_lookahead().await?; return Ok(()); @@ -82,19 +93,6 @@ async fn main() -> Result<(), Error> { let mev_boost = mev_boost::MevBoost::new(&config.mev_boost_url, config.validator_index); let ethereum_l1 = Arc::new(ethereum_l1); - let node = node::Node::new( - block_proposed_rx, - node_to_p2p_tx, - p2p_to_node_rx, - taiko.clone(), - ethereum_l1.clone(), - mev_boost, - config.l2_slot_duration_sec, - bls_service, - ) - .await?; - node.entrypoint().await?; - let block_proposed_event_checker = BlockProposedEventReceiver::new(ethereum_l1.clone(), block_proposed_tx); BlockProposedEventReceiver::start(block_proposed_event_checker); @@ -102,6 +100,27 @@ async fn main() -> Result<(), Error> { let lookahead_updated_event_checker = LookaheadUpdatedEventReceiver::new(ethereum_l1.clone()); lookahead_updated_event_checker.start(); + if config.enable_preconfirmation { + let node = node::Node::new( + block_proposed_rx, + node_to_p2p_tx, + p2p_to_node_rx, + taiko.clone(), + ethereum_l1.clone(), + mev_boost, + config.l2_slot_duration_sec, + bls_service, + ) + .await?; + node.entrypoint().await?; + } else { + let lookahead_monitor = node::lookahead_monitor::LookaheadMonitor::new( + ethereum_l1.clone(), + config.l1_slot_duration_sec, + ); + lookahead_monitor.start().await; + } + Ok(()) } diff --git a/Node/src/node/block_proposed_receiver.rs b/Node/src/node/block_proposed_receiver.rs index 2142570..ded5ba3 100644 --- a/Node/src/node/block_proposed_receiver.rs +++ b/Node/src/node/block_proposed_receiver.rs @@ -18,6 +18,7 @@ impl BlockProposedEventReceiver { } pub fn start(receiver: Self) { + info!("Starting block proposed event receiver"); tokio::spawn(async move { receiver.check_for_events().await; }); @@ -69,6 +70,7 @@ impl BlockProposedEventReceiver { None => { error!("No block proposed event received, stream closed"); // TODO: recreate a stream in this case? + return; } } } diff --git a/Node/src/node/lookahead_monitor.rs b/Node/src/node/lookahead_monitor.rs new file mode 100644 index 0000000..bd7afb3 --- /dev/null +++ b/Node/src/node/lookahead_monitor.rs @@ -0,0 +1,67 @@ +// Special mode of the AVS node that monitors the lookahead availability in the contract +// and push the lookahead if it is required. +use crate::ethereum_l1::EthereumL1; +use anyhow::Error; +use std::sync::Arc; +use tokio::time::Duration; +use tracing::{debug, error, info}; + +pub struct LookaheadMonitor { + ethereum_l1: Arc, + l1_slot_duration_sec: u64, +} + +impl LookaheadMonitor { + pub fn new(ethereum_l1: Arc, l1_slot_duration_sec: u64) -> Self { + Self { + ethereum_l1, + l1_slot_duration_sec, + } + } + + pub async fn start(self) { + // start lookahead monitor loop + let mut interval = tokio::time::interval(Duration::from_secs(self.l1_slot_duration_sec)); + loop { + interval.tick().await; + + if let Err(err) = self.lookahead_monitor_step().await { + error!("Failed to execute lookahead monitor step: {}", err); + } + } + } + + async fn lookahead_monitor_step(&self) -> Result<(), Error> { + info!( + "Monitoring lookahead, slot: {}", + self.ethereum_l1.slot_clock.get_current_slot()? + ); + + let next_epoch = self.ethereum_l1.slot_clock.get_current_epoch()? + 1; + if self + .ethereum_l1 + .execution_layer + .is_lookahead_required(next_epoch) + .await? + { + debug!("Lookahead is required, pushing it"); + let cl_lookahead = self + .ethereum_l1 + .consensus_layer + .get_lookahead(next_epoch) + .await?; + + let lookahead_params = self + .ethereum_l1 + .execution_layer + .get_lookahead_params_for_epoch_using_cl_lookahead(next_epoch, &cl_lookahead) + .await?; + + self.ethereum_l1 + .execution_layer + .force_push_lookahead(lookahead_params) + .await?; + } + Ok(()) + } +} diff --git a/Node/src/node/lookahead_updated_receiver.rs b/Node/src/node/lookahead_updated_receiver.rs index ba5bb6c..7c5a612 100644 --- a/Node/src/node/lookahead_updated_receiver.rs +++ b/Node/src/node/lookahead_updated_receiver.rs @@ -21,6 +21,7 @@ impl LookaheadUpdatedEventReceiver { } pub fn start(self) { + info!("Starting lookahead updated event receiver"); tokio::spawn(async move { self.check_for_events().await; }); @@ -61,6 +62,7 @@ impl LookaheadUpdatedEventReceiver { None => { error!("No lookahead updated event received, stream closed"); // TODO: recreate a stream in this case? + return; } } } @@ -96,10 +98,6 @@ impl LookaheadUpdatedEventHandler { .slot_clock .get_epoch_for_timestamp(lookahead_updated_next_epoch[0].timestamp.try_into()?)?; - let epoch_begin_timestamp = self - .ethereum_l1 - .slot_clock - .get_epoch_begin_timestamp(epoch)?; let epoch_duties = self .ethereum_l1 .consensus_layer @@ -108,7 +106,7 @@ impl LookaheadUpdatedEventHandler { let epoch_lookahead_params = self .ethereum_l1 .execution_layer - .get_lookahead_params_for_epoch_using_cl_lookahead(epoch_begin_timestamp, &epoch_duties) + .get_lookahead_params_for_epoch_using_cl_lookahead(epoch, &epoch_duties) .await?; if let Some(slot_timestamp) = Self::find_a_slot_timestamp_to_prove_incorrect_lookahead( diff --git a/Node/src/node/mod.rs b/Node/src/node/mod.rs index d987ce7..d4203ea 100644 --- a/Node/src/node/mod.rs +++ b/Node/src/node/mod.rs @@ -1,5 +1,6 @@ pub mod block_proposed_receiver; mod commit; +pub mod lookahead_monitor; pub mod lookahead_updated_receiver; mod operator; mod preconfirmation_helper; @@ -67,8 +68,8 @@ impl Node { l2_slot_duration_sec: u64, bls_service: Arc, ) -> Result { - let current_epoch = ethereum_l1.slot_clock.get_current_epoch()?; - let operator = Operator::new(ethereum_l1.clone(), current_epoch)?; + let init_epoch = 0; + let operator = Operator::new(ethereum_l1.clone(), init_epoch)?; Ok(Self { taiko, node_block_proposed_rx: Some(node_rx), @@ -76,7 +77,7 @@ impl Node { p2p_to_node_rx: Some(p2p_to_node_rx), ethereum_l1, mev_boost, - epoch: current_epoch, + epoch: init_epoch, cl_lookahead: vec![], lookahead_preconfer_buffer: None, l2_slot_duration_sec, @@ -283,13 +284,6 @@ impl Node { tracing::error!("Failed to initialize lookahead: {}", e); } - if let Err(err) = self.operator.update_preconfer_lookahead_for_epoch().await { - tracing::error!( - "Failed to update preconfer lookahead before starting preconfirmation loop: {}", - err - ); - } - // start preconfirmation loop let mut interval = tokio::time::interval(Duration::from_secs(self.l2_slot_duration_sec)); loop { @@ -334,7 +328,7 @@ impl Node { self.preconfirm_block(true).await?; } OperatorStatus::None => { - tracing::debug!("Not my slot to preconfirm: {}", current_slot); + tracing::info!("Not my slot to preconfirm: {}", current_slot); } } @@ -363,9 +357,7 @@ impl Node { Ok(()) } - async fn get_lookahead_params( - &mut self, - ) -> Result<(u64, Vec), Error> { + async fn get_lookahead_pointer(&mut self) -> Result { let current_timestamp = std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH)? .as_secs(); @@ -386,22 +378,28 @@ impl Node { "get_lookahead_params: Preconfer not found in lookahead" ))? as u64; - if self.operator.should_post_lookahead().await? { + Ok(lookahead_pointer) + } + + async fn get_lookahead_params( + &mut self, + ) -> Result>, Error> { + if self.operator.should_post_lookahead_for_next_epoch().await? { + tracing::debug!("Should post lookahead params, getting them"); let lookahead_params = self .ethereum_l1 .execution_layer .get_lookahead_params_for_epoch_using_cl_lookahead( - self.ethereum_l1 - .slot_clock - .get_epoch_begin_timestamp(self.epoch + 1)?, + self.epoch + 1, &self.cl_lookahead, ) .await?; - return Ok((lookahead_pointer, lookahead_params)); - } + tracing::debug!("Got Lookahead params: {}", lookahead_params.len()); - Ok((lookahead_pointer, vec![])) + return Ok(Some(lookahead_params)); + } + Ok(None) } async fn preconfirm_last_slot(&mut self) -> Result<(), Error> { @@ -451,20 +449,32 @@ impl Node { } async fn preconfirm_block(&mut self, send_to_contract: bool) -> Result<(), Error> { - tracing::debug!( + tracing::info!( "Preconfirming for the slot: {:?}", self.ethereum_l1.slot_clock.get_current_slot()? ); - let (lookahead_pointer, lookahead_params) = self.get_lookahead_params().await?; - + let lookahead_params = self.get_lookahead_params().await?; let pending_tx_lists = self.taiko.get_pending_l2_tx_lists().await?; - if pending_tx_lists.tx_list_bytes.is_empty() { + let pending_tx_lists_bytes = if pending_tx_lists.tx_list_bytes.is_empty() { + if let Some(lookahead_params) = lookahead_params { + tracing::debug!("No pending transactions to preconfirm, force pushing lookahead"); + self.preconfirmation_helper.increment_nonce(); + self.ethereum_l1 + .execution_layer + .force_push_lookahead(lookahead_params) + .await?; + } return Ok(()); - } + } else { + tracing::debug!( + "Pending {} transactions to preconfirm", + pending_tx_lists.tx_list_bytes.len() + ); + pending_tx_lists.tx_list_bytes[0].clone() // TODO: handle multiple tx lists + }; let new_block_height = pending_tx_lists.parent_block_id + 1; - let nonce = self.preconfirmation_helper.get_next_nonce(); let (commit_hash, signature) = self.generate_commit_hash_and_signature(&pending_tx_lists, new_block_height)?; @@ -476,7 +486,7 @@ impl Node { let preconf_message = PreconfirmationMessage::new( new_block_height, pending_tx_lists.tx_lists.clone(), - &pending_tx_lists.tx_list_bytes[0], //TODO: handle rest tx lists + &pending_tx_lists_bytes, proof.clone(), ); self.send_preconfirmations_to_the_avs_p2p(preconf_message.clone()) @@ -485,15 +495,15 @@ impl Node { .advance_head_to_new_l2_block(pending_tx_lists.tx_lists) .await?; + let lookahead_pointer = self.get_lookahead_pointer().await?; let tx = self .ethereum_l1 .execution_layer .propose_new_block( - nonce, - pending_tx_lists.tx_list_bytes[0].clone(), //TODO: handle rest tx lists, - pending_tx_lists.parent_meta_hash, + self.preconfirmation_helper.get_next_nonce(), + pending_tx_lists_bytes, lookahead_pointer, - lookahead_params, + lookahead_params.unwrap_or(vec![]), send_to_contract, ) .await?; diff --git a/Node/src/node/operator.rs b/Node/src/node/operator.rs index bfee606..f686ad9 100644 --- a/Node/src/node/operator.rs +++ b/Node/src/node/operator.rs @@ -4,10 +4,9 @@ use std::sync::Arc; pub struct Operator { ethereum_l1: Arc, - epoch_begin_timestamp: u64, + epoch: u64, lookahead_required_contract_called: bool, lookahead_preconfer_addresses: Vec, - lookahead_preconfer_addresses_next_epoch: Option>, l1_slots_per_epoch: u64, } @@ -20,14 +19,13 @@ pub enum Status { impl Operator { pub fn new(ethereum_l1: Arc, epoch: Epoch) -> Result { + tracing::debug!("Operator::new: epoch: {}", epoch); let l1_slots_per_epoch = ethereum_l1.slot_clock.get_slots_per_epoch(); - let epoch_begin_timestamp = ethereum_l1.slot_clock.get_epoch_begin_timestamp(epoch)?; Ok(Self { ethereum_l1, - epoch_begin_timestamp, + epoch, lookahead_required_contract_called: false, lookahead_preconfer_addresses: vec![], - lookahead_preconfer_addresses_next_epoch: None, l1_slots_per_epoch, }) } @@ -71,15 +69,9 @@ impl Operator { let lookahead_preconfer_addresses_next_epoch = self .ethereum_l1 .execution_layer - .get_lookahead_preconfer_addresses_for_epoch( - self.epoch_begin_timestamp - + self.ethereum_l1.slot_clock.get_epoch_duration_secs(), - ) + .get_lookahead_preconfer_addresses_for_epoch(self.epoch + 1) .await?; - let address = lookahead_preconfer_addresses_next_epoch[0]; - self.lookahead_preconfer_addresses_next_epoch = - Some(lookahead_preconfer_addresses_next_epoch); - Ok(address) + Ok(lookahead_preconfer_addresses_next_epoch[0]) } else { Ok(self.lookahead_preconfer_addresses[(slot_mod_slots_per_epoch + 1) as usize]) } @@ -89,13 +81,14 @@ impl Operator { next_preconfer_address != self.ethereum_l1.execution_layer.get_preconfer_address() } - pub async fn should_post_lookahead(&mut self) -> Result { + pub async fn should_post_lookahead_for_next_epoch(&mut self) -> Result { if !self.lookahead_required_contract_called { + tracing::debug!("Operator::should_post_lookahead: checking if lookahead is required"); self.lookahead_required_contract_called = true; if self .ethereum_l1 .execution_layer - .is_lookahead_required(self.epoch_begin_timestamp) + .is_lookahead_required(self.epoch + 1) .await? { return Ok(true); @@ -105,24 +98,13 @@ impl Operator { } pub async fn update_preconfer_lookahead_for_epoch(&mut self) -> Result<(), Error> { - tracing::debug!( - "Updating preconfer lookahead for epoch: {}", - self.ethereum_l1 - .slot_clock - .get_epoch_for_timestamp(self.epoch_begin_timestamp)? - ); - - if let Some(lookahead_preconfer_addresses_next_epoch) = - self.lookahead_preconfer_addresses_next_epoch.take() - { - self.lookahead_preconfer_addresses = lookahead_preconfer_addresses_next_epoch; - } else { - self.lookahead_preconfer_addresses = self - .ethereum_l1 - .execution_layer - .get_lookahead_preconfer_addresses_for_epoch(self.epoch_begin_timestamp) - .await?; - } + tracing::debug!("Updating preconfer lookahead for epoch: {}", self.epoch); + + self.lookahead_preconfer_addresses = self + .ethereum_l1 + .execution_layer + .get_lookahead_preconfer_addresses_for_epoch(self.epoch) + .await?; Ok(()) } } diff --git a/Node/src/node/preconfirmation_helper.rs b/Node/src/node/preconfirmation_helper.rs index 6eb3246..a63ffdd 100644 --- a/Node/src/node/preconfirmation_helper.rs +++ b/Node/src/node/preconfirmation_helper.rs @@ -22,6 +22,10 @@ impl PreconfirmationHelper { nonce } + pub fn increment_nonce(&mut self) { + self.nonce += 1; + } + pub fn increment_final_slot_perconfirmation(&mut self) { self.final_slot_perconfirmation_count += 1; } diff --git a/Node/src/registration/mod.rs b/Node/src/registration/mod.rs index e6f38b1..f301752 100644 --- a/Node/src/registration/mod.rs +++ b/Node/src/registration/mod.rs @@ -47,4 +47,9 @@ impl Registration { Ok(()) } + + pub async fn remove_validator(&self) -> Result<(), Error> { + self.ethereum_l1.execution_layer.remove_validator().await?; + Ok(()) + } } diff --git a/Node/src/utils/config.rs b/Node/src/utils/config.rs index 15abdf1..3021c4b 100644 --- a/Node/src/utils/config.rs +++ b/Node/src/utils/config.rs @@ -20,6 +20,7 @@ pub struct Config { pub l1_chain_id: u64, pub validator_index: u64, pub enable_p2p: bool, + pub enable_preconfirmation: bool, } #[derive(Debug)] @@ -242,6 +243,11 @@ impl Config { .parse::() .expect("ENABLE_P2P must be a boolean"); + let enable_preconfirmation = std::env::var("ENABLE_PRECONFIRMATION") + .unwrap_or("true".to_string()) + .parse::() + .expect("ENABLE_PRECONFIRMATION must be a boolean"); + let config = Self { taiko_proposer_url: std::env::var("TAIKO_PROPOSER_URL") .unwrap_or("http://127.0.0.1:1234".to_string()), @@ -265,6 +271,7 @@ impl Config { l1_chain_id, validator_index, enable_p2p, + enable_preconfirmation, }; info!( @@ -285,6 +292,7 @@ taiko chain id: {} l1 chain id: {} validator index: {} enable p2p: {} +enable preconfirmation: {} "#, config.taiko_proposer_url, config.taiko_driver_url, @@ -301,6 +309,7 @@ enable p2p: {} config.l1_chain_id, config.validator_index, config.enable_p2p, + config.enable_preconfirmation, ); config diff --git a/SmartContracts/scripts/deployment/deploy_avs.sh b/SmartContracts/scripts/deployment/deploy_avs.sh index 080cd28..f85dc73 100644 --- a/SmartContracts/scripts/deployment/deploy_avs.sh +++ b/SmartContracts/scripts/deployment/deploy_avs.sh @@ -1,13 +1,10 @@ set -e -export PRIVATE_KEY=0xbcdf20249abf0ed6d944c0288fad489e33f66b3960d9e6229c1cd214ed3bbe31 -export FORK_URL= - AVS_DIRECTORY=0x7E2E7DD2Aead92e2e6d05707F21D4C36004f8A2B \ SLASHER=0x86A0679C7987B5BA9600affA994B78D0660088ff \ TAIKO_L1=0x086f77C5686dfe3F2f8FE487C5f8d357952C8556 \ TAIKO_TOKEN=0x422A3492e218383753D8006C7Bfa97815B44373F \ -BEACON_GENESIS_TIMESTAMP=1725950369 \ +BEACON_GENESIS_TIMESTAMP=1726663179 \ BEACON_BLOCK_ROOT_CONTRACT=0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02 \ forge script scripts/deployment/DeployAVS.s.sol:DeployAVS \ --fork-url $FORK_URL \ diff --git a/SmartContracts/scripts/deployment/deploy_eigenlayer_mvp.sh b/SmartContracts/scripts/deployment/deploy_eigenlayer_mvp.sh index 5574ede..e57e1c2 100644 --- a/SmartContracts/scripts/deployment/deploy_eigenlayer_mvp.sh +++ b/SmartContracts/scripts/deployment/deploy_eigenlayer_mvp.sh @@ -1,8 +1,5 @@ set -e -export PRIVATE_KEY=0xbcdf20249abf0ed6d944c0288fad489e33f66b3960d9e6229c1cd214ed3bbe31 -export FORK_URL= - forge script scripts/deployment/DeployEigenlayerMVP.s.sol:DeployEigenlayerMVP \ --rpc-url $FORK_URL \ --broadcast \ diff --git a/avs-deploy b/avs-deploy new file mode 100644 index 0000000..ae9aedf --- /dev/null +++ b/avs-deploy @@ -0,0 +1,35 @@ +# Use an official Node.js runtime as a parent image +FROM node:18 + +# Set the working directory in the container +WORKDIR /usr/src/app + +# Copy the current directory contents into the container at /usr/src/app +COPY . . + +# Install Foundry (forge) +RUN curl -L https://foundry.paradigm.xyz | bash && \ + /root/.foundry/bin/foundryup + +# Change the working directory to packages/protocol +WORKDIR /usr/src/app/SmartContracts/ + +# Forge Install +RUN /root/.foundry/bin/forge install + +# Add Foundry to PATH +ENV PATH="/root/.foundry/bin:${PATH}" + +# Change the working directory to packages/protocol +WORKDIR /usr/src/app/SmartContracts/ + +# Make the script files executable +RUN chmod +x scripts/deployment/*.sh + +# Set environment variables +ENV PRIVATE_KEY=0x0000000000000000000000000000000000000000000000000000000000000000 +ENV FORK_URL="http://127.0.0.1:32002" +ENV BEACON_GENESIS_TIMESTAMP=1725950369 + +# Default command to run if no arguments are provided +CMD ["sh", "-c", "scripts/deployment/deploy_avs.sh"] \ No newline at end of file diff --git a/tools/tx_spammer/tx_spammer.py b/tools/tx_spammer/tx_spammer.py index 6f4b4e7..eafc5e2 100644 --- a/tools/tx_spammer/tx_spammer.py +++ b/tools/tx_spammer/tx_spammer.py @@ -18,11 +18,12 @@ RECIPIENT_ADDRESS= 5. Run the script: - python tx_spammer.py [--count COUNT] [--amount AMOUNT] + python tx_spammer.py [--count COUNT] [--amount AMOUNT] [--rpc RPC_URL] CLI Parameters: --count: Number of transactions to send (default: 1) --amount: Amount of ETH to send per transaction (default: 0.006) +--rpc: RPC URL for the Taiko network (default: https://RPC.helder.taiko.xyz) """ @@ -47,10 +48,11 @@ parser = argparse.ArgumentParser(description='Spam transactions on the Taiko network.') parser.add_argument('--count', type=int, default=1, help='Number of transactions to send') parser.add_argument('--amount', type=float, default=0.006, help='Amount of ETH to send per transaction') +parser.add_argument('--rpc', type=str, default='https://RPC.helder.taiko.xyz', help='RPC URL for the Taiko network') args = parser.parse_args() # Connect to the Taiko network -w3 = Web3(Web3.HTTPProvider('https://RPC.helder.taiko.xyz')) +w3 = Web3(Web3.HTTPProvider(args.rpc)) # Check if connected if not w3.is_connected(): @@ -69,9 +71,10 @@ def send_transaction(nonce : int): 'gasPrice': w3.to_wei('10', 'gwei'), 'chainId': w3.eth.chain_id } - print(f'Sending transaction: {tx}') + print(f'Sending transaction: {tx} by RPC: {args.rpc}') + print(f'Sending from: {account.address}') signed_tx = w3.eth.account.sign_transaction(tx, private_key) - tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction) + tx_hash = w3.eth.send_raw_transaction(signed_tx.raw_transaction) print(f'Transaction sent: {tx_hash.hex()}') def spam_transactions(count):