diff --git a/.env.example b/.env.example index 40ef30ec0..0679f7e3b 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,2 @@ RPC_1= -CONSENSUS_RPC_1= -BEACONCHAIN_API_KEY_1= -BEACONCHAIN_API_URL_1=https://beaconcha.in \ No newline at end of file +CONSENSUS_RPC_URL= \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index c19d16c11..5112eda0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,7 +181,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -191,7 +191,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -567,18 +567,18 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" +checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" dependencies = [ "serde", ] [[package]] name = "cargo_metadata" -version = "0.17.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", @@ -614,7 +614,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -629,9 +629,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272" dependencies = [ "clap_builder", "clap_derive", @@ -639,9 +639,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" dependencies = [ "anstream", "anstyle", @@ -851,9 +851,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core", @@ -883,7 +883,7 @@ dependencies = [ [[package]] name = "curta" version = "0.1.0" -source = "git+https://github.com/succinctlabs/curta.git#11f52ddc96a2433d1d983668c484a54afefc1f18" +source = "git+https://github.com/succinctlabs/curta.git#bd14c11a17827042109dd9ba1771365070ebc98f" dependencies = [ "anyhow", "bincode", @@ -965,9 +965,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -1068,7 +1068,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1096,9 +1096,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", "digest 0.10.7", @@ -1120,15 +1120,16 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", "rand_core", "serde", "sha2", + "subtle", "zeroize", ] @@ -1140,9 +1141,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -1227,12 +1228,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.6" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.52.0", ] [[package]] @@ -1307,9 +1308,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad13497f6e0a24292fc7b408e30d22fe9dc262da1f40d7b542c3a44e7fc0476" +checksum = "1a5344eea9b20effb5efeaad29418215c4d27017639fd1f908260f59cbbd226e" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1323,9 +1324,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e9e8acd0ed348403cc73a670c24daba3226c40b98dc1a41903766b3ab6240a" +checksum = "8c405f24ea3a517899ba7985385c43dc4a7eb1209af3b1e0a1a32d7dcc7f8d09" dependencies = [ "ethers-core", "once_cell", @@ -1335,9 +1336,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79269278125006bb0552349c03593ffa9702112ca88bc7046cc669f148fb47c" +checksum = "0111ead599d17a7bff6985fd5756f39ca7033edc79a31b23026a8d5d64fa95cd" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -1354,9 +1355,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce95a43c939b2e4e2f3191c5ad4a1f279780b8a39139c9905b43a7433531e2ab" +checksum = "51258120c6b47ea9d9bec0d90f9e8af71c977fbefbef8213c91bfed385fe45eb" dependencies = [ "Inflector", "const-hex", @@ -1378,9 +1379,9 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9ce44906fc871b3ee8c69a695ca7ec7f70e50cb379c9b9cb5e532269e492f6" +checksum = "936e7a0f1197cee2b62dc89f63eff3201dbf87c283ff7e18d86d38f83b845483" dependencies = [ "Inflector", "const-hex", @@ -1394,9 +1395,9 @@ dependencies = [ [[package]] name = "ethers-core" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0a17f0708692024db9956b31d7a20163607d2745953f5ae8125ab368ba280ad" +checksum = "2f03e0bdc216eeb9e355b90cf610ef6c5bb8aca631f97b5ae9980ce34ea7878d" dependencies = [ "arrayvec", "bytes", @@ -1424,10 +1425,11 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e53451ea4a8128fbce33966da71132cf9e1040dcfd2a2084fd7733ada7b2045" +checksum = "abbac2c890bdbe0f1b8e549a53b00e2c4c1de86bb077c1094d1f38cdf9381a56" dependencies = [ + "chrono", "ethers-core", "reqwest", "semver 1.0.20", @@ -1439,9 +1441,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473f1ccd0c793871bbc248729fa8df7e6d2981d6226e4343e3bbaa9281074d5d" +checksum = "681ece6eb1d10f7cf4f873059a77c04ff1de4f35c63dd7bccde8f438374fcb93" dependencies = [ "async-trait", "auto_impl", @@ -1466,9 +1468,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6838fa110e57d572336178b7c79e94ff88ef976306852d8cb87d9e5b1fc7c0b5" +checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" dependencies = [ "async-trait", "auto_impl", @@ -1503,9 +1505,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea44bec930f12292866166f9ddbea6aa76304850e4d8dcd66dc492b43d00ff1" +checksum = "0cb1b714e227bbd2d8c53528adb580b203009728b17d0d0e4119353aa9bc5532" dependencies = [ "async-trait", "coins-bip32", @@ -1522,9 +1524,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.10" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de34e484e7ae3cab99fbfd013d6c5dc7f9013676a4e0e414d8b12e1213e8b3ba" +checksum = "a64f710586d147864cff66540a6d64518b9ff37d73ef827fee430538265b595f" dependencies = [ "cfg-if", "const-hex", @@ -1554,9 +1556,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "80f656be11ddf91bd709454d15d5bd896fbaf4cc3314e69349e4d1569f5b46cd" dependencies = [ "indenter", "once_cell", @@ -1610,9 +1612,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f69037fe1b785e84986b4f2cbcf647381876a00671d25ceef715d7812dd7e1dd" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "fixed-hash" @@ -1674,9 +1676,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1841,9 +1843,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -1876,9 +1878,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" dependencies = [ "bytes", "fnv", @@ -1886,7 +1888,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1901,9 +1903,9 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "rayon", @@ -1970,14 +1972,14 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "http" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95b9abcae896730d42b78e09c155ed4ddf82c07b4de772c64aee5b2d8b7c150" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -2095,9 +2097,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -2165,7 +2167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "serde", ] @@ -2201,7 +2203,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.3", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2239,9 +2241,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -2262,9 +2264,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" dependencies = [ "cfg-if", "ecdsa", @@ -2420,7 +2422,7 @@ checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" dependencies = [ "libc", "wasi", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2610,9 +2612,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.59" +version = "0.10.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a257ad03cd8fb16ad4172fedf8094451e1af1c4b70097636ef2eac9a5f0cc33" +checksum = "79a4c6c3a2b158f7f8f2a2fc5a969fa3a068df6fc9dbb4a43845436e3af7c800" dependencies = [ "bitflags 2.4.1", "cfg-if", @@ -2642,9 +2644,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.95" +version = "0.9.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40a4130519a360279579c2053038317e40eff64d13fd3f004f9e1b72b8a6aaf9" +checksum = "3812c071ba60da8b5677cc12bcb1d42989a65553772897a7e0355545a819838f" dependencies = [ "cc", "libc", @@ -2704,7 +2706,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -2763,9 +2765,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" @@ -2906,12 +2908,12 @@ checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" [[package]] name = "plonky2" version = "0.1.4" -source = "git+https://github.com/mir-protocol/plonky2.git#5c41dc4dacc899921951d852883bb9f2792b3c62" +source = "git+https://github.com/mir-protocol/plonky2.git#2d0df393a23c4c464d9796b8018170a47c6d61d9" dependencies = [ "ahash", "anyhow", "getrandom", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "itertools 0.11.0", "keccak-hash", "log", @@ -2930,7 +2932,7 @@ dependencies = [ [[package]] name = "plonky2_field" version = "0.1.1" -source = "git+https://github.com/mir-protocol/plonky2.git#5c41dc4dacc899921951d852883bb9f2792b3c62" +source = "git+https://github.com/mir-protocol/plonky2.git#2d0df393a23c4c464d9796b8018170a47c6d61d9" dependencies = [ "anyhow", "itertools 0.11.0", @@ -2954,7 +2956,7 @@ dependencies = [ [[package]] name = "plonky2_maybe_rayon" version = "0.1.1" -source = "git+https://github.com/mir-protocol/plonky2.git#5c41dc4dacc899921951d852883bb9f2792b3c62" +source = "git+https://github.com/mir-protocol/plonky2.git#2d0df393a23c4c464d9796b8018170a47c6d61d9" dependencies = [ "rayon", ] @@ -2962,7 +2964,7 @@ dependencies = [ [[package]] name = "plonky2_util" version = "0.1.1" -source = "git+https://github.com/mir-protocol/plonky2.git#5c41dc4dacc899921951d852883bb9f2792b3c62" +source = "git+https://github.com/mir-protocol/plonky2.git#2d0df393a23c4c464d9796b8018170a47c6d61d9" [[package]] name = "plonky2x" @@ -3002,7 +3004,7 @@ dependencies = [ "sha256", "tokio", "tracing", - "uuid 1.5.0", + "uuid 1.6.1", ] [[package]] @@ -3111,9 +3113,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -3343,16 +3345,16 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.5" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" dependencies = [ "cc", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3388,9 +3390,9 @@ dependencies = [ [[package]] name = "ruint" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "724fd11728a3804e9944b14cab63825024c40bf42f8af87c8b5d97c4bbacf426" +checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" dependencies = [ "alloy-rlp", "ark-ff 0.3.0", @@ -3448,25 +3450,25 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.1", "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", - "ring 0.17.5", + "ring 0.17.6", "rustls-webpki", "sct", ] @@ -3486,7 +3488,7 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.5", + "ring 0.17.6", "untrusted 0.9.0", ] @@ -3581,7 +3583,7 @@ version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3608,7 +3610,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.5", + "ring 0.17.6", "untrusted 0.9.0", ] @@ -3690,18 +3692,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", @@ -3834,9 +3836,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core", @@ -3901,14 +3903,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] name = "solang-parser" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb9fa2fa2fa6837be8a2495486ff92e3ffe68a99b6eeba288e139efdd842457" +checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" dependencies = [ "itertools 0.11.0", "lalrpop", @@ -3932,9 +3934,9 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -4105,7 +4107,7 @@ dependencies = [ "fastrand", "redox_syscall", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4121,9 +4123,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" +checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" dependencies = [ "winapi-util", ] @@ -4217,7 +4219,7 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.5", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4282,14 +4284,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.19.15", + "toml_edit 0.21.0", ] [[package]] @@ -4308,8 +4310,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.1.0", - "serde", - "serde_spanned", "toml_datetime", "winnow", ] @@ -4325,6 +4325,19 @@ dependencies = [ "winnow", ] +[[package]] +name = "toml_edit" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -4479,9 +4492,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -4512,9 +4525,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "serde", ] @@ -4573,9 +4586,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4583,9 +4596,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -4598,9 +4611,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -4610,9 +4623,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4620,9 +4633,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -4633,15 +4646,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "web-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -4649,9 +4662,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "winapi" @@ -4690,7 +4703,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -4699,7 +4712,16 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", ] [[package]] @@ -4708,13 +4730,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -4723,42 +4760,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.19" @@ -4775,7 +4854,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -4814,18 +4893,18 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "zerocopy" -version = "0.7.25" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.25" +version = "0.7.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" dependencies = [ "proc-macro2", "quote", @@ -4834,9 +4913,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] diff --git a/plonky2x/core/src/backend/circuit/input.rs b/plonky2x/core/src/backend/circuit/input.rs index e3f3fb7a3..b56f6956e 100644 --- a/plonky2x/core/src/backend/circuit/input.rs +++ b/plonky2x/core/src/backend/circuit/input.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use plonky2::plonk::circuit_data::VerifierCircuitData; use plonky2::plonk::proof::ProofWithPublicInputs; use serde::{Deserialize, Serialize}; @@ -15,6 +16,11 @@ pub enum PublicInput, const D: usize> { Elements(Vec), RecursiveProofs(Vec>), RemoteRecursiveProofs(Vec), + CyclicProof( + Vec, + Box>>, + #[serde(skip)] Box>>, + ), None(), } @@ -25,6 +31,9 @@ impl, const D: usize> PublicInput { CircuitIO::Bytes(_) => PublicInput::Bytes(vec![]), CircuitIO::Elements(_) => PublicInput::Elements(vec![]), CircuitIO::RecursiveProofs(_) => PublicInput::RecursiveProofs(vec![]), + CircuitIO::CyclicProof(_) => { + PublicInput::CyclicProof(vec![], Box::new(None), Box::new(None)) + } CircuitIO::None() => PublicInput::None(), } } @@ -52,6 +61,9 @@ impl, const D: usize> PublicInput { CircuitIO::RecursiveProofs(_) => { todo!() } + CircuitIO::CyclicProof(_) => { + todo!() + } CircuitIO::None() => PublicInput::None(), } } @@ -62,6 +74,9 @@ impl, const D: usize> PublicInput { PublicInput::Elements(input) => { input.extend(V::elements::(value)); } + PublicInput::CyclicProof(input, _, _) => { + input.extend(V::elements::(value)); + } _ => panic!("field io is not enabled"), }; } @@ -72,6 +87,9 @@ impl, const D: usize> PublicInput { PublicInput::Elements(input) => { input.extend(value); } + PublicInput::CyclicProof(input, _, _) => { + input.extend(value); + } _ => panic!("field io is not enabled"), }; } @@ -105,7 +123,31 @@ impl, const D: usize> PublicInput { PublicInput::RecursiveProofs(input) => { input.push(proof); } - _ => panic!("proof io is not enabled"), + PublicInput::CyclicProof(_input, ref mut io_proof, ref _data) => { + if io_proof.is_some() { + panic!("cyclic proof already has data"); + } else { + *io_proof = Box::new(Some(proof)); + } + } + _ => panic!("cyclic io is not enabled"), + }; + } + + pub fn data_write(&mut self, data: VerifierCircuitData) { + match self { + PublicInput::CyclicProof(_, _, ref mut io_data) => { + if io_data.as_ref().is_some() { + panic!("cyclic proof already has data"); + } else { + let wrapped = VerifierCircuitData { + verifier_only: data.verifier_only, + common: data.common, + }; + *io_data = Box::new(Some(wrapped)); + } + } + _ => panic!("cyclic io is not enabled"), }; } diff --git a/plonky2x/core/src/backend/circuit/output.rs b/plonky2x/core/src/backend/circuit/output.rs index 84631df59..22ec6afd7 100644 --- a/plonky2x/core/src/backend/circuit/output.rs +++ b/plonky2x/core/src/backend/circuit/output.rs @@ -42,6 +42,11 @@ impl, const D: usize> PublicOutput { assert_eq!(io.output.len(), proof_with_pis.public_inputs.len()); PublicOutput::Proofs(proof_with_pis.public_inputs.clone()) } + CircuitIO::CyclicProof(io) => { + let offset = io.input.len(); + let elements = proof_with_pis.public_inputs[offset..].to_vec(); + PublicOutput::Elements(elements) + } CircuitIO::None() => PublicOutput::None(), } } @@ -58,6 +63,7 @@ impl, const D: usize> PublicOutput { PublicOutput::Elements(output) } CircuitIO::RecursiveProofs(_) => todo!(), + CircuitIO::CyclicProof(_) => todo!(), CircuitIO::None() => PublicOutput::None(), } } diff --git a/plonky2x/core/src/backend/circuit/serialization/hints.rs b/plonky2x/core/src/backend/circuit/serialization/hints.rs index dbd27cf02..c44745b9b 100644 --- a/plonky2x/core/src/backend/circuit/serialization/hints.rs +++ b/plonky2x/core/src/backend/circuit/serialization/hints.rs @@ -34,6 +34,7 @@ use plonky2::iop::generator::{ }; use plonky2::plonk::circuit_data::CommonCircuitData; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::recursion::dummy_circuit::DummyProofGenerator; use plonky2::util::serialization::{Buffer, IoResult, Read, WitnessGeneratorSerializer, Write}; use super::registry::{SerializationRegistry, Serializer}; @@ -43,12 +44,11 @@ use crate::frontend::ecc::curve25519::curta::proof_hint::EcOpProofHint; use crate::frontend::ecc::curve25519::curta::result_hint::EcOpResultHint; use crate::frontend::eth::beacon::generators::{ BeaconAllWithdrawalsHint, BeaconBalanceBatchWitnessHint, BeaconBalanceGenerator, - BeaconBalanceWitnessHint, BeaconBalancesGenerator, BeaconBlockRootsHint, - BeaconExecutionPayloadHint, BeaconGraffitiHint, BeaconHeaderHint, - BeaconHeadersFromOffsetRangeHint, BeaconHistoricalBlockHint, BeaconPartialBalancesHint, - BeaconPartialValidatorsHint, BeaconValidatorBatchHint, BeaconValidatorGenerator, - BeaconValidatorsGenerator, BeaconValidatorsHint, BeaconWithdrawalGenerator, - BeaconWithdrawalsGenerator, CompressedBeaconValidatorBatchHint, Eth1BlockToSlotHint, + BeaconBalanceWitnessHint, BeaconBalancesGenerator, BeaconBlockRootsHint, BeaconGraffitiHint, + BeaconHeaderHint, BeaconHeadersFromOffsetRangeHint, BeaconHistoricalBlockHint, + BeaconPartialBalancesHint, BeaconPartialValidatorsHint, BeaconValidatorBatchHint, + BeaconValidatorGenerator, BeaconValidatorsGenerator, BeaconValidatorsHint, + BeaconWithdrawalGenerator, BeaconWithdrawalsGenerator, CompressedBeaconValidatorBatchHint, }; use crate::frontend::eth::beacon::vars::{ BeaconBalancesVariable, BeaconHeaderVariable, BeaconValidatorVariable, @@ -347,11 +347,9 @@ where r.register_simple::>(le_generator_id); r.register_hint::(); - r.register_hint::(); r.register_async_hint::(); r.register_async_hint::(); - r.register_async_hint::(); r.register_async_hint::(); r.register_async_hint::>(); r.register_async_hint::(); @@ -415,6 +413,10 @@ where r.register_hint::(); r.register_async_hint::>(); + let dummy_proof_generator_id = + DummyProofGenerator::::default().id(); + r.register_simple::>(dummy_proof_generator_id); + register_powers_of_two!(r, BeaconHeadersFromOffsetRangeHint); register_watch_generator!( diff --git a/plonky2x/core/src/backend/function/request.rs b/plonky2x/core/src/backend/function/request.rs index ec1cccd95..88b18562a 100644 --- a/plonky2x/core/src/backend/function/request.rs +++ b/plonky2x/core/src/backend/function/request.rs @@ -114,6 +114,7 @@ impl, const D: usize> ProofRequest { }, }) } + PublicInput::CyclicProof(_, _, _) => todo!(), PublicInput::None() => todo!(), } } diff --git a/plonky2x/core/src/backend/prover/mod.rs b/plonky2x/core/src/backend/prover/mod.rs index 21fd73aa9..21c0829de 100644 --- a/plonky2x/core/src/backend/prover/mod.rs +++ b/plonky2x/core/src/backend/prover/mod.rs @@ -29,6 +29,26 @@ pub enum ProverOutputs, const D: usize> { Remote(Vec), } +impl, const D: usize> ProverOutput { + #[allow(clippy::type_complexity)] + pub fn materialize( + self, + ) -> Result<( + ProofWithPublicInputs, + PublicOutput, + )> { + let (proof, output) = match self { + ProverOutput::Local(proof, output) => (proof, output), + ProverOutput::Remote(proof_id) => { + let service = ProofService::new_from_env(); + let response = service.get::(proof_id).unwrap(); + response.result.unwrap().as_proof_and_output() + } + }; + Ok((proof, output)) + } +} + impl, const D: usize> ProverOutputs { #[allow(clippy::type_complexity)] pub fn materialize( diff --git a/plonky2x/core/src/frontend/builder/io.rs b/plonky2x/core/src/frontend/builder/io.rs index d2bc37855..f47130f3d 100644 --- a/plonky2x/core/src/frontend/builder/io.rs +++ b/plonky2x/core/src/frontend/builder/io.rs @@ -1,14 +1,17 @@ use plonky2::iop::witness::{PartialWitness, WitnessWrite}; +use plonky2::plonk::circuit_data::{CommonCircuitData, VerifierCircuitTarget}; use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; use plonky2::plonk::proof::ProofWithPublicInputsTarget; use serde::{Deserialize, Serialize}; use super::CircuitBuilder; -use crate::backend::circuit::{CircuitBuild, PlonkParameters, PublicInput}; +use crate::backend::circuit::{PlonkParameters, PublicInput}; use crate::frontend::vars::EvmVariable; use crate::prelude::{ByteVariable, CircuitVariable, Variable}; use crate::utils::serde::{ - deserialize_proof_with_pis_target_vec, serialize_proof_with_pis_target_vec, + deserialize_proof_with_pis_target_option, deserialize_proof_with_pis_target_vec, + deserialize_verifier_circuit_target_option, serialize_proof_with_pis_target_option, + serialize_proof_with_pis_target_vec, serialize_verifier_circuit_target_option, }; /// A schema for a circuit that uses bytes for input and output. @@ -34,12 +37,29 @@ pub struct RecursiveProofsIO { pub output: Vec, } +/// A schema for a circuit that uses recursive proofs for inputs and field elements for outputs. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CyclicProofIO { + pub input: Vec, + #[serde(serialize_with = "serialize_proof_with_pis_target_option")] + #[serde(deserialize_with = "deserialize_proof_with_pis_target_option")] + pub proof: Option>, + #[serde(serialize_with = "serialize_verifier_circuit_target_option")] + #[serde(deserialize_with = "deserialize_verifier_circuit_target_option")] + pub verifier_data: Option, + pub output: Vec, + #[serde(skip)] + pub closed: bool, +} + /// A schema for what the inputs and outputs are for a circuit. #[derive(Debug, Clone, Serialize, Deserialize)] +#[allow(clippy::large_enum_variant)] pub enum CircuitIO { Bytes(BytesIO), Elements(ElementsIO), RecursiveProofs(RecursiveProofsIO), + CyclicProof(CyclicProofIO), None(), } @@ -54,6 +74,7 @@ impl CircuitIO { Self::Bytes(io) => io.input.iter().flat_map(|b| b.variables()).collect(), Self::Elements(io) => io.input.clone(), Self::RecursiveProofs(_) => todo!(), + Self::CyclicProof(_) => todo!(), Self::None() => vec![], } } @@ -63,6 +84,7 @@ impl CircuitIO { Self::Bytes(io) => io.output.iter().flat_map(|b| b.variables()).collect(), Self::Elements(io) => io.output.clone(), Self::RecursiveProofs(io) => io.output.clone(), + Self::CyclicProof(_) => todo!(), Self::None() => vec![], } } @@ -106,6 +128,22 @@ impl CircuitIO { panic!("circuit io type is recursive proofs but circuit input is not") } } + CircuitIO::CyclicProof(io) => { + let variables = &io.input; + if let PublicInput::CyclicProof(input, proof, verifier_data) = input { + for i in 0..variables.len() { + variables[i].set(pw, input[i]); + } + let proof_contents = proof.as_ref().as_ref().unwrap(); + let proof = io.proof.as_ref().unwrap(); + pw.set_proof_with_pis_target(proof, proof_contents); + let verifier_data = verifier_data.clone().unwrap(); + let verifier_data_target = io.verifier_data.as_ref().unwrap(); + pw.set_verifier_data_target(verifier_data_target, &verifier_data.verifier_only); + } else { + panic!("circuit io type is cyclic but circuit input is not") + } + } CircuitIO::None() => {} } } @@ -121,6 +159,7 @@ impl, const D: usize> CircuitBuilder { }) } CircuitIO::Elements(_) => {} + CircuitIO::CyclicProof(_) => {} _ => panic!("already set io type"), }; } @@ -147,16 +186,69 @@ impl, const D: usize> CircuitBuilder { }) } CircuitIO::RecursiveProofs(_) => {} + CircuitIO::CyclicProof(_) => {} _ => panic!("already set io type"), }; } + pub fn use_cyclic_recursion(&mut self) { + match self.io { + CircuitIO::None() => { + self.io = CircuitIO::CyclicProof(CyclicProofIO { + input: Vec::new(), + output: Vec::new(), + proof: None, + verifier_data: None, + closed: false, + }) + } + CircuitIO::CyclicProof(_) => {} + _ => panic!("other io used already"), + }; + } + + /// Closes cyclic IO. This function must be called after all IO operations and before + /// `builder.proof_read` is called, since the verifier data must be the last public input. Also, + /// closing IO lets us know the correct number of public inputs when verifying the inner proof. + pub fn close_cyclic_io(&mut self) { + let verifier_data: Option; + match self.io { + CircuitIO::CyclicProof(ref mut io) => { + if io.closed { + panic!("cyclic io already closed"); + } + io.closed = true; + let input = io + .input + .iter() + .flat_map(|b| b.variables()) + .collect::>(); + let output = io + .output + .iter() + .flat_map(|b| b.variables()) + .collect::>(); + self.register_public_inputs(input.as_slice()); + self.register_public_inputs(output.as_slice()); + verifier_data = Some(self.api.add_verifier_data_public_inputs()); + } + _ => panic!("not using cyclic io"), + } + match self.io { + CircuitIO::CyclicProof(ref mut io) => { + io.verifier_data = verifier_data; + } + _ => panic!("not using cyclic io"), + } + } + // @audit pub fn read(&mut self) -> V { self.try_init_field_io(); let variable = self.init::(); match self.io { CircuitIO::Elements(ref mut io) => io.input.extend(variable.variables()), + CircuitIO::CyclicProof(ref mut io) => io.input.extend(variable.variables()), _ => panic!("field io is not enabled"), } variable @@ -181,22 +273,39 @@ impl, const D: usize> CircuitBuilder { // @audit pub fn proof_read( &mut self, - child_circuit: &CircuitBuild, + data: &CommonCircuitData, ) -> ProofWithPublicInputsTarget { self.try_init_proof_io(); - let proof = self.add_virtual_proof_with_pis(&child_circuit.data.common); + let proof = self.add_virtual_proof_with_pis(data); match self.io { - CircuitIO::RecursiveProofs(ref mut io) => io.input.push(proof.clone()), + CircuitIO::RecursiveProofs(ref mut io) => { + io.input.push(proof.clone()); + } + CircuitIO::CyclicProof(ref mut io) => { + if io.proof.is_some() { + panic!("proof already set"); + } else { + io.proof = Some(proof.clone()); + } + } _ => panic!("proof io is not enabled"), } proof } + pub fn read_verifier_data(&mut self) -> VerifierCircuitTarget { + match self.io { + CircuitIO::CyclicProof(ref mut io) => io.verifier_data.as_ref().unwrap().clone(), + _ => panic!("cyclic proof io is not enabled"), + } + } + // @audit pub fn write(&mut self, variable: V) { self.try_init_field_io(); match self.io { CircuitIO::Elements(ref mut io) => io.output.extend(variable.variables()), + CircuitIO::CyclicProof(ref mut io) => io.output.extend(variable.variables()), _ => panic!("field io is not enabled"), } } diff --git a/plonky2x/core/src/frontend/builder/mod.rs b/plonky2x/core/src/frontend/builder/mod.rs index 6d8d6bcce..e9377db72 100644 --- a/plonky2x/core/src/frontend/builder/mod.rs +++ b/plonky2x/core/src/frontend/builder/mod.rs @@ -32,7 +32,6 @@ use crate::frontend::hint::asynchronous::generator::AsyncHintDataRef; use crate::frontend::vars::{BoolVariable, CircuitVariable, Variable}; use crate::prelude::ArrayVariable; use crate::utils::eth::beacon::BeaconClient; -use crate::utils::eth::beaconchain::BeaconchainAPIClient; /// The universal builder for building circuits using `plonky2x`. pub struct CircuitBuilder, const D: usize> { @@ -41,7 +40,6 @@ pub struct CircuitBuilder, const D: usize> { pub execution_client: Option>, pub chain_id: Option, pub beacon_client: Option, - pub beaconchain_api_client: Option, pub debug: bool, pub debug_variables: HashMap, pub(crate) hints: Vec>>, @@ -73,7 +71,6 @@ impl, const D: usize> CircuitBuilder { api, io: CircuitIO::new(), beacon_client: None, - beaconchain_api_client: None, execution_client: None, chain_id: None, debug: false, @@ -87,18 +84,11 @@ impl, const D: usize> CircuitBuilder { ec_25519_ops_accelerator: None, }; - if let Ok(rpc_url) = env::var("CONSENSUS_RPC_1") { + if let Ok(rpc_url) = env::var("CONSENSUS_RPC_URL") { let client = BeaconClient::new(rpc_url); builder.set_beacon_client(client); } - if let Ok(api_url) = env::var("BEACONCHAIN_API_URL_1") { - if let Ok(api_key) = env::var("BEACONCHAIN_API_KEY_1") { - let client = BeaconchainAPIClient::new(api_url, api_key); - builder.set_beaconchain_api_client(client); - } - } - builder } @@ -140,10 +130,6 @@ impl, const D: usize> CircuitBuilder { self.beacon_client = Some(client); } - pub fn set_beaconchain_api_client(&mut self, client: BeaconchainAPIClient) { - self.beaconchain_api_client = Some(client); - } - /// Adds all the constraints nedded before building the circuit and registering hints. fn pre_build(&mut self) { let blake2b_accelerator = self.blake2b_accelerator.clone(); @@ -220,6 +206,11 @@ impl, const D: usize> CircuitBuilder { .collect::>(); self.register_public_inputs(output.as_slice()); } + CircuitIO::CyclicProof(ref io) => { + if !io.closed { + panic!("close_cyclic_io should have been called"); + } + } CircuitIO::None() => {} }; } @@ -259,6 +250,22 @@ impl, const D: usize> CircuitBuilder { } } + /// Try to build the circuit, returning data and success. If it fails due to unexpected cyclic + /// common_data, if will still return the data and success as false. + pub fn try_build(mut self) -> (CircuitBuild, bool) { + self.pre_build(); + let (data, success) = self.api.try_build_with_options(true); + let async_hints = Self::async_hint_map(&data.prover_only.generators, self.async_hints); + ( + CircuitBuild { + data, + io: self.io, + async_hints, + }, + success, + ) + } + pub fn mock_build(mut self) -> MockCircuitBuild { self.pre_build(); let mock_data = self.api.mock_build(); diff --git a/plonky2x/core/src/frontend/eth/beacon/builder.rs b/plonky2x/core/src/frontend/eth/beacon/builder.rs index 2cb142c8b..a3292b320 100644 --- a/plonky2x/core/src/frontend/eth/beacon/builder.rs +++ b/plonky2x/core/src/frontend/eth/beacon/builder.rs @@ -3,12 +3,11 @@ use ethers::types::{H256, U256}; use super::generators::{ BeaconAllWithdrawalsHint, BeaconBalanceBatchWitnessHint, BeaconBalanceGenerator, - BeaconBalanceWitnessHint, BeaconBalancesGenerator, BeaconBlockRootsHint, - BeaconExecutionPayloadHint, BeaconGraffitiHint, BeaconHeaderHint, - BeaconHeadersFromOffsetRangeHint, BeaconHistoricalBlockHint, BeaconPartialBalancesHint, - BeaconPartialValidatorsHint, BeaconValidatorBatchHint, BeaconValidatorGenerator, - BeaconValidatorsHint, BeaconWithdrawalGenerator, BeaconWithdrawalsGenerator, - CompressedBeaconValidatorBatchHint, Eth1BlockToSlotHint, CLOSE_SLOT_BLOCK_ROOT_DEPTH, + BeaconBalanceWitnessHint, BeaconBalancesGenerator, BeaconBlockRootsHint, BeaconGraffitiHint, + BeaconHeaderHint, BeaconHeadersFromOffsetRangeHint, BeaconHistoricalBlockHint, + BeaconPartialBalancesHint, BeaconPartialValidatorsHint, BeaconValidatorBatchHint, + BeaconValidatorGenerator, BeaconValidatorsHint, BeaconWithdrawalGenerator, + BeaconWithdrawalsGenerator, CompressedBeaconValidatorBatchHint, CLOSE_SLOT_BLOCK_ROOT_DEPTH, FAR_SLOT_BLOCK_ROOT_DEPTH, FAR_SLOT_HISTORICAL_SUMMARY_DEPTH, }; use super::vars::{ @@ -19,7 +18,6 @@ use super::vars::{ use crate::backend::circuit::PlonkParameters; use crate::frontend::builder::CircuitBuilder; use crate::frontend::eth::vars::BLSPubkeyVariable; -use crate::frontend::uint::uint256::U256Variable; use crate::frontend::uint::uint64::U64Variable; use crate::frontend::vars::{ Bytes32Variable, CircuitVariable, EvmVariable, SSZVariable, VariableStream, @@ -57,9 +55,6 @@ const HISTORICAL_SUMMARY_BLOCK_ROOT_GINDEX: u64 = 16384; /// The gindex for blockRoot -> state -> state.block_roots[0]. const CLOSE_SLOT_BLOCK_ROOT_GINDEX: u64 = 2924544; -/// The gindex for blockRoot -> body -> executionPayload -> blockNumber. -const EXECUTION_PAYLOAD_BLOCK_NUMBER_GINDEX: u64 = 3222; - /// The log2 of the validator registry limit. const VALIDATOR_REGISTRY_LIMIT_LOG2: usize = 40; @@ -477,47 +472,6 @@ impl, const D: usize> CircuitBuilder { header } - /// Get beacon block hash and slot from eth1 block number, then prove from source block root. - pub fn beacon_get_block_from_eth1_block_number( - &mut self, - source_beacon_block_root: Bytes32Variable, - source_slot: U64Variable, - eth1_block_number: U256Variable, - ) -> (Bytes32Variable, U64Variable) { - // Witness the slot number from the eth1 block number - let mut block_to_slot_input = VariableStream::new(); - block_to_slot_input.write(ð1_block_number); - let block_to_slot_output = self.async_hint(block_to_slot_input, Eth1BlockToSlotHint {}); - let slot = block_to_slot_output.read::(self); - - // Prove source block root -> witnessed beacon block - let target_root = - self.beacon_get_historical_block(source_beacon_block_root, source_slot, slot); - - // Witness SSZ proof for target block root -> beacon body -> execution payload -> eth1 block number - let mut beacon_block_to_eth1_number_input = VariableStream::new(); - beacon_block_to_eth1_number_input.write(&target_root); - let beacon_block_to_eth1_number_output = self.hint( - beacon_block_to_eth1_number_input, - BeaconExecutionPayloadHint {}, - ); - let proof = - beacon_block_to_eth1_number_output.read::>(self); - - // Convert eth1 block number to leaf - let eth1_block_number_leaf = eth1_block_number.hash_tree_root(self); - - // Verify the SSZ proof - self.ssz_verify_proof_const( - target_root, - eth1_block_number_leaf, - &proof.data, - EXECUTION_PAYLOAD_BLOCK_NUMBER_GINDEX, - ); - - (target_root, slot) - } - /// Get a historical block root using state.block_roots for close slots and historical_summaries for slots > 8192 slots away. pub fn beacon_get_historical_block( &mut self, @@ -763,7 +717,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -787,7 +741,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -811,7 +765,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -840,7 +794,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -868,7 +822,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -896,7 +850,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = "0x1bfb9d3eda9f16e2f50dedf079798ce218748d48024d8150a0299688bb528735"; @@ -923,7 +877,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -947,7 +901,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -971,7 +925,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -997,7 +951,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -1021,7 +975,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -1047,7 +1001,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); let slot = client.get_finalized_slot().unwrap(); @@ -1075,7 +1029,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -1099,7 +1053,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); @@ -1123,7 +1077,7 @@ pub(crate) mod tests { env_logger::try_init().unwrap_or_default(); dotenv::dotenv().ok(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); let latest_block_root = client.get_finalized_block_root().unwrap(); diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/all_withdrawals.rs b/plonky2x/core/src/frontend/eth/beacon/generators/all_withdrawals.rs index c04a1a054..527918698 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/all_withdrawals.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/all_withdrawals.rs @@ -26,7 +26,7 @@ impl, const D: usize> AsyncHint for BeaconAllWithdra input_stream: &mut ValueStream, output_stream: &mut ValueStream, ) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let block_root = input_stream.read_value::(); let withdrawals_res = client diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/balance.rs b/plonky2x/core/src/frontend/eth/beacon/generators/balance.rs index 5cf226c15..6a83c57e0 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/balance.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/balance.rs @@ -243,7 +243,7 @@ impl, const D: usize> SimpleGenerator proof.push(Bytes32Variable::from_targets(&src.read_target_vec()?)); } let gindex = U64Variable::from_targets(&src.read_target_vec()?); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); Ok(Self { client, diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/balance_witness.rs b/plonky2x/core/src/frontend/eth/beacon/generators/balance_witness.rs index 90f6b1818..68857390a 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/balance_witness.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/balance_witness.rs @@ -14,7 +14,7 @@ pub struct BeaconBalanceWitnessHint {} impl, const D: usize> Hint for BeaconBalanceWitnessHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let validator_index = input_stream.read_value::(); @@ -33,7 +33,7 @@ impl, const D: usize, const B: usize> Hint for BeaconBalanceBatchWitnessHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let start_idx = input_stream.read_value::(); let response = client diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/balances.rs b/plonky2x/core/src/frontend/eth/beacon/generators/balances.rs index 62f80396a..631aac1fa 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/balances.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/balances.rs @@ -100,7 +100,7 @@ impl, const D: usize> SimpleGenerator for i in 0..DEPTH { proof.push(Bytes32Variable::from_targets(&src.read_target_vec()?)); } - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); Ok(Self { client, diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/block_roots.rs b/plonky2x/core/src/frontend/eth/beacon/generators/block_roots.rs index 575b2fa93..48434b981 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/block_roots.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/block_roots.rs @@ -18,7 +18,7 @@ pub struct BeaconBlockRootsHint; impl, const D: usize> Hint for BeaconBlockRootsHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let response = client.get_block_roots(hex!(header_root)).unwrap(); output_stream.write_value::(bytes32!(response.block_roots_root)); diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/eth1_block.rs b/plonky2x/core/src/frontend/eth/beacon/generators/eth1_block.rs deleted file mode 100644 index 0c3fe7e60..000000000 --- a/plonky2x/core/src/frontend/eth/beacon/generators/eth1_block.rs +++ /dev/null @@ -1,65 +0,0 @@ -use std::env; - -use async_trait::async_trait; -use ethers::types::H256; -use serde::{Deserialize, Serialize}; - -use crate::frontend::hint::asynchronous::hint::AsyncHint; -use crate::frontend::hint::simple::hint::Hint; -use crate::frontend::uint::uint64::U64Variable; -use crate::frontend::vars::{U256Variable, ValueStream}; -use crate::prelude::{ArrayVariable, Bytes32Variable, PlonkParameters}; -use crate::utils::eth::beacon::BeaconClient; -use crate::utils::eth::beaconchain::BeaconchainAPIClient; -use crate::utils::{bytes32, hex}; - -/// Input: (eth1_block_number: u256) -/// Output: (slot: u64) -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Eth1BlockToSlotHint {} - -#[async_trait] -impl, const D: usize> AsyncHint for Eth1BlockToSlotHint { - async fn hint( - &self, - input_stream: &mut ValueStream, - output_stream: &mut ValueStream, - ) { - let client = BeaconchainAPIClient::new( - env::var("BEACONCHAIN_API_URL_1").unwrap(), - env::var("BEACONCHAIN_API_KEY_1").unwrap(), - ); - let eth1_block = input_stream.read_value::(); - - // Convert block numbers to slots - let execution_blocks = client.get_execution_blocks(&[eth1_block]).await.unwrap(); - let slot = execution_blocks[0].pos_consensus.slot; - output_stream.write_value::(slot); - } -} - -const DEPTH: usize = 11; - -/// Input: (block_root: bytes32) -/// Output: (proof: ArrayVariable, eth1_block_number: u256) -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BeaconExecutionPayloadHint {} - -impl, const D: usize> Hint for BeaconExecutionPayloadHint { - fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); - - let block_root = input_stream.read_value::(); - let execution_payload: crate::utils::eth::beacon::GetBeaconExecutionPayload = client - .get_execution_payload(hex!(block_root.to_fixed_bytes())) - .unwrap(); - - let proof = execution_payload - .proof - .iter() - .map(|h| bytes32!(h)) - .collect::>(); - - output_stream.write_value::>(proof); - } -} diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/graffiti.rs b/plonky2x/core/src/frontend/eth/beacon/generators/graffiti.rs index d34a5987a..05fa06c86 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/graffiti.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/graffiti.rs @@ -19,7 +19,7 @@ pub struct BeaconGraffitiHint; #[async_trait] impl, const D: usize> Hint for BeaconGraffitiHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let response = client.get_graffiti(hex!(header_root)).unwrap(); output_stream.write_value::(bytes32!(response.graffiti)); diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/header.rs b/plonky2x/core/src/frontend/eth/beacon/generators/header.rs index 4eb11ac5f..22b17fd58 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/header.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/header.rs @@ -23,7 +23,7 @@ impl, const D: usize> AsyncHint for BeaconHeaderHint input_stream: &mut ValueStream, output_stream: &mut ValueStream, ) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let block_root = input_stream.read_value::(); let header = client diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/headers.rs b/plonky2x/core/src/frontend/eth/beacon/generators/headers.rs index 4443dd142..1f57f19ea 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/headers.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/headers.rs @@ -18,7 +18,7 @@ impl, const D: usize, const B: usize> Hint for BeaconHeadersFromOffsetRangeHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let start_offset = input_stream.read_value::(); let end_offset = input_stream.read_value::() + 1; diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/historical.rs b/plonky2x/core/src/frontend/eth/beacon/generators/historical.rs index a97d54232..14dc07192 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/historical.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/historical.rs @@ -28,7 +28,7 @@ impl, const D: usize> AsyncHint for BeaconHistorical let block_root = input_stream.read_value::(); let target_slot = input_stream.read_value::(); - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let result = client .get_historical_block(hex!(block_root.as_bytes()).to_string(), target_slot) .await diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/mod.rs b/plonky2x/core/src/frontend/eth/beacon/generators/mod.rs index 827c2d0b3..d2c94a17f 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/mod.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/mod.rs @@ -3,7 +3,6 @@ mod balance; mod balance_witness; mod balances; mod block_roots; -mod eth1_block; mod graffiti; mod header; mod headers; @@ -20,7 +19,6 @@ pub use balance::BeaconBalanceGenerator; pub use balance_witness::{BeaconBalanceBatchWitnessHint, BeaconBalanceWitnessHint}; pub use balances::BeaconBalancesGenerator; pub use block_roots::BeaconBlockRootsHint; -pub use eth1_block::{BeaconExecutionPayloadHint, Eth1BlockToSlotHint}; pub use graffiti::BeaconGraffitiHint; pub use header::BeaconHeaderHint; pub use headers::BeaconHeadersFromOffsetRangeHint; diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/partial_balances.rs b/plonky2x/core/src/frontend/eth/beacon/generators/partial_balances.rs index b57b5a2d5..f846daa88 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/partial_balances.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/partial_balances.rs @@ -18,7 +18,7 @@ impl, const D: usize, const B: usize> Hint for BeaconPartialBalancesHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let response = client .get_partial_balances_root(hex!(header_root), B) diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/partial_validators.rs b/plonky2x/core/src/frontend/eth/beacon/generators/partial_validators.rs index c20a12209..8bb9d4e04 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/partial_validators.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/partial_validators.rs @@ -18,7 +18,7 @@ impl, const D: usize, const B: usize> Hint for BeaconPartialValidatorsHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let response = client .get_partial_validators_root(hex!(header_root), B) diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/validator.rs b/plonky2x/core/src/frontend/eth/beacon/generators/validator.rs index f1436b9c1..a5e119324 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/validator.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/validator.rs @@ -204,7 +204,7 @@ impl, const D: usize> SimpleGenerator let proof = (0..DEPTH) .map(|_| Bytes32Variable::from_targets(&src.read_target_vec().unwrap())) .collect::>(); - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); Ok(Self { client, diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/validator_witness.rs b/plonky2x/core/src/frontend/eth/beacon/generators/validator_witness.rs index 0db73dbb8..0df35d238 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/validator_witness.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/validator_witness.rs @@ -18,7 +18,7 @@ pub struct BeaconValidatorHint {} impl, const D: usize> Hint for BeaconValidatorHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let validator_index = input_stream.read_value::(); @@ -37,7 +37,7 @@ impl, const D: usize, const B: usize> Hint for BeaconValidatorBatchHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let start_idx = input_stream.read_value::(); let response = client @@ -55,7 +55,7 @@ impl, const D: usize, const B: usize> Hint for CompressedBeaconValidatorBatchHint { fn hint(&self, input_stream: &mut ValueStream, output_stream: &mut ValueStream) { - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header_root = input_stream.read_value::(); let start_idx = input_stream.read_value::(); let response = client diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/validators.rs b/plonky2x/core/src/frontend/eth/beacon/generators/validators.rs index cfd430797..e502ea5c9 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/validators.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/validators.rs @@ -42,7 +42,7 @@ impl, const D: usize> AsyncHint for BeaconValidators ) { let block_root = input_stream.read_value::(); - let result = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()) + let result = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()) .get_validators_root(hex!(block_root.as_bytes()).to_string()) .expect("failed to get validators root"); @@ -99,7 +99,7 @@ impl, const D: usize> SimpleGenerator ) { let block_root = self.block_root.get(witness); - let result = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()) + let result = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()) .get_validators_root(hex!(block_root.as_bytes()).to_string()) .expect("failed to get validators root"); diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/withdrawal.rs b/plonky2x/core/src/frontend/eth/beacon/generators/withdrawal.rs index 8d80b1f54..9d8827584 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/withdrawal.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/withdrawal.rs @@ -3,7 +3,6 @@ use std::env; use array_macro::array; use ethers::types::{Address, U256}; -use log::info; use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; use plonky2::iop::target::Target; use plonky2::iop::witness::PartitionWitness; @@ -81,9 +80,8 @@ impl, const D: usize> SimpleGenerator let result = self .client .get_withdrawal(hex!(block_root.as_bytes()).to_string(), idx) - .expect("failed to get validators root"); + .expect("failed to get withdrawal"); - info!("{}", result.withdrawal.amount); let withdrawal = BeaconWithdrawalValue { index: result.withdrawal.index, validator_index: result.withdrawal.validator_index, @@ -128,7 +126,7 @@ impl, const D: usize> SimpleGenerator for i in 0..DEPTH { proof.push(Bytes32Variable::from_targets(&src.read_target_vec()?)); } - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); Ok(Self { client, diff --git a/plonky2x/core/src/frontend/eth/beacon/generators/withdrawals.rs b/plonky2x/core/src/frontend/eth/beacon/generators/withdrawals.rs index cb70f7fe9..d918af3c3 100644 --- a/plonky2x/core/src/frontend/eth/beacon/generators/withdrawals.rs +++ b/plonky2x/core/src/frontend/eth/beacon/generators/withdrawals.rs @@ -101,7 +101,7 @@ impl, const D: usize> SimpleGenerator for i in 0..DEPTH { proof.push(Bytes32Variable::from_targets(&src.read_target_vec()?)); } - let consensus_rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let consensus_rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(consensus_rpc); Ok(Self { client, diff --git a/plonky2x/core/src/frontend/eth/beacon/vars/header.rs b/plonky2x/core/src/frontend/eth/beacon/vars/header.rs index 89f9bbb9e..e4588dcb2 100644 --- a/plonky2x/core/src/frontend/eth/beacon/vars/header.rs +++ b/plonky2x/core/src/frontend/eth/beacon/vars/header.rs @@ -94,7 +94,7 @@ mod test { env::set_var("RUST_LOG", "debug"); env_logger::init(); let mut builder = CircuitBuilder::::new(); - let client = BeaconClient::new(env::var("CONSENSUS_RPC_1").unwrap()); + let client = BeaconClient::new(env::var("CONSENSUS_RPC_URL").unwrap()); let header = client.get_header("7404237".to_string()).await.unwrap(); let beacon_header = BeaconHeaderValue::<>::Field> { slot: U64::from_dec_str(header.slot.as_str()).unwrap().as_u64(), diff --git a/plonky2x/core/src/frontend/fold/generator.rs b/plonky2x/core/src/frontend/fold/generator.rs new file mode 100644 index 000000000..8c720b54c --- /dev/null +++ b/plonky2x/core/src/frontend/fold/generator.rs @@ -0,0 +1,248 @@ +use std::marker::PhantomData; + +use log::debug; +use plonky2::iop::generator::{GeneratedValues, SimpleGenerator}; +use plonky2::iop::target::Target; +use plonky2::iop::witness::PartitionWitness; +use plonky2::plonk::circuit_data::CommonCircuitData; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; +use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; +use plonky2::recursion::dummy_circuit::cyclic_base_proof; +use plonky2::util::serialization::{Buffer, IoResult, Read, Write}; +use serde::{Deserialize, Serialize}; + +use super::FoldDefinition; +use crate::backend::circuit::{CircuitBuild, CircuitSerializer, DefaultSerializer, PublicOutput}; +use crate::prelude::{CircuitVariable, PlonkParameters, U32Variable, WitnessWrite}; +use crate::utils::serde::{deserialize_proof_with_pis_target, serialize_proof_with_pis_target}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct FoldGenerator +where + Definition: + FoldDefinition + std::fmt::Debug + Send + Sync + 'static, + L: PlonkParameters, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, +{ + pub circuit_id: String, + pub ctx: Ctx, + pub initial: Accumulator, + #[serde(serialize_with = "serialize_proof_with_pis_target")] + #[serde(deserialize_with = "deserialize_proof_with_pis_target")] + pub proof: ProofWithPublicInputsTarget, + pub _phantom: PhantomData<(L, Element, Definition, Accumulator, Serializer)>, +} + +impl Clone + for FoldGenerator +where + Definition: + FoldDefinition + std::fmt::Debug + Send + Sync + 'static, + L: PlonkParameters, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, +{ + fn clone(&self) -> Self { + Self { + circuit_id: self.circuit_id.clone(), + ctx: self.ctx.clone(), + initial: self.initial.clone(), + proof: self.proof.clone(), + _phantom: PhantomData::<(L, Element, Definition, Accumulator, Serializer)>, + } + } +} + +impl + FoldGenerator +where + Definition: + FoldDefinition + std::fmt::Debug + Send + Sync + 'static, + L: PlonkParameters, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, +{ + pub fn id() -> String { + "FoldGenerator".to_string() + } +} + +/// Prove one loop of the fold. +#[allow(clippy::type_complexity)] +fn prove_cycle( + circuit: &CircuitBuild, + ctx: Ctx::ValueType, + acc: Accumulator::ValueType, + initial: Accumulator::ValueType, + element: Element::ValueType, + index: u32, + prev_result: &mut Option<( + ProofWithPublicInputs, + PublicOutput, + )>, +) -> ( + ProofWithPublicInputs, + PublicOutput, +) +where + L: PlonkParameters, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + <>::Config as GenericConfig>::Hasher: AlgebraicHasher, +{ + let mut input = circuit.input(); + input.write::(ctx); + input.write::(element); + input.write::(acc); + input.write::(initial); + input.write::(index); + input.data_write(circuit.data.verifier_data()); + // If there's a previous result, use the proof from it, otherwise use a dummy proof. + let proof = if let Some((proof, _)) = prev_result.take() { + proof + } else { + cyclic_base_proof( + &circuit.data.common, + &circuit.data.verifier_only, + vec![].into_iter().enumerate().collect(), + ) + }; + input.proof_write(proof); + circuit.prove(&input) +} + +impl + SimpleGenerator + for FoldGenerator +where + Definition: + FoldDefinition + std::fmt::Debug + Send + Sync + 'static, + L: PlonkParameters, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, +{ + fn id(&self) -> String { + Self::id() + } + + fn dependencies(&self) -> Vec { + let mut targets = Vec::new(); + targets.extend(self.ctx.targets()); + targets.extend(self.initial.targets()); + targets + } + + #[allow(clippy::type_complexity)] + fn run_once( + &self, + witness: &PartitionWitness, + out_buffer: &mut GeneratedValues, + ) { + let gate_serializer = DefaultSerializer::gate_registry::(); + let generator_serializer = DefaultSerializer::generator_registry::(); + let circuit_path = format!("./build/{}.circuit", self.circuit_id); + let circuit = + CircuitBuild::::load(&circuit_path, &gate_serializer, &generator_serializer) + .unwrap(); + + let ctx_value = self.ctx.get(witness); + let initial_value = self.initial.get(witness); + + let iterator = Definition::init(ctx_value.clone()); + + let mut last_result: Option<( + ProofWithPublicInputs< + >::Field, + >::Config, + D, + >, + PublicOutput, + )> = None; + let mut i = 0_u32; + loop { + // If first iteration, use initial value, otherwise use previous accumulator. + let prev_acc = if let Some((_, ref mut output)) = last_result { + output.read::() + } else { + initial_value.clone() + }; + + // Call user definition to get next element. + let element = iterator.next(i, prev_acc.clone()); + if element.is_none() { + break; + } + + // Generate proof. + debug!("proving element {}", i); + last_result = Some(prove_cycle::( + &circuit, + ctx_value.clone(), + prev_acc, + initial_value.clone(), + element.unwrap(), + i, + &mut last_result, + )); + i += 1; + } + + out_buffer.set_proof_with_pis_target(&self.proof, &last_result.unwrap().0); + } + + fn serialize(&self, dst: &mut Vec, _: &CommonCircuitData) -> IoResult<()> { + // Write map circuit. + dst.write_usize(self.circuit_id.len())?; + dst.write_all(self.circuit_id.as_bytes())?; + + // Write context. + dst.write_target_vec(&self.ctx.targets())?; + + dst.write_target_vec(&self.initial.targets())?; + + // Write proof target. + dst.write_target_proof_with_public_inputs(&self.proof) + } + + fn deserialize(src: &mut Buffer, _: &CommonCircuitData) -> IoResult { + // Read map circuit. + let circuit_id_length = src.read_usize()?; + let mut circuit_id = vec![0u8; circuit_id_length]; + src.read_exact(&mut circuit_id)?; + + // Read context. + let ctx = Ctx::from_targets(&src.read_target_vec()?); + + let initial = Accumulator::from_targets(&src.read_target_vec()?); + + // Read proof. + let proof: ProofWithPublicInputsTarget = src.read_target_proof_with_public_inputs()?; + + // todo!() + Ok(Self { + circuit_id: String::from_utf8(circuit_id).unwrap(), + ctx, + initial, + proof, + _phantom: PhantomData::<(L, Element, Definition, Accumulator, Serializer)>, + }) + } +} diff --git a/plonky2x/core/src/frontend/fold/mod.rs b/plonky2x/core/src/frontend/fold/mod.rs new file mode 100644 index 000000000..24320b576 --- /dev/null +++ b/plonky2x/core/src/frontend/fold/mod.rs @@ -0,0 +1,344 @@ +use core::panic; +use std::marker::PhantomData; + +use log::debug; +use plonky2::iop::target::BoolTarget; +use plonky2::plonk::circuit_data::CommonCircuitData; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; + +use crate::backend::circuit::{CircuitBuild, CircuitSerializer}; +use crate::frontend::fold::generator::FoldGenerator; +use crate::frontend::fold::util::common_data_for_recursion; +use crate::prelude::{CircuitBuilder, CircuitVariable, PlonkParameters, U32Variable}; + +pub mod generator; +mod util; + +pub trait FoldBuilderMethods, const D: usize> { + fn fold( + &mut self, + ctx: Ctx, + initial: Accumulator, + ) -> (U32Variable, Accumulator) + where + Definition: FoldDefinition + + std::fmt::Debug + + Send + + Sync + + 'static, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, + ::ValueType<>::Field>: Sync + Send, + ::ValueType<>::Field>: Sync + Send; +} + +impl, const D: usize> FoldBuilderMethods for CircuitBuilder { + fn fold( + &mut self, + ctx: Ctx, + initial: Accumulator, + ) -> (U32Variable, Accumulator) + where + Definition: FoldDefinition + + std::fmt::Debug + + Send + + Sync + + 'static, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, + ::ValueType<>::Field>: Sync + Send, + ::ValueType<>::Field>: Sync + Send, + { + // Build and save inner circuit. + let inner_circuit = + build_inner::(None); + debug!("succesfully built circuit: id={}", inner_circuit.id()); + + let gate_serializer = Serializer::gate_registry::(); + let generator_serializer = Serializer::generator_registry::(); + + // Save cyclic inner circuit to build folder. + let circuit_id = inner_circuit.id(); + let circuit_path = format!("./build/{}.circuit", circuit_id); + inner_circuit.save(&circuit_path, &gate_serializer, &generator_serializer); + + // Generate cyclic proofs using generator. + let final_proof = self.add_virtual_proof_with_pis(&inner_circuit.data.common); + let generator = FoldGenerator { + circuit_id, + ctx: ctx.clone(), + initial: initial.clone(), + proof: final_proof.clone(), + _phantom: PhantomData::<(L, Element, Definition, Accumulator, Serializer)>, + }; + self.add_simple_generator(generator); + + // Read final proof from generator and verify. + let final_verifier_data = self.constant_verifier_data::(&inner_circuit.data); + self.verify_proof::( + &final_proof, + &final_verifier_data, + &inner_circuit.data.common, + ); + + // Verify the inner proof ctx and initial acc are correct. + let proof_pis = &final_proof.public_inputs; + debug!("pis: {:?}", proof_pis.len()); + let mut ptr = 0; + let ctx_elements = Ctx::nb_elements(); + let inner_ctx = Ctx::from_targets(&proof_pis[ptr..ptr + ctx_elements]); + ptr += ctx_elements; + let element_elements = Element::nb_elements(); + ptr += element_elements; + let accumulator_elements = Accumulator::nb_elements(); + ptr += accumulator_elements; + let inner_initial = Accumulator::from_targets(&proof_pis[ptr..ptr + accumulator_elements]); + ptr += accumulator_elements; + let u32_elements = U32Variable::nb_elements(); + let inner_index = U32Variable::from_targets(&proof_pis[ptr..ptr + u32_elements]); + ptr += u32_elements; + let inner_output = Accumulator::from_targets(&proof_pis[ptr..ptr + accumulator_elements]); + + self.assert_is_equal(inner_ctx, ctx); + self.assert_is_equal(inner_initial, initial); + + // Return output acc which is after all inputs + (inner_index, inner_output) + } +} + +/// Builds the inner circuit for the fold. The circuit takes in context, element, previous acc, +/// initial acc, and index, and outputs the next accumulator. +fn build_inner( + input_data: Option>, +) -> CircuitBuild +where + Definition: + FoldDefinition + std::fmt::Debug + Send + Sync + 'static, + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + Serializer: CircuitSerializer, + L: PlonkParameters, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, + ::ValueType<>::Field>: Sync + Send, + ::ValueType<>::Field>: Sync + Send, +{ + let mut builder = CircuitBuilder::::new(); + // Explicitly enable cyclic IO. + builder.use_cyclic_recursion(); + + let ctx = builder.read::(); + let element = builder.read::(); + let prev = builder.read::(); + let initial = builder.read::(); + let index = builder.read::(); + + let zero_u32 = builder.constant(0u32); + let true_bool = builder._true(); + + // If index = 0, the inner proof will be dummy, and we should use the initial accumulator. + let should_dummy = builder.is_equal(index, zero_u32); + let prev_or_initial = builder.select(should_dummy, initial.clone(), prev.clone()); + + // Call user defined fold step. + let next_acc = + Definition::fold_step(&ctx, element.clone(), prev_or_initial, index, &mut builder); + builder.write(next_acc); + + // Close cyclic IO so we can use builder.proof_read and get # of public inputs. + builder.close_cyclic_io(); + + // Use dummy data for the first time, then once we know the expected real data, use that. + let mut common_data = if input_data.is_none() { + common_data_for_recursion::() + } else { + input_data.clone().unwrap() + }; + // Set the number of public inputs + common_data.num_public_inputs = builder.api.num_public_inputs(); + // Read inner proof and decode its public inputs that we want to verify. + let inner_cyclic_proof_with_pis = builder.proof_read(&common_data); + let inner_cyclic_pis = &inner_cyclic_proof_with_pis.public_inputs; + let mut ptr = 0; + let ctx_elements = Ctx::nb_elements(); + let inner_ctx = Ctx::from_targets(&inner_cyclic_pis[ptr..ptr + ctx_elements]); + ptr += ctx_elements; + let element_elements = Element::nb_elements(); + ptr += element_elements; + let accumulator_elements = Accumulator::nb_elements(); + ptr += accumulator_elements; + let inner_initial = + Accumulator::from_targets(&inner_cyclic_pis[ptr..ptr + accumulator_elements]); + ptr += accumulator_elements; + let u32_elements = U32Variable::nb_elements(); + let inner_index = U32Variable::from_targets(&inner_cyclic_pis[ptr..ptr + u32_elements]); + ptr += u32_elements; + let inner_output = + Accumulator::from_targets(&inner_cyclic_pis[ptr..ptr + accumulator_elements]); + + // Ensure ctx is equal. + let ctx_equal = builder.is_equal(inner_ctx, ctx); + // Ensure initial acc is equal. + let initial_equal = builder.is_equal(inner_initial, initial); + // Ensure prev acc = inner proof output. + let correct_prev = builder.is_equal(inner_output, prev); + // Ensure index = inner_index + 1. + let one_u32 = builder.constant(1_u32); + let inner_index_plus_one = builder.add(inner_index, one_u32); + let correct_index = builder.is_equal(inner_index_plus_one, index); + + // AND together above conditions. + let mut inner_valid = builder.and(ctx_equal, initial_equal); + inner_valid = builder.and(inner_valid, correct_prev); + inner_valid = builder.and(inner_valid, correct_index); + + // Only verify inner validity if this is not the 0th proof. + let inner_valid_or_dummy = builder.or(inner_valid, should_dummy); + builder.assert_is_equal(inner_valid_or_dummy, true_bool); + + // Verify inner proof or dummy if index = 0. + let not_dummy = builder.not(should_dummy); + let should_verify_target = BoolTarget::new_unsafe(not_dummy.variable.0); + let result = builder + .api + .conditionally_verify_cyclic_proof_or_dummy::( + should_verify_target, + &inner_cyclic_proof_with_pis, + &common_data, + ); + if result.is_err() { + debug!("error: {:?}", result.err()); + panic!("failed to verify cyclic proof"); + } + + let (build, success) = builder.try_build(); + + if !success && input_data.is_none() { + build_inner::(Some(build.data.common)) + } else { + build + } +} + +pub trait FoldDefinition +where + Ctx: CircuitVariable, + Element: CircuitVariable, + Accumulator: CircuitVariable, + L: PlonkParameters, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, +{ + fn init(ctx: Ctx::ValueType) -> Self; + + fn next( + &self, + index: u32, + current_acc: Accumulator::ValueType, + ) -> Option>; + + fn fold_step( + ctx: &Ctx, + element: Element, + acc: Accumulator, + index: U32Variable, + builder: &mut CircuitBuilder, + ) -> Accumulator; +} + +#[cfg(test)] +mod tests { + + use log::info; + use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; + + use super::FoldDefinition; + use crate::backend::circuit::DefaultSerializer; + use crate::frontend::fold::FoldBuilderMethods; + use crate::prelude::{CircuitBuilder, DefaultParameters, PlonkParameters, U32Variable}; + + type L = DefaultParameters; + const D: usize = 2; + + #[derive(Debug, Clone)] + struct TestFoldDefinition(u32); + + impl + FoldDefinition + for TestFoldDefinition + where + L: PlonkParameters, + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher<>::Field>, + { + fn init(ctx: u32) -> Self { + Self(ctx) + } + + fn next(&self, index: u32, _: (u32, u32)) -> Option { + if index < self.0 { + Some((index + 1).pow(2)) + } else { + None + } + } + + fn fold_step( + _: &U32Variable, + element: U32Variable, + acc: (U32Variable, U32Variable), + index: U32Variable, + builder: &mut CircuitBuilder, + ) -> (U32Variable, U32Variable) { + let (_, prev_sum) = acc; + let new_sum = builder.add(prev_sum, element); + let one_u32 = builder.constant(1u32); + let index_plus_one = builder.add(index, one_u32); + let expected_element = builder.mul(index_plus_one, index_plus_one); + let is_expected = builder.is_equal(expected_element, element); + let true_bool = builder._true(); + builder.assert_is_equal(is_expected, true_bool); + (index_plus_one, new_sum) + } + } + + #[test] + fn test_recursion() { + let mut builder = CircuitBuilder::::new(); + let num = builder.evm_read::(); + let zero_u32 = builder.constant::(0u32); + let (last_index, result) = builder + .fold::(num, (zero_u32, zero_u32)); + builder.evm_write(result.0); + builder.evm_write(result.1); + builder.evm_write(last_index); + let circuit = builder.build(); + + let mut input = circuit.input(); + input.evm_write::(4); + let (proof, output) = circuit.prove(&input); + circuit.verify(&proof, &input, &output); + + let mut result = output.clone(); + let last_element = result.evm_read::(); + let sum = result.evm_read::(); + let last_index = result.evm_read::(); + info!("last_element: {}", last_element); + info!("sum: {}", sum); + info!("last_index: {}", last_index); + + assert_eq!(last_element, 4); + assert_eq!(sum, 30); + assert_eq!(last_index, 3); + } +} diff --git a/plonky2x/core/src/frontend/fold/util.rs b/plonky2x/core/src/frontend/fold/util.rs new file mode 100644 index 000000000..afa339cb2 --- /dev/null +++ b/plonky2x/core/src/frontend/fold/util.rs @@ -0,0 +1,33 @@ +use plonky2::gates::noop::NoopGate; +use plonky2::plonk::circuit_data::CommonCircuitData; +use plonky2::plonk::config::{AlgebraicHasher, GenericConfig}; + +use crate::prelude::{CircuitBuilder, PlonkParameters}; + +pub fn common_data_for_recursion, const D: usize>( +) -> CommonCircuitData +where + <>::Config as GenericConfig>::Hasher: + AlgebraicHasher, +{ + let builder = CircuitBuilder::::new(); + let data = builder.build(); + let mut builder = CircuitBuilder::::new(); + let proof = builder.add_virtual_proof_with_pis(&data.data.common); + let verifier_data = builder + .api + .add_virtual_verifier_data(data.data.common.config.fri_config.cap_height); + builder.verify_proof::(&proof, &verifier_data, &data.data.common); + let data = builder.build(); + + let mut builder = CircuitBuilder::::new(); + let proof = builder.add_virtual_proof_with_pis(&data.data.common); + let verifier_data = builder + .api + .add_virtual_verifier_data(data.data.common.config.fri_config.cap_height); + builder.verify_proof::(&proof, &verifier_data, &data.data.common); + while builder.api.num_gates() < 1 << 12 { + builder.api.add_gate(NoopGate, vec![]); + } + builder.build().data.common +} diff --git a/plonky2x/core/src/frontend/mapreduce/mod.rs b/plonky2x/core/src/frontend/mapreduce/mod.rs index 049e49684..6c58374ba 100644 --- a/plonky2x/core/src/frontend/mapreduce/mod.rs +++ b/plonky2x/core/src/frontend/mapreduce/mod.rs @@ -123,9 +123,9 @@ impl, const D: usize> CircuitBuilder { // Read and verify the child proofs. let verifier_data = builder.constant_verifier_data::(&child_circuit.data); - let proof_left = builder.proof_read(child_circuit); + let proof_left = builder.proof_read(&child_circuit.data.common); builder.verify_proof::(&proof_left, &verifier_data, &child_circuit.data.common); - let proof_right = builder.proof_read(child_circuit); + let proof_right = builder.proof_read(&child_circuit.data.common); builder.verify_proof::(&proof_right, &verifier_data, &child_circuit.data.common); // Assert that the contexts match. diff --git a/plonky2x/core/src/frontend/mod.rs b/plonky2x/core/src/frontend/mod.rs index 1bda56d37..a0423b777 100644 --- a/plonky2x/core/src/frontend/mod.rs +++ b/plonky2x/core/src/frontend/mod.rs @@ -3,6 +3,7 @@ pub mod curta; pub mod ecc; pub mod eth; pub mod extension; +pub mod fold; pub mod hash; pub mod hint; pub mod mapreduce; diff --git a/plonky2x/core/src/utils/eth/beacon/mod.rs b/plonky2x/core/src/utils/eth/beacon/mod.rs index ad2b2ff67..528254053 100644 --- a/plonky2x/core/src/utils/eth/beacon/mod.rs +++ b/plonky2x/core/src/utils/eth/beacon/mod.rs @@ -400,10 +400,15 @@ impl BeaconClient { /// `stateRoot -> validatorsRoot`. pub fn get_validators_root(&self, beacon_id: String) -> Result { let endpoint = format!("{}/api/beacon/proof/validator/{}", self.rpc_url, beacon_id); + debug!("{}", endpoint); let client = Client::new(); - let response = client.get(endpoint).timeout(Duration::new(120, 0)).send()?; + let response = client + .get(&endpoint) + .timeout(Duration::new(120, 0)) + .send()?; let response: CustomResponse = response.json()?; assert!(response.success); + debug!("done {}", endpoint); Ok(response.result) } @@ -418,6 +423,7 @@ impl BeaconClient { "{}/api/beacon/validator/{}/{}", self.rpc_url, beacon_id, validator_idx ); + debug!("{}", endpoint); let response = self.client.fetch(&endpoint)?; let response: CustomResponse = response.json()?; assert!(response.success); @@ -451,9 +457,11 @@ impl BeaconClient { "{}/api/beacon/proof/validator/{}/{}", self.rpc_url, beacon_id, validator_idx ); + debug!("{}", endpoint); let response = self.client.fetch(&endpoint)?; let response: CustomResponse = response.json()?; assert!(response.success); + debug!("done {}", endpoint); Ok(response.result) } @@ -610,6 +618,7 @@ impl BeaconClient { let response = self.client.fetch(&endpoint)?; let response: CustomResponse = response.json()?; assert!(response.success); + debug!("done {}", endpoint); Ok(response.result) } @@ -627,9 +636,11 @@ impl BeaconClient { "{}/api/beacon/proof/withdrawal/{}/{}", self.rpc_url, beacon_id, idx ); + info!("{}", endpoint); let response = self.client.fetch(&endpoint)?; let response: CustomResponse = response.json()?; assert!(response.success); + debug!("done {}", endpoint); Ok(response.result) } @@ -753,7 +764,7 @@ mod tests { fn test_get_validators_root_by_slot() -> Result<()> { utils::setup_logger(); dotenv::dotenv()?; - let rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(rpc.to_string()); let slot = 7052735; let result = client.get_validators_root(slot.to_string())?; @@ -766,7 +777,7 @@ mod tests { fn test_get_validators_root_by_block_root() -> Result<()> { utils::setup_logger(); dotenv::dotenv()?; - let rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(rpc.to_string()); let block_root = "0x6b6964f45d0aeff741260ec4faaf76bb79a009fc18ae17979784d92aec374946"; let result = client.get_validators_root(block_root.to_string())?; @@ -779,7 +790,7 @@ mod tests { fn test_get_validator_by_slot() -> Result<()> { utils::setup_logger(); dotenv::dotenv()?; - let rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(rpc.to_string()); let slot = 7052735; let result = client.get_validator(slot.to_string(), 0)?; @@ -792,7 +803,7 @@ mod tests { fn test_get_validator_by_block_root() -> Result<()> { utils::setup_logger(); dotenv::dotenv()?; - let rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(rpc.to_string()); let block_root = "0x6b6964f45d0aeff741260ec4faaf76bb79a009fc18ae17979784d92aec374946"; let result = client.get_validator(block_root.to_string(), 0)?; @@ -804,7 +815,7 @@ mod tests { #[test] fn test_get_block_roots() -> Result<()> { utils::setup_logger(); - let rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(rpc.to_string()); let slot = 7052735; let result = client.get_block_roots(slot.to_string())?; @@ -816,7 +827,7 @@ mod tests { #[test] fn test_get_headers_from_offset_range() -> Result<()> { utils::setup_logger(); - let rpc = env::var("CONSENSUS_RPC_1").unwrap(); + let rpc = env::var("CONSENSUS_RPC_URL").unwrap(); let client = BeaconClient::new(rpc.to_string()); let slot = 7052735; let result = client.get_headers_from_offset_range(slot.to_string(), 0, 16)?; diff --git a/plonky2x/core/src/utils/eth/beaconchain/mod.rs b/plonky2x/core/src/utils/eth/beaconchain/mod.rs deleted file mode 100644 index ecd7a269e..000000000 --- a/plonky2x/core/src/utils/eth/beaconchain/mod.rs +++ /dev/null @@ -1,93 +0,0 @@ -use anyhow::Result; -use ethers::types::U256; -use log::debug; -use reqwest::header::{HeaderMap, HeaderValue}; -use serde::Deserialize; - -use crate::utils::reqwest::ReqwestClient; - -/// A client used for connecting and querying the beaconcha.in API. -#[derive(Debug, Clone)] -pub struct BeaconchainAPIClient { - pub api_url: String, - pub client: ReqwestClient, -} - -#[derive(Debug, Deserialize)] -pub struct APIResponse { - pub data: Option, -} - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ExecutionBlock { - // TODO: may need to be bigint - pub pos_consensus: ExecutionBlockConsensusData, -} - -#[derive(Debug, Deserialize)] -pub struct ExecutionBlockConsensusData { - pub slot: u64, -} - -impl BeaconchainAPIClient { - /// Creates a new BeaconChainAPIClient based on a api url and key. - pub fn new(api_url: String, api_key: String) -> Self { - let mut headers = HeaderMap::new(); - headers.insert("apikey", HeaderValue::from_str(api_key.as_str()).unwrap()); - let client = reqwest::blocking::Client::builder() - .default_headers(headers.clone()) - .build() - .unwrap(); - let client_async = reqwest::Client::builder() - .default_headers(headers) - .build() - .unwrap(); - let reqwest_client = ReqwestClient::from_clients(client, client_async); - Self { - api_url, - client: reqwest_client, - } - } - - /// GET /api/v1/execution/block/{blockNumbers} - /// Returns the execution + consensus block data for the given eth1 block numbers, in descending block number order. - pub async fn get_execution_blocks( - &self, - eth1_block_numbers: &[U256], - ) -> Result> { - let query_str = eth1_block_numbers - .iter() - .map(|block_number| block_number.to_string()) - .collect::>() - .join(","); - let endpoint = format!("{}/api/v1/execution/block/{}", self.api_url, query_str); - debug!("{}", endpoint); - let response = self.client.fetch_async(endpoint.as_str()).await?; - - let parsed: APIResponse> = response.json().await?; - - Ok(parsed.data.unwrap()) - } -} - -#[cfg(test)] -mod test { - use std::env; - - use super::*; - - #[tokio::test] - #[cfg_attr(feature = "ci", ignore)] - async fn test_get_execution_blocks() { - dotenv::dotenv().ok(); - let api_key = env::var("BEACONCHAIN_API_KEY_1").unwrap(); - let client = BeaconchainAPIClient::new("https://beaconcha.in".to_string(), api_key); - let withdrawals = client - .get_execution_blocks(&[U256::from(18173221)]) - .await - .unwrap(); - assert_eq!(withdrawals.len(), 1); - println!("withdrawals: {:?}", withdrawals); - } -} diff --git a/plonky2x/core/src/utils/eth/mod.rs b/plonky2x/core/src/utils/eth/mod.rs index 768aa304c..fb47005dc 100644 --- a/plonky2x/core/src/utils/eth/mod.rs +++ b/plonky2x/core/src/utils/eth/mod.rs @@ -5,7 +5,6 @@ use std::env; use ethers::providers::{Http, Provider}; pub mod beacon; -pub mod beaconchain; #[derive(Debug, Clone)] pub struct Address(pub [u8; 20]); diff --git a/plonky2x/core/src/utils/reqwest/mod.rs b/plonky2x/core/src/utils/reqwest/mod.rs index d6d734c22..e30e8de61 100644 --- a/plonky2x/core/src/utils/reqwest/mod.rs +++ b/plonky2x/core/src/utils/reqwest/mod.rs @@ -37,7 +37,7 @@ impl ReqwestClient { let response = self .client_async .get(endpoint) - .timeout(core::time::Duration::from_secs(60)) + .timeout(core::time::Duration::from_secs(300)) .send() .await; match response { @@ -78,7 +78,7 @@ impl ReqwestClient { let response = self .client .get(endpoint) - .timeout(core::time::Duration::from_secs(60)) + .timeout(core::time::Duration::from_secs(300)) .send(); match response { diff --git a/plonky2x/core/src/utils/serde/mod.rs b/plonky2x/core/src/utils/serde/mod.rs index 16636e0a4..11573b9bb 100644 --- a/plonky2x/core/src/utils/serde/mod.rs +++ b/plonky2x/core/src/utils/serde/mod.rs @@ -2,6 +2,7 @@ use itertools::Itertools; use num::BigInt; use plonky2::field::extension::Extendable; use plonky2::hash::hash_types::RichField; +use plonky2::plonk::circuit_data::VerifierCircuitTarget; use plonky2::plonk::config::GenericConfig; use plonky2::plonk::proof::{ProofWithPublicInputs, ProofWithPublicInputsTarget}; use plonky2::util::serialization::{Buffer, IoResult, Read, Write}; @@ -169,6 +170,46 @@ where serializer.serialize_str(&hex) } +pub fn serialize_proof_with_pis_target_option( + proof_with_pis: &Option>, + serializer: S, +) -> Result +where + S: serde::Serializer, +{ + match proof_with_pis { + Some(proof_with_pis) => { + let mut buffer: Vec = Vec::new(); + buffer + .write_target_proof_with_public_inputs(proof_with_pis) + .unwrap(); + let hex = hex::encode(buffer); + serializer.serialize_some(&hex) + } + None => serializer.serialize_none(), + } +} + +pub fn deserialize_proof_with_pis_target_option<'de, D, const E: usize>( + deserialize: D, +) -> Result>, D::Error> +where + D: serde::Deserializer<'de>, +{ + let s: Option = Deserialize::deserialize(deserialize)?; + match s { + Some(s) => { + let bytes = hex::decode(s).unwrap(); + let mut buffer = Buffer::new(&bytes); + buffer + .read_target_proof_with_public_inputs() + .map_err(serde::de::Error::custom) + .map(Some) + } + None => Ok(None), + } +} + pub fn deserialize_proof_with_pis_target<'de, D, const E: usize>( deserialize: D, ) -> Result, D::Error> @@ -217,3 +258,43 @@ where } Ok(proof_with_pis_vec) } + +pub fn serialize_verifier_circuit_target_option( + verifier_circuit_target: &Option, + serializer: S, +) -> Result +where + S: serde::Serializer, +{ + match verifier_circuit_target { + Some(verifier_circuit_target) => { + let mut buffer: Vec = Vec::new(); + buffer + .write_target_verifier_circuit(verifier_circuit_target) + .unwrap(); + let hex = hex::encode(buffer); + serializer.serialize_some(&hex) + } + None => serializer.serialize_none(), + } +} + +pub fn deserialize_verifier_circuit_target_option<'de, D>( + deserialize: D, +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let s: Option = Deserialize::deserialize(deserialize)?; + match s { + Some(s) => { + let bytes = hex::decode(s).unwrap(); + let mut buffer = Buffer::new(&bytes); + buffer + .read_target_verifier_circuit() + .map_err(serde::de::Error::custom) + .map(Some) + } + None => Ok(None), + } +}