From a44d5b61f281c5832b8c918a330a47d2d2c6acfe Mon Sep 17 00:00:00 2001 From: Marko Atanasievski Date: Wed, 5 Feb 2025 18:15:43 +0100 Subject: [PATCH] feat: aggchain-proof-builder --- Cargo.lock | 484 ++++++++++++++++-- crates/aggchain-proof-builder/Cargo.toml | 22 + crates/aggchain-proof-builder/src/lib.rs | 121 ++++- .../src/provider/json_rpc.rs | 46 ++ .../src/provider/mod.rs | 1 + crates/aggchain-proof-core/src/lib.rs | 2 +- crates/aggchain-proof-core/src/proof.rs | 2 +- crates/aggkit-prover-config/Cargo.toml | 1 + .../src/aggchain_proof_builder.rs | 37 ++ .../src/aggchain_proof_service.rs | 20 + crates/aggkit-prover-config/src/lib.rs | 19 +- .../src/proposer_service.rs} | 9 +- crates/aggkit-prover-config/src/shutdown.rs | 2 +- crates/aggkit-prover-types/Cargo.toml | 1 + crates/aggkit-prover-types/src/lib.rs | 13 + .../aggkit-prover/src/aggchain_proof/error.rs | 19 +- .../aggkit-prover/src/aggchain_proof/mod.rs | 2 +- .../aggkit-prover/src/aggchain_proof/rpc.rs | 51 +- .../src/aggchain_proof/service.rs | 103 ++-- .../src/aggchain_proof/tests/mod.rs | 4 +- crates/aggkit-prover/src/main.rs | 3 +- crates/proposer-client/Cargo.toml | 4 +- crates/proposer-client/src/lib.rs | 24 +- crates/proposer-client/src/network_prover.rs | 2 +- crates/proposer-client/src/rpc.rs | 15 +- crates/proposer-service/Cargo.toml | 1 + crates/proposer-service/src/config.rs | 8 - crates/proposer-service/src/lib.rs | 37 +- crates/prover-config/src/lib.rs | 10 +- 29 files changed, 917 insertions(+), 146 deletions(-) create mode 100644 crates/aggchain-proof-builder/src/provider/json_rpc.rs create mode 100644 crates/aggchain-proof-builder/src/provider/mod.rs create mode 100644 crates/aggkit-prover-config/src/aggchain_proof_builder.rs create mode 100644 crates/aggkit-prover-config/src/aggchain_proof_service.rs rename crates/{proposer-client/src/config.rs => aggkit-prover-config/src/proposer_service.rs} (89%) delete mode 100644 crates/proposer-service/src/config.rs diff --git a/Cargo.lock b/Cargo.lock index 10cb9fe..89e1d95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -53,10 +53,18 @@ dependencies = [ name = "aggchain-proof-builder" version = "0.1.0" dependencies = [ + "aggchain-proof-core", + "aggkit-prover-config", + "aggkit-prover-types", + "alloy", + "anyhow", "futures", + "serde", + "sp1-sdk", "thiserror 2.0.11", "tower 0.4.13", "tracing", + "url", ] [[package]] @@ -115,6 +123,7 @@ dependencies = [ "serde", "serde_json", "serde_with", + "sp1-sdk", "thiserror 2.0.11", "toml", "tracing", @@ -126,6 +135,7 @@ dependencies = [ name = "aggkit-prover-types" version = "0.1.0" dependencies = [ + "aggchain-proof-core", "anyhow", "bincode", "prost", @@ -247,16 +257,62 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "alloy" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5295219c9bc87cfa2497131423921e8ea136ee7e2ab338967078995168431d5" +dependencies = [ + "alloy-consensus 0.11.0", + "alloy-core", + "alloy-eips 0.11.0", + "alloy-json-rpc 0.11.0", + "alloy-network 0.11.0", + "alloy-provider", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-transport", + "alloy-transport-http", +] + +[[package]] +name = "alloy-chains" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0d6c784abf2e061139798d51299da278fc8f02d7b7546662b898d9b22ab5e9" +dependencies = [ + "alloy-primitives", + "num_enum 0.7.3", + "strum", +] + [[package]] name = "alloy-consensus" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e88e1edea70787c33e11197d3f32ae380f3db19e6e061e539a5bcf8184a6b326" dependencies = [ - "alloy-eips", + "alloy-eips 0.8.3", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.8.3", + "alloy-trie", + "auto_impl", + "c-kzg", + "derive_more", + "serde", +] + +[[package]] +name = "alloy-consensus" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce20c85f6b24a5da40b2350a748e348417f0465dedbb523a4d149143bc4a41ce" +dependencies = [ + "alloy-eips 0.11.0", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.11.0", "alloy-trie", "auto_impl", "c-kzg", @@ -270,14 +326,50 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57b1bb53f40c0273cd1975573cd457b39213e68584e36d1401d25fd0398a1d65" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.8.3", + "alloy-eips 0.8.3", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.8.3", + "serde", +] + +[[package]] +name = "alloy-consensus-any" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e23af02ccded0031ef2b70df4fe9965b1c742c5d5384c8c767ae0311f7e62b9" +dependencies = [ + "alloy-consensus 0.11.0", + "alloy-eips 0.11.0", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.11.0", "serde", ] +[[package]] +name = "alloy-core" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648275bb59110f88cc5fa9a176845e52a554ebfebac2d21220bcda8c9220f797" +dependencies = [ + "alloy-primitives", + "alloy-rlp", +] + +[[package]] +name = "alloy-eip2124" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675264c957689f0fd75f5993a73123c2cc3b5c235a38f5b9037fe6c826bfb2c0" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "crc", + "thiserror 2.0.11", +] + [[package]] name = "alloy-eip2930" version = "0.1.0" @@ -301,6 +393,18 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-eip7702" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabf647eb4650c91a9d38cb6f972bb320009e7e9d61765fb688a86f1563b33e8" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more", + "serde", +] + [[package]] name = "alloy-eips" version = "0.8.3" @@ -308,10 +412,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f9fadfe089e9ccc0650473f2d4ef0a28bc015bbca5631d9f0f09e49b557fdb3" dependencies = [ "alloy-eip2930", - "alloy-eip7702", + "alloy-eip7702 0.4.2", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.8.3", + "c-kzg", + "derive_more", + "once_cell", + "serde", + "sha2 0.10.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "alloy-eips" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7149e011edbd588f6df6564b369c75f6b538d76db14053d95e0b43b2d92e4266" +dependencies = [ + "alloy-eip2124", + "alloy-eip2930", + "alloy-eip7702 0.5.0", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.11.0", + "auto_impl", "c-kzg", "derive_more", "once_cell", @@ -345,22 +469,61 @@ dependencies = [ "tracing", ] +[[package]] +name = "alloy-json-rpc" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0c5c9651fd20a2fd4a57606b6a570d1c17ab86e686b962b2f1ecac68b51e020" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror 2.0.11", + "tracing", +] + [[package]] name = "alloy-network" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "510cc00b318db0dfccfdd2d032411cfae64fc144aef9679409e014145d3dacc4" dependencies = [ - "alloy-consensus", - "alloy-consensus-any", - "alloy-eips", - "alloy-json-rpc", - "alloy-network-primitives", + "alloy-consensus 0.8.3", + "alloy-consensus-any 0.8.3", + "alloy-eips 0.8.3", + "alloy-json-rpc 0.8.3", + "alloy-network-primitives 0.8.3", + "alloy-primitives", + "alloy-rpc-types-any 0.8.3", + "alloy-rpc-types-eth 0.8.3", + "alloy-serde 0.8.3", + "alloy-signer 0.8.3", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.11", +] + +[[package]] +name = "alloy-network" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b02ed56783fb2c086a4ac8961175dd6d3ad163e6cf6125f0b83f7de03379b607" +dependencies = [ + "alloy-consensus 0.11.0", + "alloy-consensus-any 0.11.0", + "alloy-eips 0.11.0", + "alloy-json-rpc 0.11.0", + "alloy-network-primitives 0.11.0", "alloy-primitives", - "alloy-rpc-types-any", - "alloy-rpc-types-eth", - "alloy-serde", - "alloy-signer", + "alloy-rpc-types-any 0.11.0", + "alloy-rpc-types-eth 0.11.0", + "alloy-serde 0.11.0", + "alloy-signer 0.11.0", "alloy-sol-types", "async-trait", "auto_impl", @@ -376,10 +539,23 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9081c099e798b8a2bba2145eb82a9a146f01fc7a35e9ab6e7b43305051f97550" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.8.3", + "alloy-eips 0.8.3", "alloy-primitives", - "alloy-serde", + "alloy-serde 0.8.3", + "serde", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0624cfa9311aa8283cd3bf5eed883d0d1e823e2a4d57b30e1b49af4b3678a6b" +dependencies = [ + "alloy-consensus 0.11.0", + "alloy-eips 0.11.0", + "alloy-primitives", + "alloy-serde 0.11.0", "serde", ] @@ -410,6 +586,44 @@ dependencies = [ "tiny-keccak 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "alloy-provider" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c68df5354225da542efeb6d9388b65773b3304309b437416146e9d1e2bc1bd" +dependencies = [ + "alloy-chains", + "alloy-consensus 0.11.0", + "alloy-eips 0.11.0", + "alloy-json-rpc 0.11.0", + "alloy-network 0.11.0", + "alloy-network-primitives 0.11.0", + "alloy-primitives", + "alloy-rpc-client", + "alloy-rpc-types-debug", + "alloy-rpc-types-eth 0.11.0", + "alloy-rpc-types-trace", + "alloy-transport", + "alloy-transport-http", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures", + "futures-utils-wasm", + "lru 0.13.0", + "parking_lot", + "pin-project", + "reqwest 0.12.12", + "serde", + "serde_json", + "thiserror 2.0.11", + "tokio", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "alloy-rlp" version = "0.3.11" @@ -432,15 +646,72 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "alloy-rpc-client" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0371aae9b44a35e374c94c7e1df5cbccf0f52b2ef7c782291ed56e86d88ec106" +dependencies = [ + "alloy-json-rpc 0.11.0", + "alloy-primitives", + "alloy-transport", + "alloy-transport-http", + "futures", + "pin-project", + "reqwest 0.12.12", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower 0.5.2", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1428d64569961b00373c503a3de306656e94ef1f2a474e93fd41a6daae0d6ac7" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types-eth 0.11.0", + "alloy-rpc-types-trace", + "alloy-serde 0.11.0", + "serde", +] + [[package]] name = "alloy-rpc-types-any" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed98e1af55a7d856bfa385f30f63d8d56be2513593655c904a8f4a7ec963aa3e" dependencies = [ - "alloy-consensus-any", - "alloy-rpc-types-eth", - "alloy-serde", + "alloy-consensus-any 0.8.3", + "alloy-rpc-types-eth 0.8.3", + "alloy-serde 0.8.3", +] + +[[package]] +name = "alloy-rpc-types-any" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e119337400d8b0348e1576ab37ffa56d1a04cbc977a84d4fa0a527d7cb0c21" +dependencies = [ + "alloy-consensus-any 0.11.0", + "alloy-rpc-types-eth 0.11.0", + "alloy-serde 0.11.0", +] + +[[package]] +name = "alloy-rpc-types-debug" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea98e1c4ac005ffe5f8691164f5f2ef5ee8dda50b1fdba173d44892141909e2" +dependencies = [ + "alloy-primitives", + "serde", ] [[package]] @@ -449,13 +720,13 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8737d7a6e37ca7bba9c23e9495c6534caec6760eb24abc9d5ffbaaba147818e1" dependencies = [ - "alloy-consensus", - "alloy-consensus-any", - "alloy-eips", - "alloy-network-primitives", + "alloy-consensus 0.8.3", + "alloy-consensus-any 0.8.3", + "alloy-eips 0.8.3", + "alloy-network-primitives 0.8.3", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.8.3", "alloy-sol-types", "derive_more", "itertools 0.13.0", @@ -463,6 +734,40 @@ dependencies = [ "serde_json", ] +[[package]] +name = "alloy-rpc-types-eth" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a4a43d8b1344e3ef115ed7a2cee934876e4a64d2b9d9bee8738f9806900757e" +dependencies = [ + "alloy-consensus 0.11.0", + "alloy-consensus-any 0.11.0", + "alloy-eips 0.11.0", + "alloy-network-primitives 0.11.0", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.11.0", + "alloy-sol-types", + "itertools 0.13.0", + "serde", + "serde_json", + "thiserror 2.0.11", +] + +[[package]] +name = "alloy-rpc-types-trace" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac383c60b09660b7695a4f210cd11ab05887d058dfc669efd814904dbbaead82" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types-eth 0.11.0", + "alloy-serde 0.11.0", + "serde", + "serde_json", + "thiserror 2.0.11", +] + [[package]] name = "alloy-serde" version = "0.8.3" @@ -474,6 +779,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "alloy-serde" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86aa42c36e3c0db5bd9a7314e98aa261a61d5e3d6a0bd7e51fb8b0a3d6438481" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + [[package]] name = "alloy-signer" version = "0.8.3" @@ -488,16 +804,30 @@ dependencies = [ "thiserror 2.0.11", ] +[[package]] +name = "alloy-signer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c613222abd016e03ba548f41db938a2c99108b59c0c66ca105eab1b7a2e6b40a" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror 2.0.11", +] + [[package]] name = "alloy-signer-local" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47fababf5a745133490cde927d48e50267f97d3d1209b9fc9f1d1d666964d172" dependencies = [ - "alloy-consensus", - "alloy-network", + "alloy-consensus 0.8.3", + "alloy-network 0.8.3", "alloy-primitives", - "alloy-signer", + "alloy-signer 0.8.3", "async-trait", "k256", "rand", @@ -574,6 +904,40 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-transport" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e2f34fcd849676c8fe274a6e72f0664dfede7ce06d12daa728d2e72f1b4393" +dependencies = [ + "alloy-json-rpc 0.11.0", + "base64 0.22.1", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.11", + "tokio", + "tower 0.5.2", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-transport-http" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e291c97c3c0ebb5d03c34e3a55c0f7c5bfa307536a2efaaa6fae4b3a4d09851" +dependencies = [ + "alloy-json-rpc 0.11.0", + "alloy-transport", + "reqwest 0.12.12", + "serde_json", + "tower 0.5.2", + "tracing", + "url", +] + [[package]] name = "alloy-trie" version = "0.7.8" @@ -1621,6 +1985,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.4.2" @@ -1746,6 +2125,20 @@ dependencies = [ "syn 2.0.96", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "dashu" version = "0.4.2" @@ -3946,6 +4339,15 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "lru" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" +dependencies = [ + "hashbrown 0.15.2", +] + [[package]] name = "matchers" version = "0.1.0" @@ -5152,17 +5554,16 @@ dependencies = [ name = "proposer-client" version = "0.1.0" dependencies = [ + "aggkit-prover-config", "alloy-primitives", "anyhow", "hex", - "prover-utils", "reqwest 0.12.12", "serde", "sp1-sdk", "thiserror 2.0.11", "tonic", "tracing", - "url", ] [[package]] @@ -5179,6 +5580,7 @@ dependencies = [ "sp1-sdk", "thiserror 2.0.11", "tower 0.4.13", + "url", ] [[package]] @@ -6708,7 +7110,7 @@ dependencies = [ "eyre", "hex", "itertools 0.13.0", - "lru", + "lru 0.12.5", "num-bigint 0.4.6", "p3-baby-bear", "p3-bn254-fr", @@ -6879,7 +7281,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b47b98599a826c8d24976791495bc59c7d8be3af97a515cf5f7a7c3b02daa835" dependencies = [ "alloy-primitives", - "alloy-signer", + "alloy-signer 0.8.3", "alloy-signer-local", "alloy-sol-types", "anyhow", @@ -8129,6 +8531,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmtimer" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0048ad49a55b9deb3953841fa1fc5858f0efbcb7a18868c899a360269fac1b23" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.77" diff --git a/crates/aggchain-proof-builder/Cargo.toml b/crates/aggchain-proof-builder/Cargo.toml index 8aa69df..f971c65 100644 --- a/crates/aggchain-proof-builder/Cargo.toml +++ b/crates/aggchain-proof-builder/Cargo.toml @@ -5,10 +5,32 @@ edition.workspace = true license.workspace = true [dependencies] +aggchain-proof-core.workspace = true +aggkit-prover-config.workspace = true +aggkit-prover-types.workspace = true +alloy = { version = '0.11.0', default-features = false, features = [ + "consensus", + "reqwest", + "json-rpc", + "rlp", + "rpc", + "rpc-client", + "rpc-types-eth", + "rpc-types-trace", + "providers", + "transports", + "transport-http", + "rpc-types-debug", +] } + +anyhow.workspace = true futures.workspace = true thiserror.workspace = true tower = { workspace = true, features = ["timeout"] } tracing.workspace = true +serde = { workspace = true, features = ["derive"] } +sp1-sdk = { workspace = true, features = ["native-gnark"] } +url = "2.5.4" [lints] workspace = true diff --git a/crates/aggchain-proof-builder/src/lib.rs b/crates/aggchain-proof-builder/src/lib.rs index 4ea6cad..1c7926c 100644 --- a/crates/aggchain-proof-builder/src/lib.rs +++ b/crates/aggchain-proof-builder/src/lib.rs @@ -1,22 +1,110 @@ +mod provider; + +use std::sync::Arc; use std::task::{Context, Poll}; +use aggchain_proof_core::proof::AggchainProofWitness; +use aggkit_prover_config::aggchain_proof_service::{ + HTTP_RPC_NODE_BACKOFF_MAX_RETRIES, HTTP_RPC_NODE_INITIAL_BACKOFF_MS, +}; +use aggkit_prover_config::AggchainProofBuilderConfig; +use aggkit_prover_types::AggchainProof; +use alloy::eips::{BlockId, BlockNumberOrTag}; +use alloy::network::primitives::BlockTransactionsKind; +use alloy::primitives::B256; +use alloy::providers::Provider; +use alloy::transports::{RpcError, TransportErrorKind}; use futures::{future::BoxFuture, FutureExt}; +use sp1_sdk::SP1ProofWithPublicValues; + +use crate::provider::json_rpc::{build_http_retry_provider, AlloyProvider}; + +pub struct AgghcainProofBuilderRequest { + pub agg_span_proof: SP1ProofWithPublicValues, + // TODO add rest of the fields +} -pub struct Request {} -pub struct Response {} +#[derive(Clone, Debug)] +pub struct AgghcainProofBuilderResponse { + pub proof: AggchainProof, +} #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Noop")] - Noop, + #[error("Alloy error: {0}")] + AlloyProviderError(String), + + #[error("Alloy transport rpc error: {0:?}")] + AlloyRpcTransportError(RpcError), + + #[error("Proof generation error: {0:?}")] + ProofGenerationError(aggchain_proof_core::error::ProofError), } /// This service is responsible for building an Aggchain proof. -#[derive(Default, Clone)] -pub struct AggchainProofBuilderService {} +#[derive(Debug, Clone)] +pub struct AggchainProofBuilder { + l1_client: Arc, + #[allow(unused)] + l2_client: Arc, +} + +impl AggchainProofBuilder { + pub fn new(config: &AggchainProofBuilderConfig) -> Result { + Ok(AggchainProofBuilder { + l1_client: Arc::new( + build_http_retry_provider( + &config.l1_rpc_endpoint, + HTTP_RPC_NODE_INITIAL_BACKOFF_MS, + HTTP_RPC_NODE_BACKOFF_MAX_RETRIES, + ) + .map_err(|e| Error::AlloyProviderError(e.to_string()))?, + ), + l2_client: Arc::new( + build_http_retry_provider( + &config.l2_rpc_endpoint, + HTTP_RPC_NODE_INITIAL_BACKOFF_MS, + HTTP_RPC_NODE_BACKOFF_MAX_RETRIES, + ) + .map_err(|e| Error::AlloyProviderError(e.to_string()))?, + ), + }) + } + + pub async fn get_l1_block_hash(&self, block_num: u64) -> Result { + let block = self + .l1_client + .get_block( + BlockId::Number(BlockNumberOrTag::Number(block_num)), + BlockTransactionsKind::Hashes, + ) + .await + .map_err(Error::AlloyRpcTransportError)? + .ok_or(Error::AlloyProviderError(format!( + "target block {block_num} does not exist" + )))?; -impl tower::Service for AggchainProofBuilderService { - type Response = Response; + Ok(block.header.hash) + } + + // Retrieve l1 and l2 public data needed for aggchain proof generation + pub async fn retrieve_chain_data(&self) -> Result<(), Error> { + //TODO decide output structure + todo!() + } + + // Generate aggchain proof + pub async fn generate_aggchain_proof( + &self, + mut _aggchain_proof_witness: AggchainProofWitness, + ) -> Result { + //TODO implement + todo!() + } +} + +impl tower::Service for AggchainProofBuilder { + type Response = AgghcainProofBuilderResponse; type Error = Error; @@ -26,7 +114,20 @@ impl tower::Service for AggchainProofBuilderService { todo!() } - fn call(&mut self, _req: Request) -> Self::Future { - async move { Ok(Response {}) }.boxed() + fn call(&mut self, _req: AgghcainProofBuilderRequest) -> Self::Future { + async move { + //TODO implement + + // Call all necessary data retrieval + //self.retrieve_chain_data().await?; + + // Generate proof + //self.generate_aggchain_proof().await?; + + Ok(AgghcainProofBuilderResponse { + proof: Default::default(), + }) + } + .boxed() } } diff --git a/crates/aggchain-proof-builder/src/provider/json_rpc.rs b/crates/aggchain-proof-builder/src/provider/json_rpc.rs new file mode 100644 index 0000000..887f47c --- /dev/null +++ b/crates/aggchain-proof-builder/src/provider/json_rpc.rs @@ -0,0 +1,46 @@ +use std::time::Duration; + +use alloy::network::Ethereum; +use alloy::providers::fillers::{ + BlobGasFiller, ChainIdFiller, FillProvider, GasFiller, JoinFill, NonceFiller, +}; +use alloy::providers::Identity; +use alloy::transports::http::reqwest; +use alloy::transports::layers::RetryBackoffLayer; +use alloy::{ + providers::{ProviderBuilder, RootProvider}, + rpc::client::ClientBuilder, +}; + +const HTTP_CLIENT_CONNECTION_POOL_IDLE_TIMEOUT: u64 = 90; +const HTTP_CLIENT_MAX_IDLE_CONNECTIONS_PER_HOST: usize = 64; + +pub type AlloyProvider = FillProvider< + JoinFill< + Identity, + JoinFill>>, + >, + RootProvider, + Ethereum, +>; + +pub fn build_http_retry_provider( + rpc_url: &url::Url, + backoff: u64, + max_retries: u32, +) -> Result { + let retry_policy = RetryBackoffLayer::new(max_retries, backoff, 5); + let reqwest_client = reqwest::ClientBuilder::new() + .pool_max_idle_per_host(HTTP_CLIENT_MAX_IDLE_CONNECTIONS_PER_HOST) + .pool_idle_timeout(Duration::from_secs( + HTTP_CLIENT_CONNECTION_POOL_IDLE_TIMEOUT, + )) + .build()?; + + let http = alloy::transports::http::Http::with_client(reqwest_client, rpc_url.clone()); + let is_local = http.guess_local(); + let client = ClientBuilder::default() + .layer(retry_policy) + .transport(http, is_local); + Ok(ProviderBuilder::new().on_client(client)) +} diff --git a/crates/aggchain-proof-builder/src/provider/mod.rs b/crates/aggchain-proof-builder/src/provider/mod.rs new file mode 100644 index 0000000..c60b700 --- /dev/null +++ b/crates/aggchain-proof-builder/src/provider/mod.rs @@ -0,0 +1 @@ +pub(crate) mod json_rpc; diff --git a/crates/aggchain-proof-core/src/lib.rs b/crates/aggchain-proof-core/src/lib.rs index 81a824c..e1c2090 100644 --- a/crates/aggchain-proof-core/src/lib.rs +++ b/crates/aggchain-proof-core/src/lib.rs @@ -1,4 +1,4 @@ mod digest; -mod error; +pub mod error; mod full_execution_proof; pub mod proof; diff --git a/crates/aggchain-proof-core/src/proof.rs b/crates/aggchain-proof-core/src/proof.rs index 41baef3..162e2fa 100644 --- a/crates/aggchain-proof-core/src/proof.rs +++ b/crates/aggchain-proof-core/src/proof.rs @@ -56,7 +56,7 @@ impl AggchainProofWitness { } /// Public values of the SP1 aggchain proof. -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Default, Clone, Debug)] pub struct AggchainProofPublicValues { /// Previous local exit root. pub prev_local_exit_root: Digest, diff --git a/crates/aggkit-prover-config/Cargo.toml b/crates/aggkit-prover-config/Cargo.toml index e45df6c..0462ea0 100644 --- a/crates/aggkit-prover-config/Cargo.toml +++ b/crates/aggkit-prover-config/Cargo.toml @@ -10,6 +10,7 @@ humantime-serde = "1.1.1" jsonrpsee.workspace = true serde = { workspace = true, features = ["derive"] } serde_with.workspace = true +sp1-sdk = { workspace = true, features = ["native-gnark"] } thiserror.workspace = true toml.workspace = true tracing.workspace = true diff --git a/crates/aggkit-prover-config/src/aggchain_proof_builder.rs b/crates/aggkit-prover-config/src/aggchain_proof_builder.rs new file mode 100644 index 0000000..9c120a5 --- /dev/null +++ b/crates/aggkit-prover-config/src/aggchain_proof_builder.rs @@ -0,0 +1,37 @@ +use std::str::FromStr; + +use jsonrpsee::core::Serialize; +use serde::Deserialize; +use url::Url; + +/// The Aggchain proof builder configuration +#[derive(Serialize, Deserialize, Clone, Debug)] +#[serde(rename_all = "kebab-case")] +pub struct AggchainProofBuilderConfig { + /// Json rpc endpoint of the l1 node. + pub l1_rpc_endpoint: Url, + + /// Json rpc endpoint of the l2 rollup node. + pub l2_rpc_endpoint: Url, + + /// Id of the rollup chain + pub rollup_id: u32, +} + +impl Default for AggchainProofBuilderConfig { + fn default() -> Self { + AggchainProofBuilderConfig { + l1_rpc_endpoint: default_l1_url(), + l2_rpc_endpoint: default_l2_url(), + rollup_id: 0, + } + } +} + +fn default_l1_url() -> Url { + Url::from_str("127.0.0.1::8545").unwrap() +} + +fn default_l2_url() -> Url { + Url::from_str("127.0.0.1::8546").unwrap() +} diff --git a/crates/aggkit-prover-config/src/aggchain_proof_service.rs b/crates/aggkit-prover-config/src/aggchain_proof_service.rs new file mode 100644 index 0000000..22476d8 --- /dev/null +++ b/crates/aggkit-prover-config/src/aggchain_proof_service.rs @@ -0,0 +1,20 @@ +use std::fmt::Debug; + +use serde::{Deserialize, Serialize}; + +use crate::aggchain_proof_builder::AggchainProofBuilderConfig; +use crate::proposer_service::ProposerServiceConfig; + +/// The initial blockchain node backoff in milliseconds +pub const HTTP_RPC_NODE_INITIAL_BACKOFF_MS: u64 = 5000; + +/// The blockchain node backoff number of retries +pub const HTTP_RPC_NODE_BACKOFF_MAX_RETRIES: u32 = 64; + +/// The Aggchain proof service configuration +#[derive(Serialize, Deserialize, Clone, Debug, Default)] +#[serde(rename_all = "kebab-case")] +pub struct AggchainProofServiceConfig { + pub aggchain_proof_builder_config: AggchainProofBuilderConfig, + pub proposer_service_config: ProposerServiceConfig, +} diff --git a/crates/aggkit-prover-config/src/lib.rs b/crates/aggkit-prover-config/src/lib.rs index 89b9433..31e0f78 100644 --- a/crates/aggkit-prover-config/src/lib.rs +++ b/crates/aggkit-prover-config/src/lib.rs @@ -3,18 +3,25 @@ use std::path::Path; use prover_config::{NetworkProverConfig, ProverType}; use prover_logger::log::Log; -use prover_utils::with; use serde::{Deserialize, Serialize}; -pub use crate::{shutdown::ShutdownConfig, telemetry::TelemetryConfig}; +use crate::aggchain_proof_service::AggchainProofServiceConfig; +pub use crate::{ + aggchain_proof_builder::AggchainProofBuilderConfig, shutdown::ShutdownConfig, + telemetry::TelemetryConfig, +}; +pub mod aggchain_proof_service; + +pub mod aggchain_proof_builder; +pub mod proposer_service; pub mod shutdown; pub(crate) mod telemetry; pub(crate) const DEFAULT_IP: std::net::Ipv4Addr = std::net::Ipv4Addr::new(0, 0, 0, 0); /// The Aggkit Prover configuration. -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, Clone)] #[serde(rename_all = "kebab-case")] pub struct ProverConfig { /// The gRPC endpoint used by the prover. @@ -36,6 +43,9 @@ pub struct ProverConfig { #[serde(default)] pub shutdown: ShutdownConfig, + /// Aggchain proof service configuration + pub aggchain_proof_service: AggchainProofServiceConfig, + /// The primary prover to be used for generation of the pessimistic proof #[serde(default)] pub primary_prover: ProverType, @@ -52,6 +62,7 @@ impl Default for ProverConfig { log: Log::default(), telemetry: TelemetryConfig::default(), shutdown: ShutdownConfig::default(), + aggchain_proof_service: AggchainProofServiceConfig::default(), primary_prover: ProverType::NetworkProver(NetworkProverConfig::default()), fallback_prover: None, grpc: Default::default(), @@ -74,7 +85,7 @@ impl ProverConfig { } } -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "kebab-case")] pub struct GrpcConfig { #[serde( diff --git a/crates/proposer-client/src/config.rs b/crates/aggkit-prover-config/src/proposer_service.rs similarity index 89% rename from crates/proposer-client/src/config.rs rename to crates/aggkit-prover-config/src/proposer_service.rs index 66cbfcb..a8fc991 100644 --- a/crates/proposer-client/src/config.rs +++ b/crates/aggkit-prover-config/src/proposer_service.rs @@ -1,8 +1,15 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone, Default)] +#[serde(rename_all = "kebab-case")] +pub struct ProposerServiceConfig { + pub client: ProposerClientConfig, +} + use std::str::FromStr; use std::time::Duration; use prover_utils::from_env_or_default; -use serde::{Deserialize, Serialize}; use url::Url; /// The default proposer service endpoint diff --git a/crates/aggkit-prover-config/src/shutdown.rs b/crates/aggkit-prover-config/src/shutdown.rs index 9c85906..eb9ea2f 100644 --- a/crates/aggkit-prover-config/src/shutdown.rs +++ b/crates/aggkit-prover-config/src/shutdown.rs @@ -7,7 +7,7 @@ use serde::Serialize; #[serde(rename_all = "kebab-case")] pub struct ShutdownConfig { #[serde(default = "default_shutdown_runtime_timeout")] - #[serde(with = "crate::with::HumanDuration")] + #[serde(with = "prover_utils::with::HumanDuration")] pub runtime_timeout: Duration, } diff --git a/crates/aggkit-prover-types/Cargo.toml b/crates/aggkit-prover-types/Cargo.toml index e0b3c0a..a8850da 100644 --- a/crates/aggkit-prover-types/Cargo.toml +++ b/crates/aggkit-prover-types/Cargo.toml @@ -6,6 +6,7 @@ license.workspace = true [dependencies] anyhow.workspace = true +aggchain-proof-core.workspace = true bincode.workspace = true prost = "0.13.4" serde.workspace = true diff --git a/crates/aggkit-prover-types/src/lib.rs b/crates/aggkit-prover-types/src/lib.rs index 1f33986..6c7f74c 100644 --- a/crates/aggkit-prover-types/src/lib.rs +++ b/crates/aggkit-prover-types/src/lib.rs @@ -1,7 +1,10 @@ +use aggchain_proof_core::proof::AggchainProofPublicValues; use bincode::{ config::{BigEndian, FixintEncoding, WithOtherEndian, WithOtherIntEncoding}, DefaultOptions, Options, }; +use serde::{Deserialize, Serialize}; + pub const FILE_DESCRIPTOR_SET: &[u8] = include_bytes!("generated/aggkit.prover.bin"); #[path = "generated/aggkit.prover.v1.rs"] @@ -15,3 +18,13 @@ pub fn default_bincode_options( .with_big_endian() .with_fixint_encoding() } + +pub type Hash = [u8; 32]; + +/// Agghchain proof is generated from FEP proof and additional +/// bridge inputs +#[derive(Serialize, Deserialize, Default, Clone, Debug)] +pub struct AggchainProof { + proof: AggchainProofPublicValues, + //TODO add all necessary fields +} diff --git a/crates/aggkit-prover/src/aggchain_proof/error.rs b/crates/aggkit-prover/src/aggchain_proof/error.rs index 9c75a09..08a6e48 100644 --- a/crates/aggkit-prover/src/aggchain_proof/error.rs +++ b/crates/aggkit-prover/src/aggchain_proof/error.rs @@ -1,5 +1,20 @@ #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Noop")] - Noop, + #[error("Proposer service error: {0}")] + ProposerService(proposer_service::Error), + + #[error("Aggchain proof builder error: {0}")] + AggchainProofBuilder(aggchain_proof_builder::Error), +} + +impl From for Error { + fn from(e: proposer_service::Error) -> Self { + Self::ProposerService(e) + } +} + +impl From for Error { + fn from(e: aggchain_proof_builder::Error) -> Self { + Self::AggchainProofBuilder(e) + } } diff --git a/crates/aggkit-prover/src/aggchain_proof/mod.rs b/crates/aggkit-prover/src/aggchain_proof/mod.rs index cec7dbf..a0e447a 100644 --- a/crates/aggkit-prover/src/aggchain_proof/mod.rs +++ b/crates/aggkit-prover/src/aggchain_proof/mod.rs @@ -1,4 +1,4 @@ -pub(crate) mod error; +pub mod error; pub(crate) mod rpc; pub(crate) mod service; diff --git a/crates/aggkit-prover/src/aggchain_proof/rpc.rs b/crates/aggkit-prover/src/aggchain_proof/rpc.rs index e4fa540..485ea96 100644 --- a/crates/aggkit-prover/src/aggchain_proof/rpc.rs +++ b/crates/aggkit-prover/src/aggchain_proof/rpc.rs @@ -1,19 +1,32 @@ +use aggkit_prover_config::aggchain_proof_service::AggchainProofServiceConfig; use aggkit_prover_types::v1::{ aggchain_proof_service_server::AggchainProofService as AggchainProofGrpcService, GenerateAggchainProofRequest, GenerateAggchainProofResponse, }; +use aggkit_prover_types::{default_bincode_options, Hash}; +use bincode::Options; use tonic::{Request, Response, Status}; use tonic_types::{ErrorDetails, StatusExt}; use tower::{Service, ServiceExt}; use tracing::instrument; -use super::service::{AggchainProofService, ProofRequest}; +use super::service::{AggchainProofService, AggchainProofServiceRequest}; -#[derive(Default, Clone)] +#[derive(Clone)] pub struct GrpcService { service: AggchainProofService, } +impl GrpcService { + pub fn new( + config: &AggchainProofServiceConfig, + ) -> Result { + Ok(GrpcService { + service: AggchainProofService::new(config)?, + }) + } +} + #[tonic::async_trait] impl AggchainProofGrpcService for GrpcService { #[instrument(skip(self))] @@ -35,9 +48,26 @@ impl AggchainProofGrpcService for GrpcService { error, )); } - let proof_request = ProofRequest { + + let l1_info_tree_root_hash: Hash = + request.l1_info_tree_root_hash.try_into().map_err(|_| { + let mut error_details = ErrorDetails::new(); + error_details.add_bad_request_violation( + "l1_info_tree_root_hash", + "l1 info tree root hash must be non empty and 32 bytes long", + ); + Status::with_error_details( + tonic::Code::InvalidArgument, + "Invalid l1 info tree root hash", + error_details, + ) + })?; + + let proof_request = AggchainProofServiceRequest { start_block: request.start_block, max_block: request.max_end_block, + l1_info_tree_root_hash, + ..Default::default() }; let mut service = self.service.clone(); @@ -48,11 +78,16 @@ impl AggchainProofGrpcService for GrpcService { .map_err(|_| Status::internal("Unable to get the service"))?; match service.call(proof_request).await { - Ok(_response) => Ok(Response::new(GenerateAggchainProofResponse { - aggchain_proof: Vec::new(), - start_block: 0, - end_block: 0, - })), + Ok(response) => { + let aggchain_proof = default_bincode_options() + .serialize(&response.proof) + .map_err(|e| Status::internal(format!("Unable to serialize proof: {e:?}")))?; + Ok(Response::new(GenerateAggchainProofResponse { + aggchain_proof, + start_block: response.start_block, + end_block: response.end_block, + })) + } Err(e) => Err(Status::internal(e.to_string())), } } diff --git a/crates/aggkit-prover/src/aggchain_proof/service.rs b/crates/aggkit-prover/src/aggchain_proof/service.rs index e48b8a5..d24ccc8 100644 --- a/crates/aggkit-prover/src/aggchain_proof/service.rs +++ b/crates/aggkit-prover/src/aggchain_proof/service.rs @@ -4,71 +4,116 @@ use std::{ task::{Context, Poll}, }; -use aggchain_proof_builder::{AggchainProofBuilderService, Request as ProofBuilderRequest}; -use proposer_service::{ProposerService, Request as ProposerRequest}; +use aggchain_proof_builder::{ + AggchainProofBuilder, AgghcainProofBuilderRequest as ProofBuilderRequest, +}; +use aggkit_prover_config::aggchain_proof_service::AggchainProofServiceConfig; +use aggkit_prover_types::{AggchainProof, Hash}; +use proposer_service::{ProposerRequest, ProposerService}; +use tracing::debug; use super::error::Error; -pub struct ProofRequest { - #[allow(dead_code)] +/// Request to the AggchainProofService to generate the +/// aggchain proof for the range of blocks. +#[derive(Default, Clone, Debug)] +#[allow(unused)] +pub struct AggchainProofServiceRequest { + /// Aggchain proof starting block pub start_block: u64, - #[allow(dead_code)] + /// Max number of blocks that the aggchain proof could contain pub max_block: u64, + /// L1 Info tree root hash. + pub l1_info_tree_root_hash: Hash, + /// L1 Info tree leaf hash. + pub l1_info_tree_leaf_hash: Hash, + /// L1 Info tree proof. + pub l1_info_tree_merkle_proof: [Hash; 32], } -pub struct ProofResponse {} +/// Resulting generated Aggchain proof +pub struct AggchainProofServiceResponse { + pub proof: AggchainProof, + pub start_block: u64, + pub end_block: u64, +} /// The Aggchain proof service is responsible for orchestrating an Aggchain /// proof generation. /// /// The Aggchain proof is generated by fetching the Aggregated FEP from the -/// proposer service and the aggchain proof builder service to generate the +/// proposer service and the `aggchain-proof-builder` service to generate the /// Aggchain proof. #[derive(Clone)] pub(crate) struct AggchainProofService { pub(crate) proposer_service: ProposerService, - pub(crate) aggchain_proof_builder: AggchainProofBuilderService, + pub(crate) aggchain_proof_builder: AggchainProofBuilder, } -impl Default for AggchainProofService { - fn default() -> Self { - // Implement new function and remove this default - todo!() +impl AggchainProofService { + pub fn new(config: &AggchainProofServiceConfig) -> Result { + Ok(AggchainProofService { + proposer_service: ProposerService::new(&config.proposer_service_config)?, + aggchain_proof_builder: AggchainProofBuilder::new( + &config.aggchain_proof_builder_config, + )?, + }) } } -impl tower::Service for AggchainProofService { - type Response = ProofResponse; +impl tower::Service for AggchainProofService { + type Response = AggchainProofServiceResponse; type Error = Error; type Future = Pin> + Send>>; fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> { - if self - .proposer_service - .poll_ready(cx) - .map_err(|_| Error::Noop) - .is_pending() - { - return Poll::Pending; - } + match self.proposer_service.poll_ready(cx) { + Poll::Ready(Ok(())) => (), + Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())), + Poll::Pending => return Poll::Pending, + }; self.aggchain_proof_builder .poll_ready(cx) - .map_err(|_| Error::Noop) + .map_err(Error::from) } - fn call(&mut self, _req: ProofRequest) -> Self::Future { - let mut proposer_client = self.proposer_service.clone(); + fn call(&mut self, req: AggchainProofServiceRequest) -> Self::Future { + let mut proposer_service = self.proposer_service.clone(); let mut proof_builder = self.aggchain_proof_builder.clone(); let fut = async move { + // TODO: check what l1_block_number should be + let l1_block_number = req.max_block; + let l1_block_hash = proof_builder.get_l1_block_hash(l1_block_number).await?; + + let proposer_request = ProposerRequest { + start_block: req.start_block, + max_block: req.max_block, + l1_block_number, + l1_block_hash, + }; + // Fetch Aggregated FEP - let _result = proposer_client.call(ProposerRequest {}).await.unwrap(); + let agg_span_proof_response = proposer_service.call(proposer_request).await?; + // Fetch the private inputs for Aggchain proof - proof_builder.call(ProofBuilderRequest {}).await.unwrap(); - // Generate Aggchain proof + let _aggchain_proof_builder_response = proof_builder + .call(ProofBuilderRequest { + agg_span_proof: agg_span_proof_response.agg_span_proof, + }) + .await?; + + // TODO Aggchain proof should be available here from the + // `aggchain_proof_builder_response` + let aggchain_proof = AggchainProof::default(); + debug!("The proof is {:?}", aggchain_proof); - Ok(ProofResponse {}) + Ok(AggchainProofServiceResponse { + proof: AggchainProof::default(), + start_block: Default::default(), + end_block: Default::default(), + }) }; Box::pin(fut) diff --git a/crates/aggkit-prover/src/aggchain_proof/tests/mod.rs b/crates/aggkit-prover/src/aggchain_proof/tests/mod.rs index ff824a3..1458047 100644 --- a/crates/aggkit-prover/src/aggchain_proof/tests/mod.rs +++ b/crates/aggkit-prover/src/aggchain_proof/tests/mod.rs @@ -9,7 +9,7 @@ use tonic_types::StatusExt; use tower::{service_fn, Service}; use crate::aggchain_proof::{ - service::{AggchainProofService, ProofRequest}, + service::{AggchainProofService, AggchainProofServiceRequest}, GrpcService, }; @@ -21,7 +21,7 @@ async fn service_can_be_called() { "0xaabbccddff000000000000000000000000000000000000000000000000000000", ); let mut service = AggchainProofService::default(); - let request = ProofRequest { + let request = AggchainProofServiceRequest { start_block: 0, max_block: 100, }; diff --git a/crates/aggkit-prover/src/main.rs b/crates/aggkit-prover/src/main.rs index f81f174..5702078 100644 --- a/crates/aggkit-prover/src/main.rs +++ b/crates/aggkit-prover/src/main.rs @@ -28,7 +28,8 @@ fn main() -> anyhow::Result<()> { .build()?; // TODO: implement the aggchain-proof service - let aggchain_proof_service = AggchainProofServiceServer::new(GrpcService::default()); + let aggchain_proof_service = + AggchainProofServiceServer::new(GrpcService::new(&config.aggchain_proof_service)?); _ = ProverEngine::builder() .add_rpc_service(aggchain_proof_service) diff --git a/crates/proposer-client/Cargo.toml b/crates/proposer-client/Cargo.toml index 016add5..9309ccc 100644 --- a/crates/proposer-client/Cargo.toml +++ b/crates/proposer-client/Cargo.toml @@ -11,13 +11,13 @@ workspace = true anyhow.workspace = true alloy-primitives.workspace = true hex.workspace = true -prover-utils.workspace = true +aggkit-prover-config.workspace = true reqwest = { workspace = true, features = ["json"]} serde.workspace = true thiserror.workspace = true tracing.workspace = true tonic.workspace = true -url.workspace = true + sp1-sdk = { workspace = true, features = ["native-gnark"] } diff --git a/crates/proposer-client/src/lib.rs b/crates/proposer-client/src/lib.rs index 0a62077..fdc48bb 100644 --- a/crates/proposer-client/src/lib.rs +++ b/crates/proposer-client/src/lib.rs @@ -2,25 +2,23 @@ use std::fmt::Display; use std::sync::Arc; use std::time::Duration; +use alloy_primitives::B256; use serde::{Deserialize, Serialize}; use sp1_sdk::SP1ProofWithPublicValues; -pub use crate::config::ProposerClientConfig; pub use crate::error::Error; use crate::network_prover::AggSpanProofProver; use crate::rpc::AggSpanProofProposer; - -pub mod config; pub mod error; pub mod network_prover; pub mod rpc; -/// The Proposer client is responsible for retrieval of the AggProof. -/// AggProof is the aggregated proof of the multiple +/// The Proposer client is responsible for retrieval of the AggSpanProof. +/// AggSpanProof is the aggregated proof of the multiple /// block span full execution proofs. /// /// The proposer client communicates with the proposer API to -/// request creation of the AggProof (getting the proof ID in return), +/// request creation of the AggSpanProof (getting the proof ID in return), /// and directly communicates with the SP1 cluster using NetworkProver /// to retrieve the generated proof. #[derive(Clone)] @@ -47,7 +45,7 @@ where }) } - pub async fn request_agg_proof(&mut self, request: Request) -> Result { + pub async fn request_agg_proof(&self, request: ProposerRequest) -> Result { self.proposer .request_agg_proof(request.into()) .await? @@ -55,7 +53,7 @@ where } pub async fn wait_for_proof( - &mut self, + &self, proof_id: ProofId, ) -> Result { let request_id = proof_id.0; @@ -68,16 +66,16 @@ where } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Request { +pub struct ProposerRequest { pub start_block: u64, pub max_block: u64, pub l1_block_number: u64, - pub l1_block_hash: Vec, + pub l1_block_hash: B256, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct Response { - proofs: Vec, +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ProposerResponse { + pub agg_span_proof: SP1ProofWithPublicValues, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/crates/proposer-client/src/network_prover.rs b/crates/proposer-client/src/network_prover.rs index 6859961..795c815 100644 --- a/crates/proposer-client/src/network_prover.rs +++ b/crates/proposer-client/src/network_prover.rs @@ -5,7 +5,7 @@ use anyhow::Error; use sp1_sdk::{NetworkProver, SP1ProofWithPublicValues}; /// This prover waits for the SP1 cluster generated -/// AggProof based on the proof id. +/// AggSpanProof based on the proof id. #[tonic::async_trait] pub trait AggSpanProofProver { async fn wait_for_proof( diff --git a/crates/proposer-client/src/rpc.rs b/crates/proposer-client/src/rpc.rs index 1f3790d..3c5b2e2 100644 --- a/crates/proposer-client/src/rpc.rs +++ b/crates/proposer-client/src/rpc.rs @@ -1,12 +1,13 @@ use std::fmt::Display; +use alloy_primitives::B256; use serde::{Deserialize, Serialize}; use tracing::info; -use crate::{error::Error, ProofId, Request}; +use crate::{error::Error, ProofId, ProposerRequest}; /// Proposer client that requests the generation -/// of the AggProof from the proposer and gets +/// of the AggSpanProof from the proposer and gets /// proof_id in response. #[tonic::async_trait] pub trait AggSpanProofProposer { @@ -64,12 +65,12 @@ pub struct AggSpanProofProposerRequest { pub start: u64, pub end: u64, pub l1_block_number: u64, - pub l1_block_hash: Vec, + pub l1_block_hash: B256, } -impl From for Request { +impl From for ProposerRequest { fn from(request: AggSpanProofProposerRequest) -> Self { - Request { + ProposerRequest { start_block: request.start, max_block: request.end, l1_block_number: request.l1_block_number, @@ -78,8 +79,8 @@ impl From for Request { } } -impl From for AggSpanProofProposerRequest { - fn from(request: Request) -> Self { +impl From for AggSpanProofProposerRequest { + fn from(request: ProposerRequest) -> Self { AggSpanProofProposerRequest { start: request.start_block, end: request.max_block, diff --git a/crates/proposer-service/Cargo.toml b/crates/proposer-service/Cargo.toml index e1f4c59..0cfa389 100644 --- a/crates/proposer-service/Cargo.toml +++ b/crates/proposer-service/Cargo.toml @@ -18,6 +18,7 @@ aggkit-prover-types.workspace = true proposer-client.workspace = true prover-engine.workspace = true prover-logger.workspace = true +url = "2.5.4" [lints] workspace = true diff --git a/crates/proposer-service/src/config.rs b/crates/proposer-service/src/config.rs deleted file mode 100644 index 2cb2675..0000000 --- a/crates/proposer-service/src/config.rs +++ /dev/null @@ -1,8 +0,0 @@ -use proposer_client::config::ProposerClientConfig; -use serde::{Deserialize, Serialize}; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -#[serde(rename_all = "kebab-case")] -pub struct ProposerServiceConfig { - pub client: ProposerClientConfig, -} diff --git a/crates/proposer-service/src/lib.rs b/crates/proposer-service/src/lib.rs index b8dea20..33f72bc 100644 --- a/crates/proposer-service/src/lib.rs +++ b/crates/proposer-service/src/lib.rs @@ -1,25 +1,25 @@ use std::sync::Arc; use std::task::{Context, Poll}; +use aggkit_prover_config::proposer_service::ProposerServiceConfig; use futures::{future::BoxFuture, FutureExt}; use proposer_client::network_prover::new_network_prover; use proposer_client::rpc::ProposerRpcClient; use proposer_client::ProposerClient; +pub use proposer_client::{ProposerRequest, ProposerResponse}; use sp1_sdk::NetworkProver; -use crate::config::ProposerServiceConfig; - -pub mod config; - pub mod error; +pub use error::Error; + #[derive(Clone)] pub struct ProposerService { pub client: Arc>, } impl ProposerService { - pub fn new(config: ProposerServiceConfig) -> Result { + pub fn new(config: &ProposerServiceConfig) -> Result { let proposer_rpc_client = ProposerRpcClient::new(config.client.proposer_endpoint.as_str())?; let network_prover = new_network_prover(config.client.sp1_cluster_endpoint.as_str()); Ok(Self { @@ -32,14 +32,8 @@ impl ProposerService { } } -pub struct Request {} -pub struct Response {} - -#[derive(thiserror::Error, Debug)] -pub enum Error {} - -impl tower::Service for ProposerService { - type Response = Response; +impl tower::Service for ProposerService { + type Response = ProposerResponse; type Error = Error; @@ -49,7 +43,20 @@ impl tower::Service for ProposerService { Poll::Ready(Ok(())) } - fn call(&mut self, _req: Request) -> Self::Future { - async { Ok(Response {}) }.boxed() + fn call(&mut self, req: ProposerRequest) -> Self::Future { + let client = self.client.clone(); + + async move { + // Request the AggSpanProof generation from the proposer + let proof_id = client.request_agg_proof(req).await?; + + // Wait for the prover to finish aggregating span proofs + let proofs = client.wait_for_proof(proof_id).await?; + + Ok(ProposerResponse { + agg_span_proof: proofs, + }) + } + .boxed() } } diff --git a/crates/prover-config/src/lib.rs b/crates/prover-config/src/lib.rs index f7c1f4a..522a37f 100644 --- a/crates/prover-config/src/lib.rs +++ b/crates/prover-config/src/lib.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use serde_with::serde_as; /// Type of the prover to be used for generation of the pessimistic proof -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "kebab-case")] pub enum ProverType { NetworkProver(NetworkProverConfig), @@ -21,7 +21,7 @@ impl Default for ProverType { } #[serde_as] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "kebab-case")] pub struct CpuProverConfig { #[serde(default = "default_max_concurrency_limit")] @@ -56,7 +56,7 @@ impl Default for CpuProverConfig { } #[serde_as] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "kebab-case")] pub struct NetworkProverConfig { #[serde_as(as = "Option")] @@ -87,7 +87,7 @@ impl Default for NetworkProverConfig { } #[serde_as] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "kebab-case")] pub struct GpuProverConfig { #[serde(default = "default_max_concurrency_limit")] @@ -122,7 +122,7 @@ impl Default for GpuProverConfig { } #[serde_as] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] #[serde(rename_all = "kebab-case")] pub struct MockProverConfig { #[serde(default = "default_max_concurrency_limit")]