diff --git a/.vscode/settings.json b/.vscode/settings.json index db220b5d..62ae1315 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,7 @@ "./Cargo.toml", "./guests/eth-block/Cargo.toml", "./guests/op-block/Cargo.toml", + "./guests/op-derive/Cargo.toml", "./testing/ef-tests/testguest/Cargo.toml" ] } \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 60e5da02..8f50e55a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.8.6" @@ -635,9 +641,9 @@ 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", ] @@ -792,6 +798,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpp_demangle" version = "0.4.3" @@ -860,9 +875,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f85c3514d2a6e64160359b45a3918c3b4178bcbf4ae5d03ab2d02e521c479a" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core", @@ -915,6 +930,12 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "dary_heap" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" + [[package]] name = "data-encoding" version = "2.4.0" @@ -1085,9 +1106,9 @@ checksum = "7f6e7d85896690fe195447717af8eceae0593ac2196fd42fe88c184e904406ce" [[package]] name = "elliptic-curve" -version = "0.13.7" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9775b22bc152ad86a0cf23f0f348b884b26add12bf741e7ffc4d4ab2ab4d205" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -1613,6 +1634,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.2" @@ -2023,6 +2053,30 @@ version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "libflate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524" +dependencies = [ + "core2", + "hashbrown 0.13.2", + "rle-decode-fast", +] + [[package]] name = "libloading" version = "0.7.4" @@ -3262,6 +3316,12 @@ dependencies = [ "libm", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "rlp" version = "0.5.2" @@ -3325,9 +3385,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", @@ -3391,9 +3451,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.24" +version = "0.38.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ad981d6c340a49cdc40a1028d9c6084ec7e9fa33fcb839cab656a267071e234" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" dependencies = [ "bitflags 2.4.1", "errno", @@ -3998,22 +4058,22 @@ dependencies = [ [[package]] name = "thiserror-core" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d97345f6437bb2004cd58819d8a9ef8e36cdd7661c2abc4bbde0a7c40d9f497" +checksum = "c001ee18b7e5e3f62cbf58c7fe220119e68d902bb7443179c0c8aef30090e999" dependencies = [ "thiserror-core-impl", ] [[package]] name = "thiserror-core-impl" -version = "1.0.38" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ac1c5050e43014d16b2f94d0d2ce79e65ffdd8b38d8048f9c8f6a8a6da62ac" +checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.39", ] [[package]] @@ -4742,6 +4802,7 @@ dependencies = [ "revm", "risc0-zkvm", "rstest", + "ruint", "serde", "tempfile", "tokio", @@ -4761,6 +4822,7 @@ dependencies = [ name = "zeth-lib" version = "0.1.0" dependencies = [ + "alloy-sol-types", "anyhow", "bincode", "chrono", @@ -4768,6 +4830,7 @@ dependencies = [ "ethers-providers", "flate2", "hashbrown 0.14.2", + "libflate", "log", "once_cell", "revm", diff --git a/guests/Cargo.toml b/guests/Cargo.toml index 598a89cc..c5831d9f 100644 --- a/guests/Cargo.toml +++ b/guests/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" risc0-build = { workspace = true } [package.metadata.risc0] -methods = ["eth-block", "op-block"] +methods = ["eth-block", "op-block", "op-derive"] diff --git a/guests/eth-block/Cargo.lock b/guests/eth-block/Cargo.lock index f1c270cc..1a77541b 100644 --- a/guests/eth-block/Cargo.lock +++ b/guests/eth-block/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.8.6" @@ -87,6 +93,35 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7e42aa2983db6676af5d762bc8d9371dd74f5948739790d3080c3d652a957b" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -564,6 +599,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.11" @@ -645,6 +689,12 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "dary_heap" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" + [[package]] name = "data-encoding" version = "2.4.0" @@ -722,6 +772,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "ecdsa" version = "0.16.9" @@ -1202,6 +1258,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.2" @@ -1534,6 +1599,30 @@ version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "libflate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524" +dependencies = [ + "core2", + "hashbrown 0.13.2", + "rle-decode-fast", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2380,6 +2469,12 @@ dependencies = [ "libm", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "rlp" version = "0.5.2" @@ -2936,6 +3031,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -3632,12 +3739,14 @@ dependencies = [ name = "zeth-lib" version = "0.1.0" dependencies = [ + "alloy-sol-types", "anyhow", "chrono", "ethers-core", "ethers-providers", "flate2", "hashbrown 0.14.2", + "libflate", "log", "once_cell", "revm", diff --git a/guests/op-block/Cargo.lock b/guests/op-block/Cargo.lock index e7fe743c..a10f1376 100644 --- a/guests/op-block/Cargo.lock +++ b/guests/op-block/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.8.6" @@ -87,6 +93,35 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -564,6 +599,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.11" @@ -645,6 +689,12 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "dary_heap" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" + [[package]] name = "data-encoding" version = "2.4.0" @@ -722,6 +772,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "ecdsa" version = "0.16.9" @@ -1194,6 +1250,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.2" @@ -1526,6 +1591,30 @@ version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "libflate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524" +dependencies = [ + "core2", + "hashbrown 0.13.2", + "rle-decode-fast", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2380,6 +2469,12 @@ dependencies = [ "libm", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "rlp" version = "0.5.2" @@ -2936,6 +3031,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -3632,12 +3739,14 @@ dependencies = [ name = "zeth-lib" version = "0.1.0" dependencies = [ + "alloy-sol-types", "anyhow", "chrono", "ethers-core", "ethers-providers", "flate2", "hashbrown 0.14.2", + "libflate", "log", "once_cell", "revm", diff --git a/guests/op-derive/Cargo.lock b/guests/op-derive/Cargo.lock new file mode 100644 index 00000000..0a73d81a --- /dev/null +++ b/guests/op-derive/Cargo.lock @@ -0,0 +1,3743 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "ahash" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "alloy-primitives" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0628ec0ba5b98b3370bb6be17b12f23bfce8ee4ad83823325a20546d9b03b78" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "rand", + "ruint", + "serde", + "tiny-keccak", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" +dependencies = [ + "alloy-rlp-derive", + "arrayvec", + "bytes", + "smol_str", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "async-trait" +version = "0.1.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.0", +] + +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bindgen" +version = "0.66.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" +dependencies = [ + "bitflags 2.4.1", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.39", + "which", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "serde", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "c-kzg" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac926d808fb72fe09ebf471a091d6d72918876ccf0b4989766093d2d0d24a0ef" +dependencies = [ + "bindgen", + "blst", + "cc", + "glob", + "hex", + "libc", + "serde", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets", +] + +[[package]] +name = "clang-sys" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "const-hex" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.2" +source = "git+https://github.com/risc0/RustCrypto-crypto-bigint?tag=v0.5.2-risc0#8b30304277cfe553b51a78a0e693f48bbb059eb3" +dependencies = [ + "generic-array", + "getrandom", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.39", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "dary_heap" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" + +[[package]] +name = "data-encoding" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elf" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6e7d85896690fe195447717af8eceae0593ac2196fd42fe88c184e904406ce" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enr" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +dependencies = [ + "base64 0.21.5", + "bytes", + "hex", + "k256", + "log", + "rand", + "rlp", + "serde", + "sha3", + "zeroize", +] + +[[package]] +name = "enumn" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers-core" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f03e0bdc216eeb9e355b90cf610ef6c5bb8aca631f97b5ae9980ce34ea7878d" +dependencies = [ + "arrayvec", + "bytes", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum", + "open-fastrlp", + "rand", + "rlp", + "serde", + "serde_json", + "strum", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "ethers-providers" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25d6c0c9455d93d4990c06e049abf9b30daf148cf461ee939c11d88907c60816" +dependencies = [ + "async-trait", + "auto_impl", + "base64 0.21.5", + "bytes", + "const-hex", + "enr", + "ethers-core", + "futures-channel", + "futures-core", + "futures-timer", + "futures-util", + "hashers", + "http", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash", + "allocator-api2", + "serde", +] + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.4.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.2", + "serde", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.5", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "git+https://github.com/risc0/RustCrypto-elliptic-curves?tag=k256/v0.13.1-risc0#44b1fc2b317e76bb150636cf67d0fbdfcac39601" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "libflate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524" +dependencies = [ + "core2", + "hashbrown 0.13.2", + "rle-decode-fast", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "linux-raw-sys" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683751d591e6d81200c39fb0d1032608b77724f34114db54f571ff1317b337c0" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c11e44798ad209ccdd91fc192f0526a369a01234f7373e1b141c96d7cee4f0e" +dependencies = [ + "proc-macro-crate 2.0.0", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "op-derive" +version = "0.1.0" +dependencies = [ + "k256", + "risc0-zkvm", + "zeth-lib", + "zeth-primitives", +] + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.0", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2", + "syn 2.0.39", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.1", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.1" +source = "git+https://github.com/ferrilab/radium.git?rev=723bed5#723bed5abd75994ee4b7221b8b12c9f4e77ce408" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +dependencies = [ + "base64 0.21.5", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "revm" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f4ca8ae0345104523b4af1a8a7ea97cfa1865cdb7a7c25d23c1a18d9b48598" +dependencies = [ + "auto_impl", + "revm-interpreter", + "revm-precompile", + "serde", + "serde_json", +] + +[[package]] +name = "revm-interpreter" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f959cafdf64a7f89b014fa73dc2325001cf654b3d9400260b212d19a2ebe3da0" +dependencies = [ + "revm-primitives", + "serde", +] + +[[package]] +name = "revm-precompile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d360a88223d85709d2e95d4609eb1e19c649c47e28954bfabae5e92bb37e83e" +dependencies = [ + "c-kzg", + "k256", + "num", + "once_cell", + "revm-primitives", + "ripemd", + "secp256k1", + "sha2", + "substrate-bn", +] + +[[package]] +name = "revm-primitives" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51187b852d9e458816a2e19c81f1dd6c924077e1a8fccd16e4f044f865f299d7" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "auto_impl", + "bitflags 2.4.1", + "bitvec", + "c-kzg", + "enumn", + "hashbrown 0.14.2", + "hex", + "serde", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +dependencies = [ + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "risc0-binfmt" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede27631e6b2a946a43db812063453c9701d5d2544d82f9abec2cc12574ebb8e" +dependencies = [ + "anyhow", + "elf", + "log", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", +] + +[[package]] +name = "risc0-circuit-rv32im" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e00222152fdc94cacc9b6682b5c0cbe8138f1ee82e80c24a64d9ad2c6d7415" +dependencies = [ + "anyhow", + "log", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "tracing", +] + +[[package]] +name = "risc0-core" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08605aec93ea22ed83f7f81f42e2d7287a5b0c749d8671f94de9d5994020045c" +dependencies = [ + "bytemuck", + "rand_core", +] + +[[package]] +name = "risc0-zkp" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28166926bb177824939f4e91083198f9f3da8137aeac32361bd34548c0526fa5" +dependencies = [ + "anyhow", + "blake2", + "bytemuck", + "digest 0.10.7", + "hex", + "log", + "paste", + "rand_core", + "risc0-core", + "risc0-zkvm-platform", + "serde", + "sha2", + "tracing", +] + +[[package]] +name = "risc0-zkvm" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec972152bcaa1a2967e412e22a84f6e2984a95c701bcc7943ca8ca10126ee0a2" +dependencies = [ + "anyhow", + "bytemuck", + "cfg-if", + "getrandom", + "hex", + "libm", + "log", + "num-derive", + "num-traits", + "risc0-binfmt", + "risc0-circuit-rv32im", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "tempfile", + "tracing", +] + +[[package]] +name = "risc0-zkvm-platform" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8524b46783b58b00e9b2a4712e837093c975b23cf25bfaf99e1cf69e9011bf6b" + +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ruint" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608a5726529f2f0ef81b8fde9873c4bb829d6b5b5ca6be4d97345ddf0749c825" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.20", +] + +[[package]] +name = "rustix" +version = "0.38.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustls" +version = "0.21.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" +dependencies = [ + "log", + "ring 0.17.5", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.5", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scale-info" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7d66a1128282b7ef025a8ead62a4a9fcf017382ec53b8ffbf4d7bf77bd3c60" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf2c68b89cafb3b8d918dd07b42be0da66ff202cf1155c5739a4e0c1ea0dc19" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.5", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "serde" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.192" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "indexmap 2.1.0", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64 0.21.5", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "git+https://github.com/risc0/RustCrypto-hashes?tag=sha2/v0.10.6-risc0#e75cafd9f55da196061f6fadf8bc8a86778192b7" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.39", +] + +[[package]] +name = "substrate-bn" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b5bbfa79abbae15dd642ea8176a21a635ff3c00059961d1ea27ad04e5b441c" +dependencies = [ + "byteorder", + "crunchy", + "lazy_static", + "rand", + "rustc-hex", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "time" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls", + "tokio", + "tokio-rustls", + "tungstenite", + "webpki-roots", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.1.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand", + "rustls", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" + +[[package]] +name = "web-sys" +version = "0.3.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +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", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[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_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[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_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "winnow" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.0", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "zeth-lib" +version = "0.1.0" +dependencies = [ + "alloy-sol-types", + "anyhow", + "chrono", + "ethers-core", + "ethers-providers", + "flate2", + "hashbrown 0.14.2", + "libflate", + "log", + "once_cell", + "revm", + "ruint", + "serde", + "serde_json", + "serde_with", + "thiserror", + "tokio", + "zeth-primitives", +] + +[[package]] +name = "zeth-primitives" +version = "0.1.0" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "alloy-rlp-derive", + "anyhow", + "bytes", + "ethers-core", + "k256", + "revm-primitives", + "rlp", + "serde", + "sha3", + "thiserror", +] diff --git a/guests/op-derive/Cargo.toml b/guests/op-derive/Cargo.toml new file mode 100644 index 00000000..44ab376d --- /dev/null +++ b/guests/op-derive/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "op-derive" +version = "0.1.0" +edition = "2021" + +[workspace] + +[dependencies] +k256 = { version = "=0.13.1", features = ["std", "ecdsa"], default_features = false } +risc0-zkvm = { version = "0.18", default-features = false, features = ['std'] } +zeth-lib = { path = "../../lib", default-features = false } +zeth-primitives = { path = "../../primitives", default-features = false } + +[patch.crates-io] +radium = { git = 'https://github.com/ferrilab/radium.git', rev = "723bed5" } +# use optimized risc0 circuit +crypto-bigint = { git = "https://github.com/risc0/RustCrypto-crypto-bigint", tag = "v0.5.2-risc0" } +k256 = { git = "https://github.com/risc0/RustCrypto-elliptic-curves", tag = "k256/v0.13.1-risc0" } +sha2 = { git = "https://github.com/risc0/RustCrypto-hashes", tag = "sha2/v0.10.6-risc0" } + +[profile.release] +codegen-units = 1 +panic = "abort" diff --git a/guests/op-derive/src/main.rs b/guests/op-derive/src/main.rs new file mode 100644 index 00000000..4f7c34db --- /dev/null +++ b/guests/op-derive/src/main.rs @@ -0,0 +1,32 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#![no_main] + +use risc0_zkvm::guest::env; +use zeth_lib::optimism::{ + batcher_db::MemDb, config::OPTIMISM_CHAIN_SPEC, DeriveInput, DeriveMachine, +}; + +risc0_zkvm::guest::entry!(main); + +pub fn main() { + let derive_input: DeriveInput = env::read(); + let mut derive_machine = DeriveMachine::new(&OPTIMISM_CHAIN_SPEC, derive_input) + .expect("Could not create derive machine"); + let output = derive_machine + .derive() + .expect("Failed to process derivation input"); + env::commit(&output); +} diff --git a/host/Cargo.toml b/host/Cargo.toml index 959e6fdb..c4d6e137 100644 --- a/host/Cargo.toml +++ b/host/Cargo.toml @@ -16,6 +16,7 @@ hex = "0.4.3" log = "0.4" revm = { workspace = true } risc0-zkvm = { workspace = true, features = ["prove", "profiler"] } +ruint = { version = "1.10", default-features = false } serde = "1.0" tempfile = "3.6" tokio = { version = "1.23", features = ["full"] } diff --git a/host/src/bin/op-derive.rs b/host/src/bin/op-derive.rs new file mode 100644 index 00000000..7c1011f8 --- /dev/null +++ b/host/src/bin/op-derive.rs @@ -0,0 +1,452 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Example usage: +// +// RUST_LOG=info ./target/release/op-derive \ +// --eth-rpc-url="https://eth-mainnet.g.alchemy.com/v2/API_KEY_HERE" \ +// --op-rpc-url="https://opt-mainnet.g.alchemy.com/v2/API_KEY_HERE" \ +// --cache \ +// --op-block-no=109279674 \ +// --op-blocks=6 + +use std::path::{Path, PathBuf}; + +use anyhow::{Context, Result}; +use bonsai_sdk::alpha as bonsai_sdk; +use clap::Parser; +use log::{error, info}; +use risc0_zkvm::{ + serde::to_vec, ExecutorEnv, ExecutorImpl, FileSegmentRef, MemoryImage, Program, Receipt, +}; +use tempfile::tempdir; +use zeth_guests::{OP_DERIVE_ELF, OP_DERIVE_ID, OP_DERIVE_PATH}; +use zeth_lib::{ + host::provider::{new_provider, BlockQuery}, + optimism::{ + batcher_db::{BatcherDb, BlockInput, MemDb}, + config::OPTIMISM_CHAIN_SPEC, + DeriveInput, DeriveMachine, DeriveOutput, + }, +}; +use zeth_primitives::{ + block::Header, + transactions::{ethereum::EthereumTxEssence, optimism::OptimismTxEssence}, +}; + +#[derive(Parser, Debug, Clone)] +#[clap(author, version, about, long_about = None)] +struct Args { + #[clap(long, require_equals = true)] + /// URL of the L1 RPC node. + eth_rpc_url: Option, + + #[clap(long, require_equals = true)] + /// URL of the L2 RPC node. + op_rpc_url: Option, + + #[clap(short, long, require_equals = true, num_args = 0..=1, default_missing_value = "host/testdata/derivation")] + /// Use a local directory as a cache for RPC calls. Accepts a custom directory. + /// [default: host/testdata/derivation] + cache: Option, + + #[clap(long, require_equals = true)] + /// L2 block number to begin from + op_block_no: u64, + + #[clap(long, require_equals = true)] + /// Number of L2 blocks to provably derive. + op_blocks: u64, + + #[clap(short, long, require_equals = true, num_args = 0..=1, default_missing_value = "20")] + /// Runs the verification inside the zkvm executor locally. Accepts a custom maximum + /// segment cycle count as a power of 2. [default: 20] + local_exec: Option, + + #[clap(short, long, default_value_t = false)] + /// Whether to submit the proving workload to Bonsai. + submit_to_bonsai: bool, + + #[clap(short, long, require_equals = true)] + /// Bonsai Session UUID to use for receipt verification. + verify_bonsai_receipt_uuid: Option, + + #[clap(short, long, default_value_t = false)] + /// Whether to profile the zkVM execution + profile: bool, +} + +fn cache_file_path(cache_path: &Path, network: &str, block_no: u64, ext: &str) -> PathBuf { + cache_path + .join(network) + .join(block_no.to_string()) + .with_extension(ext) +} + +fn eth_cache_path(cache: &Option, block_no: u64) -> Option { + cache + .as_ref() + .map(|dir| cache_file_path(dir, "ethereum", block_no, "json.gz")) +} + +fn op_cache_path(cache: &Option, block_no: u64) -> Option { + cache + .as_ref() + .map(|dir| cache_file_path(dir, "optimism", block_no, "json.gz")) +} + +#[tokio::main] +async fn main() -> Result<()> { + env_logger::init(); + let args = Args::parse(); + + info!("Fetching data ..."); + let (derive_input, output) = tokio::task::spawn_blocking(move || { + let derive_input = DeriveInput { + db: RpcDb::new(args.eth_rpc_url, args.op_rpc_url, args.cache), + op_head_block_no: args.op_block_no, + op_derive_block_count: args.op_blocks, + }; + let mut derive_machine = DeriveMachine::new(&OPTIMISM_CHAIN_SPEC, derive_input) + .context("Could not create derive machine")?; + let derive_output = derive_machine.derive().context("could not derive")?; + let derive_input_mem = DeriveInput { + db: derive_machine.derive_input.db.get_mem_db(), + op_head_block_no: args.op_block_no, + op_derive_block_count: args.op_blocks, + }; + let out: Result<_> = Ok((derive_input_mem, derive_output)); + out + }) + .await? + .context("preflight failed")?; + + info!("Running from memory ..."); + { + let output_mem = DeriveMachine::new(&OPTIMISM_CHAIN_SPEC, derive_input.clone()) + .context("Could not create derive machine")? + .derive() + .unwrap(); + assert_eq!(output, output_mem); + } + + info!("In-memory test complete"); + println!("Eth tail: {} {}", output.eth_tail.0, output.eth_tail.1); + println!("Op Head: {} {}", output.op_head.0, output.op_head.1); + for derived_block in &output.derived_op_blocks { + println!("Derived: {} {}", derived_block.0, derived_block.1); + } + + // Run in the executor (if requested) + if let Some(segment_limit_po2) = args.local_exec { + info!( + "Running in executor with segment_limit_po2 = {:?}", + segment_limit_po2 + ); + + let input = to_vec(&derive_input).expect("Could not serialize input!"); + info!( + "Input size: {} words ( {} MB )", + input.len(), + input.len() * 4 / 1_000_000 + ); + + let mut profiler = risc0_zkvm::Profiler::new(OP_DERIVE_PATH, OP_DERIVE_ELF).unwrap(); + + info!("Running the executor..."); + let start_time = std::time::Instant::now(); + let session = { + let mut builder = ExecutorEnv::builder(); + builder + .session_limit(None) + .segment_limit_po2(segment_limit_po2) + .write_slice(&input); + + if args.profile { + builder.trace_callback(profiler.make_trace_callback()); + } + + let env = builder.build().unwrap(); + let mut exec = ExecutorImpl::from_elf(env, OP_DERIVE_ELF).unwrap(); + + let segment_dir = tempdir().unwrap(); + + exec.run_with_callback(|segment| { + Ok(Box::new(FileSegmentRef::new(&segment, segment_dir.path())?)) + }) + .unwrap() + }; + println!( + "Generated {:?} segments; elapsed time: {:?}", + session.segments.len(), + start_time.elapsed() + ); + + if args.profile { + profiler.finalize(); + + let sys_time = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap(); + tokio::fs::write( + format!("profile_{}.pb", sys_time.as_secs()), + &profiler.encode_to_vec(), + ) + .await + .expect("Failed to write profiling output"); + } + + println!( + "Executor ran in (roughly) {} cycles", + session.segments.len() * (1 << segment_limit_po2) + ); + + let output_guest: DeriveOutput = session.journal.decode().unwrap(); + + if output == output_guest { + println!("Executor succeeded"); + } else { + error!( + "Output mismatch! Executor: {:?}, expected: {:?}", + output_guest, output, + ); + } + } + + let mut bonsai_session_uuid = args.verify_bonsai_receipt_uuid; + + // Run in Bonsai (if requested) + if bonsai_session_uuid.is_none() && args.submit_to_bonsai { + info!("Creating Bonsai client"); + let client = bonsai_sdk::Client::from_env(risc0_zkvm::VERSION) + .expect("Could not create Bonsai client"); + + // create the memoryImg, upload it and return the imageId + info!("Uploading memory image"); + let img_id = { + let program = Program::load_elf(OP_DERIVE_ELF, risc0_zkvm::GUEST_MAX_MEM as u32) + .expect("Could not load ELF"); + let image = MemoryImage::new(&program, risc0_zkvm::PAGE_SIZE as u32) + .expect("Could not create memory image"); + let image_id = hex::encode(image.compute_id()); + let image = bincode::serialize(&image).expect("Failed to serialize memory img"); + + client + .upload_img(&image_id, image) + .expect("Could not upload ELF"); + image_id + }; + + // Prepare input data and upload it. + info!("Uploading inputs"); + let input_data = to_vec(&derive_input).unwrap(); + let input_data = bytemuck::cast_slice(&input_data).to_vec(); + let input_id = client + .upload_input(input_data) + .expect("Could not upload inputs"); + + // Start a session running the prover + info!("Starting session"); + let session = client + .create_session(img_id, input_id) + .expect("Could not create Bonsai session"); + + println!("Bonsai session UUID: {}", session.uuid); + bonsai_session_uuid = Some(session.uuid) + } + + // Verify receipt from Bonsai (if requested) + if let Some(session_uuid) = bonsai_session_uuid { + let client = bonsai_sdk::Client::from_env(risc0_zkvm::VERSION) + .expect("Could not create Bonsai client"); + let session = bonsai_sdk::SessionId { uuid: session_uuid }; + + loop { + let res = session + .status(&client) + .expect("Could not fetch Bonsai status"); + if res.status == "RUNNING" { + println!( + "Current status: {} - state: {} - continue polling...", + res.status, + res.state.unwrap_or_default() + ); + tokio::time::sleep(std::time::Duration::from_secs(15)).await; + continue; + } + if res.status == "SUCCEEDED" { + // Download the receipt, containing the output + let receipt_url = res + .receipt_url + .expect("API error, missing receipt on completed session"); + + let receipt_buf = client + .download(&receipt_url) + .expect("Could not download receipt"); + let receipt: Receipt = + bincode::deserialize(&receipt_buf).expect("Could not deserialize receipt"); + receipt + .verify(OP_DERIVE_ID) + .expect("Receipt verification failed"); + + let bonsai_output: DeriveOutput = receipt.journal.decode().unwrap(); + + if output == bonsai_output { + println!("Bonsai succeeded"); + } else { + error!( + "Output mismatch! Bonsai: {:?}, expected: {:?}", + bonsai_output, output, + ); + } + } else { + panic!( + "Workflow exited: {} - | err: {}", + res.status, + res.error_msg.unwrap_or_default() + ); + } + + break; + } + + info!("Bonsai request completed"); + } + + Ok(()) +} + +pub struct RpcDb { + eth_rpc_url: Option, + op_rpc_url: Option, + cache: Option, + mem_db: MemDb, +} + +impl RpcDb { + pub fn new( + eth_rpc_url: Option, + op_rpc_url: Option, + cache: Option, + ) -> Self { + RpcDb { + eth_rpc_url, + op_rpc_url, + cache, + mem_db: MemDb::new(), + } + } + + pub fn get_mem_db(self) -> MemDb { + self.mem_db + } +} + +impl BatcherDb for RpcDb { + fn get_full_op_block(&mut self, block_no: u64) -> Result> { + let mut provider = new_provider( + op_cache_path(&self.cache, block_no), + self.op_rpc_url.clone(), + ) + .context("failed to create provider")?; + let block = { + let ethers_block = provider.get_full_block(&BlockQuery { block_no })?; + BlockInput { + block_header: ethers_block.clone().try_into().unwrap(), + transactions: ethers_block + .transactions + .into_iter() + .map(|tx| tx.try_into().unwrap()) + .collect(), + receipts: None, + } + }; + self.mem_db.full_op_block.insert(block_no, block.clone()); + provider.save()?; + Ok(block) + } + + fn get_op_block_header(&mut self, block_no: u64) -> Result
{ + let mut provider = new_provider( + op_cache_path(&self.cache, block_no), + self.op_rpc_url.clone(), + )?; + let header: Header = provider + .get_partial_block(&BlockQuery { block_no })? + .try_into()?; + self.mem_db.op_block_header.insert(block_no, header.clone()); + provider.save()?; + Ok(header) + } + + fn get_full_eth_block(&mut self, block_no: u64) -> Result> { + let query = BlockQuery { block_no }; + let mut provider = new_provider( + eth_cache_path(&self.cache, block_no), + self.eth_rpc_url.clone(), + )?; + let block = { + let ethers_block = provider.get_full_block(&query)?; + let block_header: Header = ethers_block.clone().try_into().unwrap(); + // include receipts when needed + let can_contain_deposits = zeth_lib::optimism::deposits::can_contain( + &OPTIMISM_CHAIN_SPEC.deposit_contract, + &block_header.logs_bloom, + ); + let can_contain_config = zeth_lib::optimism::system_config::can_contain( + &OPTIMISM_CHAIN_SPEC.system_config_contract, + &block_header.logs_bloom, + ); + let receipts = if can_contain_config || can_contain_deposits { + let receipts = provider.get_block_receipts(&query)?; + Some( + receipts + .into_iter() + .map(|receipt| receipt.try_into()) + .collect::, _>>() + .context("invalid receipt")?, + ) + } else { + None + }; + BlockInput { + block_header, + transactions: ethers_block + .transactions + .into_iter() + .map(|tx| tx.try_into().unwrap()) + .collect(), + receipts, + } + }; + self.mem_db.full_eth_block.insert(block_no, block.clone()); + provider.save()?; + Ok(block) + } + + fn get_eth_block_header(&mut self, block_no: u64) -> Result
{ + let mut provider = new_provider( + eth_cache_path(&self.cache, block_no), + self.eth_rpc_url.clone(), + )?; + let header: Header = provider + .get_partial_block(&BlockQuery { block_no })? + .try_into()?; + self.mem_db + .eth_block_header + .insert(block_no, header.clone()); + provider.save()?; + Ok(header) + } +} diff --git a/host/src/bin/op-info.rs b/host/src/bin/op-info.rs index c5f392c0..c675d619 100644 --- a/host/src/bin/op-info.rs +++ b/host/src/bin/op-info.rs @@ -14,26 +14,13 @@ use std::path::{Path, PathBuf}; -use alloy_sol_types::{sol, SolInterface}; +use alloy_sol_types::SolInterface; use anyhow::Result; use clap::Parser; -use zeth_lib::host::provider::{new_provider, BlockQuery}; - -sol! { - #[derive(Debug)] - interface OpSystemInfo { - function setL1BlockValues( - uint64 _number, - uint64 _timestamp, - uint256 _basefee, - bytes32 _hash, - uint64 _sequenceNumber, - bytes32 _batcherHash, - uint256 _l1FeeOverhead, - uint256 _l1FeeScalar - ); - } -} +use zeth_lib::{ + host::provider::{new_provider, BlockQuery}, + optimism::OpSystemInfo, +}; #[derive(Parser, Debug, Clone)] #[clap(author, version, about, long_about = None)] @@ -48,7 +35,7 @@ struct Args { cache: Option, #[clap(long, require_equals = true)] - /// L2 block number to begin from + /// L2 block number to query block_no: u64, } diff --git a/host/src/main.rs b/host/src/main.rs index f4be9049..fea9c0ac 100644 --- a/host/src/main.rs +++ b/host/src/main.rs @@ -291,6 +291,11 @@ where .status(&client) .expect("Could not fetch Bonsai status"); if res.status == "RUNNING" { + println!( + "Current status: {} - state: {} - continue polling...", + res.status, + res.state.unwrap_or_default() + ); tokio::time::sleep(std::time::Duration::from_secs(15)).await; continue; } @@ -321,7 +326,11 @@ where ); } } else { - panic!("Workflow exited: {}", res.status); + panic!( + "Workflow exited: {} - | err: {}", + res.status, + res.error_msg.unwrap_or_default() + ); } break; diff --git a/host/testdata/derivation/.gitkeep b/host/testdata/derivation/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/host/testdata/derivation/ethereum/.gitkeep b/host/testdata/derivation/ethereum/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/host/testdata/derivation/ethereum/18090205.json.gz b/host/testdata/derivation/ethereum/18090205.json.gz new file mode 100644 index 00000000..fcefcc1e Binary files /dev/null and b/host/testdata/derivation/ethereum/18090205.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090206.json.gz b/host/testdata/derivation/ethereum/18090206.json.gz new file mode 100644 index 00000000..da043287 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090206.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090207.json.gz b/host/testdata/derivation/ethereum/18090207.json.gz new file mode 100644 index 00000000..d6b69373 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090207.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090208.json.gz b/host/testdata/derivation/ethereum/18090208.json.gz new file mode 100644 index 00000000..1e886d15 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090208.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090209.json.gz b/host/testdata/derivation/ethereum/18090209.json.gz new file mode 100644 index 00000000..88cd5f04 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090209.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090210.json.gz b/host/testdata/derivation/ethereum/18090210.json.gz new file mode 100644 index 00000000..d39fe8bc Binary files /dev/null and b/host/testdata/derivation/ethereum/18090210.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090211.json.gz b/host/testdata/derivation/ethereum/18090211.json.gz new file mode 100644 index 00000000..5cd54573 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090211.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090212.json.gz b/host/testdata/derivation/ethereum/18090212.json.gz new file mode 100644 index 00000000..d46eca5d Binary files /dev/null and b/host/testdata/derivation/ethereum/18090212.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090213.json.gz b/host/testdata/derivation/ethereum/18090213.json.gz new file mode 100644 index 00000000..de28d0c1 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090213.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090214.json.gz b/host/testdata/derivation/ethereum/18090214.json.gz new file mode 100644 index 00000000..b4f6249b Binary files /dev/null and b/host/testdata/derivation/ethereum/18090214.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090215.json.gz b/host/testdata/derivation/ethereum/18090215.json.gz new file mode 100644 index 00000000..72ead9d2 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090215.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090216.json.gz b/host/testdata/derivation/ethereum/18090216.json.gz new file mode 100644 index 00000000..c25ee505 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090216.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090217.json.gz b/host/testdata/derivation/ethereum/18090217.json.gz new file mode 100644 index 00000000..7b03884b Binary files /dev/null and b/host/testdata/derivation/ethereum/18090217.json.gz differ diff --git a/host/testdata/derivation/ethereum/18090218.json.gz b/host/testdata/derivation/ethereum/18090218.json.gz new file mode 100644 index 00000000..899286e0 Binary files /dev/null and b/host/testdata/derivation/ethereum/18090218.json.gz differ diff --git a/host/testdata/derivation/optimism/.gitkeep b/host/testdata/derivation/optimism/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/host/testdata/derivation/optimism/109279674.json.gz b/host/testdata/derivation/optimism/109279674.json.gz new file mode 100644 index 00000000..1fc93512 Binary files /dev/null and b/host/testdata/derivation/optimism/109279674.json.gz differ diff --git a/host/testdata/derivation/optimism/109279675.json.gz b/host/testdata/derivation/optimism/109279675.json.gz new file mode 100644 index 00000000..e8b9341e Binary files /dev/null and b/host/testdata/derivation/optimism/109279675.json.gz differ diff --git a/host/testdata/derivation/optimism/109279676.json.gz b/host/testdata/derivation/optimism/109279676.json.gz new file mode 100644 index 00000000..3089101f Binary files /dev/null and b/host/testdata/derivation/optimism/109279676.json.gz differ diff --git a/host/testdata/derivation/optimism/109279677.json.gz b/host/testdata/derivation/optimism/109279677.json.gz new file mode 100644 index 00000000..bdc52000 Binary files /dev/null and b/host/testdata/derivation/optimism/109279677.json.gz differ diff --git a/host/testdata/derivation/optimism/109279678.json.gz b/host/testdata/derivation/optimism/109279678.json.gz new file mode 100644 index 00000000..cd4e0b97 Binary files /dev/null and b/host/testdata/derivation/optimism/109279678.json.gz differ diff --git a/host/testdata/derivation/optimism/109279679.json.gz b/host/testdata/derivation/optimism/109279679.json.gz new file mode 100644 index 00000000..fcd78d79 Binary files /dev/null and b/host/testdata/derivation/optimism/109279679.json.gz differ diff --git a/host/testdata/derivation/optimism/109279680.json.gz b/host/testdata/derivation/optimism/109279680.json.gz new file mode 100644 index 00000000..02a37308 Binary files /dev/null and b/host/testdata/derivation/optimism/109279680.json.gz differ diff --git a/host/testdata/optimism/.gitkeep b/host/testdata/optimism/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/host/tests/blocks.rs b/host/tests/cmd.rs similarity index 86% rename from host/tests/blocks.rs rename to host/tests/cmd.rs index 978a3ddd..d8c6963a 100644 --- a/host/tests/blocks.rs +++ b/host/tests/cmd.rs @@ -26,7 +26,7 @@ use zeth_lib::{ use zeth_primitives::{transactions::ethereum::EthereumTxEssence, trie::MptNodeData}; #[rstest] -fn block_cli_ethereum(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) { +fn zeth_ethereum(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) { let block_no = file_prefix(&path); Command::cargo_bin("zeth") @@ -36,6 +36,20 @@ fn block_cli_ethereum(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) { .success(); } +#[rstest] +#[case(109279674, 6)] +fn derive_optimism(#[case] op_block_no: u64, #[case] op_blocks: u64) { + Command::cargo_bin("op-derive") + .unwrap() + .args([ + "--cache=testdata/derivation", + &format!("--op-block-no={}", op_block_no), + &format!("--op-blocks={}", op_blocks), + ]) + .assert() + .success(); +} + #[rstest] fn empty_blocks(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) { let block_no = u64::from_str(file_prefix(&path)).unwrap(); diff --git a/lib/Cargo.toml b/lib/Cargo.toml index bb7845d3..61fe1700 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -4,15 +4,17 @@ version = "0.1.0" edition = "2021" [dependencies] +alloy-sol-types = "0.4" anyhow = "1.0" ethers-core = { version = "2.0", features = ["optimism"] } hashbrown = { workspace = true } +libflate = "2.0.0" once_cell = "1.18" revm = { workspace = true } ruint = { version = "1.10", default-features = false } serde = "1.0" thiserror = "1.0" -zeth-primitives = { path = "../primitives", features = ["revm"] } +zeth-primitives = { path = "../primitives", features = ["revm", "ethers"] } [target.'cfg(not(target_os = "zkvm"))'.dependencies] chrono = { version = "0.4", default-features = false } diff --git a/lib/src/builder/execute/ethereum.rs b/lib/src/builder/execute/ethereum.rs index 86d79b74..36d11f35 100644 --- a/lib/src/builder/execute/ethereum.rs +++ b/lib/src/builder/execute/ethereum.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{fmt::Debug, mem::take}; +use core::{fmt::Debug, mem::take}; use anyhow::{anyhow, bail, Context}; #[cfg(not(target_os = "zkvm"))] diff --git a/lib/src/builder/execute/optimism.rs b/lib/src/builder/execute/optimism.rs index 7ba6abb2..a236a86b 100644 --- a/lib/src/builder/execute/optimism.rs +++ b/lib/src/builder/execute/optimism.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{fmt::Debug, mem::take, str::FromStr}; +use core::{fmt::Debug, mem::take, str::FromStr}; use anyhow::{anyhow, bail, Context, Result}; #[cfg(not(target_os = "zkvm"))] diff --git a/lib/src/consts.rs b/lib/src/consts.rs index 0bfbf408..7ec26dfe 100644 --- a/lib/src/consts.rs +++ b/lib/src/consts.rs @@ -13,9 +13,9 @@ // limitations under the License. //! Constants for the Ethereum protocol. +extern crate alloc; -use core::str::FromStr; -use std::collections::BTreeMap; +use std::{collections::BTreeMap, str::FromStr}; use anyhow::bail; use once_cell::sync::Lazy; diff --git a/lib/src/host/provider/cached_rpc_provider.rs b/lib/src/host/provider/cached_rpc_provider.rs index a6a59be3..111391d9 100644 --- a/lib/src/host/provider/cached_rpc_provider.rs +++ b/lib/src/host/provider/cached_rpc_provider.rs @@ -15,7 +15,9 @@ use std::path::PathBuf; use anyhow::Result; -use ethers_core::types::{Block, Bytes, EIP1186ProofResponse, Transaction, H256, U256}; +use ethers_core::types::{ + Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H256, U256, +}; use super::{ file_provider::FileProvider, rpc_provider::RpcProvider, AccountQuery, BlockQuery, MutProvider, @@ -29,7 +31,7 @@ pub struct CachedRpcProvider { impl CachedRpcProvider { pub fn new(cache_path: PathBuf, rpc_url: String) -> Result { - let cache = match FileProvider::read_from_file(cache_path.clone()) { + let cache = match FileProvider::from_file(&cache_path) { Ok(provider) => provider, Err(_) => FileProvider::empty(cache_path), }; @@ -68,6 +70,18 @@ impl Provider for CachedRpcProvider { Ok(out) } + fn get_block_receipts(&mut self, query: &BlockQuery) -> Result> { + let cache_out = self.cache.get_block_receipts(query); + if cache_out.is_ok() { + return cache_out; + } + + let out = self.rpc.get_block_receipts(query)?; + self.cache.insert_block_receipts(query.clone(), out.clone()); + + Ok(out) + } + fn get_proof(&mut self, query: &ProofQuery) -> Result { let cache_out = self.cache.get_proof(query); if cache_out.is_ok() { diff --git a/lib/src/host/provider/file_provider.rs b/lib/src/host/provider/file_provider.rs index dc7d411e..285bd2db 100644 --- a/lib/src/host/provider/file_provider.rs +++ b/lib/src/host/provider/file_provider.rs @@ -20,7 +20,9 @@ use std::{ }; use anyhow::{anyhow, Result}; -use ethers_core::types::{Block, Bytes, EIP1186ProofResponse, Transaction, H256, U256}; +use ethers_core::types::{ + Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H256, U256, +}; use serde::{Deserialize, Serialize}; use serde_with::serde_as; @@ -37,6 +39,9 @@ pub struct FileProvider { full_blocks: HashMap>, #[serde_as(as = "Vec<(_, _)>")] partial_blocks: HashMap>, + #[serde(default)] + #[serde_as(as = "Vec<(_, _)>")] + receipts: HashMap>, #[serde_as(as = "Vec<(_, _)>")] proofs: HashMap, #[serde_as(as = "Vec<(_, _)>")] @@ -56,6 +61,7 @@ impl FileProvider { dirty: false, full_blocks: HashMap::new(), partial_blocks: HashMap::new(), + receipts: HashMap::new(), proofs: HashMap::new(), transaction_count: HashMap::new(), balance: HashMap::new(), @@ -64,14 +70,14 @@ impl FileProvider { } } - pub fn read_from_file(file_path: PathBuf) -> Result { + pub fn from_file(file_path: &PathBuf) -> Result { let mut buf = vec![]; - let mut decoder = flate2::read::GzDecoder::new(File::open(&file_path)?); + let mut decoder = flate2::read::GzDecoder::new(File::open(file_path)?); decoder.read_to_end(&mut buf)?; let mut out: Self = serde_json::from_slice(&buf[..])?; - out.file_path = file_path; + out.file_path = file_path.clone(); out.dirty = false; Ok(out) } @@ -109,6 +115,13 @@ impl Provider for FileProvider { } } + fn get_block_receipts(&mut self, query: &BlockQuery) -> Result> { + match self.receipts.get(query) { + Some(val) => Ok(val.clone()), + None => Err(anyhow!("No data for {:?}", query)), + } + } + fn get_proof(&mut self, query: &ProofQuery) -> Result { match self.proofs.get(query) { Some(val) => Ok(val.clone()), @@ -156,6 +169,11 @@ impl MutProvider for FileProvider { self.dirty = true; } + fn insert_block_receipts(&mut self, query: BlockQuery, val: Vec) { + self.receipts.insert(query, val); + self.dirty = true; + } + fn insert_proof(&mut self, query: ProofQuery, val: EIP1186ProofResponse) { self.proofs.insert(query, val); self.dirty = true; diff --git a/lib/src/host/provider/mod.rs b/lib/src/host/provider/mod.rs index 9bc6aa29..d6203417 100644 --- a/lib/src/host/provider/mod.rs +++ b/lib/src/host/provider/mod.rs @@ -14,8 +14,10 @@ use std::{collections::BTreeSet, path::PathBuf}; -use anyhow::{anyhow, Result}; -use ethers_core::types::{Block, Bytes, EIP1186ProofResponse, Transaction, H160, H256, U256}; +use anyhow::{anyhow, Context, Result}; +use ethers_core::types::{ + Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H160, H256, U256, +}; use serde::{Deserialize, Serialize}; pub mod cached_rpc_provider; @@ -52,6 +54,7 @@ pub trait Provider: Send { fn get_full_block(&mut self, query: &BlockQuery) -> Result>; fn get_partial_block(&mut self, query: &BlockQuery) -> Result>; + fn get_block_receipts(&mut self, query: &BlockQuery) -> Result>; fn get_proof(&mut self, query: &ProofQuery) -> Result; fn get_transaction_count(&mut self, query: &AccountQuery) -> Result; fn get_balance(&mut self, query: &AccountQuery) -> Result; @@ -62,6 +65,7 @@ pub trait Provider: Send { pub trait MutProvider: Provider { fn insert_full_block(&mut self, query: BlockQuery, val: Block); fn insert_partial_block(&mut self, query: BlockQuery, val: Block); + fn insert_block_receipts(&mut self, query: BlockQuery, val: Vec); fn insert_proof(&mut self, query: ProofQuery, val: EIP1186ProofResponse); fn insert_transaction_count(&mut self, query: AccountQuery, val: U256); fn insert_balance(&mut self, query: AccountQuery, val: U256); @@ -70,7 +74,8 @@ pub trait MutProvider: Provider { } pub fn new_file_provider(file_path: PathBuf) -> Result> { - let provider = file_provider::FileProvider::read_from_file(file_path)?; + let provider = file_provider::FileProvider::from_file(&file_path) + .with_context(|| format!("invalid cache file: {}", file_path.display()))?; Ok(Box::new(provider)) } diff --git a/lib/src/host/provider/rpc_provider.rs b/lib/src/host/provider/rpc_provider.rs index fcf9df56..2644e1f2 100644 --- a/lib/src/host/provider/rpc_provider.rs +++ b/lib/src/host/provider/rpc_provider.rs @@ -13,7 +13,9 @@ // limitations under the License. use anyhow::{anyhow, Result}; -use ethers_core::types::{Block, Bytes, EIP1186ProofResponse, Transaction, H256, U256}; +use ethers_core::types::{ + Block, Bytes, EIP1186ProofResponse, Transaction, TransactionReceipt, H256, U256, +}; use ethers_providers::{Http, Middleware, RetryClient}; use log::info; @@ -68,6 +70,16 @@ impl Provider for RpcProvider { } } + fn get_block_receipts(&mut self, query: &BlockQuery) -> Result> { + info!("Querying RPC for block receipts: {:?}", query); + + let response = self + .tokio_handle + .block_on(async { self.http_client.get_block_receipts(query.block_no).await })?; + + Ok(response) + } + fn get_proof(&mut self, query: &ProofQuery) -> Result { info!("Querying RPC for inclusion proof: {:?}", query); diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 72b4d7ff..ab0bd361 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -21,6 +21,7 @@ pub mod builder; pub mod consts; pub mod input; pub mod mem_db; +pub mod optimism; pub use zeth_primitives::transactions::{ethereum::EthereumTxEssence, optimism::OptimismTxEssence}; diff --git a/lib/src/optimism/batcher.rs b/lib/src/optimism/batcher.rs new file mode 100644 index 00000000..c0eabe1a --- /dev/null +++ b/lib/src/optimism/batcher.rs @@ -0,0 +1,458 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::cmp::Ordering; +use std::{ + cmp::Reverse, + collections::{BinaryHeap, VecDeque}, +}; + +use anyhow::{ensure, Context, Result}; +use zeth_primitives::{ + batch::Batch, + transactions::{ + ethereum::EthereumTxEssence, + optimism::{OptimismTxEssence, OPTIMISM_DEPOSITED_TX_TYPE}, + Transaction, + }, + BlockHash, BlockNumber, B256, U256, +}; + +use super::{ + batcher_channel::BatcherChannels, batcher_db::BlockInput, config::ChainConfig, deposits, +}; + +#[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] +pub struct BlockInfo { + pub hash: B256, + pub timestamp: u64, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct Epoch { + pub number: BlockNumber, + pub hash: B256, + pub timestamp: u64, + pub base_fee_per_gas: U256, + pub deposits: Vec>, +} + +#[derive(Debug, Clone, Default)] +pub struct State { + pub current_l1_block_number: BlockNumber, + pub current_l1_block_hash: BlockHash, + pub safe_head: BlockInfo, + pub epoch: Epoch, + pub op_epoch_queue: VecDeque, + pub next_epoch: Option, +} + +impl State { + pub fn new( + current_l1_block_number: BlockNumber, + current_l1_block_hash: BlockHash, + safe_head: BlockInfo, + epoch: Epoch, + ) -> Self { + State { + current_l1_block_number, + current_l1_block_hash, + safe_head, + epoch, + op_epoch_queue: VecDeque::new(), + next_epoch: None, + } + } + + pub fn do_next_epoch(&mut self) -> anyhow::Result<()> { + self.epoch = self.next_epoch.take().expect("No next epoch!"); + self.deque_next_epoch_if_none()?; + Ok(()) + } + + pub fn push_epoch(&mut self, epoch: Epoch) -> anyhow::Result<()> { + self.op_epoch_queue.push_back(epoch); + self.deque_next_epoch_if_none()?; + Ok(()) + } + + fn deque_next_epoch_if_none(&mut self) -> anyhow::Result<()> { + if self.next_epoch.is_none() { + while let Some(next_epoch) = self.op_epoch_queue.pop_front() { + if next_epoch.number <= self.epoch.number { + continue; + } else if next_epoch.number == self.epoch.number + 1 { + self.next_epoch = Some(next_epoch); + break; + } else { + anyhow::bail!("Epoch gap!"); + } + } + } + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq)] +enum BatchStatus { + Drop, + Accept, + Undecided, + Future, +} + +pub struct Batcher { + batches: BinaryHeap>, + batcher_channel: BatcherChannels, + pub state: State, + pub config: ChainConfig, +} + +impl Batcher { + pub fn new( + config: ChainConfig, + op_head: BlockInfo, + eth_block: &BlockInput, + ) -> Result { + let eth_block_hash = eth_block.block_header.hash(); + + let batcher_channel = BatcherChannels::new(&config); + + let state = State::new( + eth_block.block_header.number, + eth_block_hash, + op_head, + Epoch { + number: eth_block.block_header.number, + hash: eth_block_hash, + timestamp: eth_block.block_header.timestamp.try_into().unwrap(), + base_fee_per_gas: eth_block.block_header.base_fee_per_gas, + deposits: deposits::extract_transactions(&config, eth_block)?, + }, + ); + + Ok(Batcher { + batches: BinaryHeap::new(), + batcher_channel, + state, + config, + }) + } + + pub fn process_l1_block(&mut self, eth_block: &BlockInput) -> Result<()> { + let eth_block_hash = eth_block.block_header.hash(); + + // Ensure block has correct parent + ensure!( + eth_block.block_header.parent_hash == self.state.current_l1_block_hash, + "Eth block has invalid parent hash" + ); + + // Update the system config. From the spec: + // "Upon traversal of the L1 block, the system configuration copy used by the L1 retrieval + // stage is updated, such that the batch-sender authentication is always accurate to the + // exact L1 block that is read by the stage" + if eth_block.receipts.is_some() { + self.config + .system_config + .update(&self.config.system_config_contract, eth_block) + .context("failed to update system config")?; + } + + // Enqueue epoch + self.state.push_epoch(Epoch { + number: eth_block.block_header.number, + hash: eth_block_hash, + timestamp: eth_block.block_header.timestamp.try_into().unwrap(), + base_fee_per_gas: eth_block.block_header.base_fee_per_gas, + deposits: deposits::extract_transactions(&self.config, eth_block)?, + })?; + + // Read frames into channels + self.batcher_channel.process_l1_transactions( + self.config.system_config.batch_sender, + eth_block.block_header.number, + ð_block.transactions, + )?; + + // Read batches + while let Some(batches) = self.batcher_channel.read_batches() { + batches.into_iter().for_each(|batch| { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "saw batch: t={}, ph={:?}, e={}", + batch.essence.timestamp, + batch.essence.parent_hash, + batch.essence.epoch_num + ); + self.batches.push(Reverse(batch)); + }); + } + + self.state.current_l1_block_number = eth_block.block_header.number; + self.state.current_l1_block_hash = eth_block_hash; + + Ok(()) + } + + pub fn read_batch(&mut self) -> Result> { + let mut out = None; + + // Grab the first accepted batch. From the spec: + // "The batches are processed in order of the inclusion on L1: if multiple batches can be + // accept-ed the first is applied. An implementation can defer future batches a later + // derivation step to reduce validation work." + while let Some(Reverse(batch)) = self.batches.pop() { + match self.batch_status(&batch) { + BatchStatus::Accept => { + out = Some(batch); + break; + } + BatchStatus::Drop => { + #[cfg(not(target_os = "zkvm"))] + log::debug!("Dropping batch"); + } + BatchStatus::Future => { + #[cfg(not(target_os = "zkvm"))] + log::debug!("Encountered future batch"); + + self.batches.push(Reverse(batch)); + break; + } + BatchStatus::Undecided => { + #[cfg(not(target_os = "zkvm"))] + log::debug!("Encountered undecided batch"); + + self.batches.push(Reverse(batch)); + break; + } + } + } + + // If there are no accepted batches, attempt to generate the default batch. From the spec: + // "If no batch can be accept-ed, and the stage has completed buffering of all batches + // that can fully be read from the L1 block at height epoch.number + + // sequence_window_size, and the next_epoch is available, then an empty batch can + // be derived." + if out.is_none() { + let current_l1_block = self.state.current_l1_block_number; + let safe_head = self.state.safe_head; + let current_epoch = &self.state.epoch; + let next_epoch = &self.state.next_epoch; + let seq_window_size = self.config.seq_window_size; + + if let Some(next_epoch) = next_epoch { + if current_l1_block > current_epoch.number + seq_window_size { + let next_timestamp = safe_head.timestamp + self.config.blocktime; + let epoch = if next_timestamp < next_epoch.timestamp { + // From the spec: + // "If next_timestamp < next_epoch.time: the current L1 origin is repeated, + // to preserve the L2 time invariant." + current_epoch + } else { + next_epoch + }; + + out = Some(Batch::new( + current_l1_block, + safe_head.hash, + epoch.number, + epoch.hash, + next_timestamp, + )) + } + } + } + + Ok(out) + } + + fn batch_status(&self, batch: &Batch) -> BatchStatus { + // Apply the batch status rules. The spec describes a precise order for these checks. + + let epoch = &self.state.epoch; + let next_epoch = &self.state.next_epoch; + let safe_l2_head = self.state.safe_head; + let next_timestamp = safe_l2_head.timestamp + self.config.blocktime; + + // From the spec: + // "batch.timestamp > next_timestamp -> future" + // "batch.timestamp < next_timestamp -> drop" + match batch.essence.timestamp.cmp(&next_timestamp) { + Ordering::Greater => { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Future batch: {} = batch.essence.timestamp > next_timestamp = {}", + &batch.essence.timestamp, + &next_timestamp + ); + return BatchStatus::Future; + } + Ordering::Less => { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Batch too old: {} = batch.essence.timestamp < next_timestamp = {}", + &batch.essence.timestamp, + &next_timestamp + ); + return BatchStatus::Drop; + } + Ordering::Equal => (), + } + + // From the spec: + // "batch.parent_hash != safe_l2_head.hash -> drop" + if batch.essence.parent_hash != safe_l2_head.hash { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Incorrect parent hash: {} != {}", + batch.essence.parent_hash, + safe_l2_head.hash + ); + return BatchStatus::Drop; + } + + // From the spec: + // "batch.epoch_num + sequence_window_size < inclusion_block_number -> drop" + if batch.essence.epoch_num + self.config.seq_window_size < batch.inclusion_block_number { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Batch is not timely: {} + {} < {}", + batch.essence.epoch_num, + self.config.seq_window_size, + batch.inclusion_block_number + ); + return BatchStatus::Drop; + } + + // From the spec: + // "batch.epoch_num < epoch.number -> drop" + if batch.essence.epoch_num < epoch.number { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Batch epoch number is too low: {} < {}", + batch.essence.epoch_num, + epoch.number + ); + return BatchStatus::Drop; + } + + let batch_origin = if batch.essence.epoch_num == epoch.number { + // From the spec: + // "batch.epoch_num == epoch.number: define batch_origin as epoch" + epoch + } else if batch.essence.epoch_num == epoch.number + 1 { + // From the spec: + // "batch.epoch_num == epoch.number+1:" + // " If known, then define batch_origin as next_epoch" + // " If next_epoch is not known -> undecided" + match next_epoch { + Some(epoch) => epoch, + None => return BatchStatus::Undecided, + } + } else { + // From the spec: + // "batch.epoch_num > epoch.number+1 -> drop" + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Batch epoch number is too large: {} > {}", + batch.essence.epoch_num, + epoch.number + 1 + ); + return BatchStatus::Drop; + }; + + // From the spec: + // "batch.epoch_hash != batch_origin.hash -> drop" + if batch.essence.epoch_hash != batch_origin.hash { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Epoch hash mismatch: {} != {}", + batch.essence.epoch_hash, + batch_origin.hash + ); + return BatchStatus::Drop; + } + + // From the spec: + // "batch.timestamp < batch_origin.time -> drop" + if batch.essence.timestamp < batch_origin.timestamp { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Batch violates timestamp rule: {} < {}", + batch.essence.timestamp, + batch_origin.timestamp + ); + return BatchStatus::Drop; + } + + // From the spec: + // "batch.timestamp > batch_origin.time + max_sequencer_drift: enforce the L2 timestamp + // drift rule, but with exceptions to preserve above min L2 timestamp invariant:" + if batch.essence.timestamp > batch_origin.timestamp + self.config.max_seq_drift { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "Sequencer drift detected: {} > {} + {}", + batch.essence.timestamp, + batch_origin.timestamp, + self.config.max_seq_drift + ); + + // From the spec: + // "len(batch.transactions) > 0: -> drop" + if !batch.essence.transactions.is_empty() { + #[cfg(not(target_os = "zkvm"))] + log::debug!("Sequencer drift detected for non-empty batch; drop."); + return BatchStatus::Drop; + } + + // From the spec: + // "len(batch.transactions) == 0:" + // epoch.number == batch.epoch_num: this implies the batch does not already + // advance the L1 origin, and must thus be checked against next_epoch." + if epoch.number == batch.essence.epoch_num { + if let Some(next_epoch) = next_epoch { + // From the spec: + // "If batch.timestamp >= next_epoch.time -> drop" + if batch.essence.timestamp >= next_epoch.timestamp { + #[cfg(not(target_os = "zkvm"))] + log::debug!("Sequencer drift detected; drop; batch timestamp is too far into the future. {} >= {}", batch.essence.timestamp, next_epoch.timestamp); + return BatchStatus::Drop; + } + } else { + // From the spec: + // "If next_epoch is not known -> undecided" + #[cfg(not(target_os = "zkvm"))] + log::debug!("Sequencer drift detected, but next epoch is not known; undecided"); + return BatchStatus::Undecided; + } + } + } + + // From the spec: + // "batch.transactions: drop if the batch.transactions list contains a transaction that is + // invalid or derived by other means exclusively: + // any transaction that is empty (zero length byte string) + // any deposited transactions (identified by the transaction type prefix byte)" + for tx in &batch.essence.transactions { + if matches!(tx.first(), None | Some(&OPTIMISM_DEPOSITED_TX_TYPE)) { + #[cfg(not(target_os = "zkvm"))] + log::debug!("Batch contains empty or invalid transaction"); + return BatchStatus::Drop; + } + } + + BatchStatus::Accept + } +} diff --git a/lib/src/optimism/batcher_channel.rs b/lib/src/optimism/batcher_channel.rs new file mode 100644 index 00000000..da11e705 --- /dev/null +++ b/lib/src/optimism/batcher_channel.rs @@ -0,0 +1,328 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::{collections::VecDeque, io::Read}; + +use anyhow::{ensure, Context, Result}; +use libflate::zlib::Decoder; +use zeth_primitives::{ + batch::Batch, + rlp::{Decodable, Header}, + transactions::{ethereum::EthereumTxEssence, Transaction, TxEssence}, + Address, BlockNumber, +}; + +use super::config::ChainConfig; + +pub const MAX_RLP_BYTES_PER_CHANNEL: u64 = 10_000_000; + +pub struct BatcherChannels { + batch_inbox: Address, + max_channel_bank_size: u64, + channel_timeout: u64, + channels: VecDeque, + batches: VecDeque>, +} + +impl BatcherChannels { + pub fn new(config: &ChainConfig) -> Self { + Self { + batch_inbox: config.batch_inbox, + max_channel_bank_size: config.max_channel_bank_size, + channel_timeout: config.channel_timeout, + channels: VecDeque::new(), + batches: VecDeque::new(), + } + } + + pub fn process_l1_transactions( + &mut self, + batch_sender: Address, + block_number: BlockNumber, + transactions: &Vec>, + ) -> anyhow::Result<()> { + for tx in transactions { + // From the spec: + // "The receiver must be the configured batcher inbox address." + if tx.essence.to() != Some(self.batch_inbox) { + continue; + } + // From the spec: + // "The sender must match the batcher address loaded from the system config matching + // the L1 block of the data." + if tx.recover_from()? != batch_sender { + continue; + } + + for frame in Frame::process_l1_transaction(&tx.essence)? { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "received frame: channel_id: {}, frame_number: {}, is_last: {}", + frame.channel_id, + frame.frame_number, + frame.is_last + ); + + let frame_channel_id = frame.channel_id; + + // Send the frame to its corresponding channel + { + if let Some(channel_index) = self.channel_index(frame_channel_id) { + let channel = &mut self.channels[channel_index]; + + // Enforce channel_timeout + if block_number > channel.open_l1_block + self.channel_timeout { + // Remove the channel. From the spec: + // "New frames for timed-out channels are dropped instead of buffered." + self.channels.remove(channel_index); + } else { + // Add frame to channel + channel.process_frame(frame); + } + } else { + // Create new channel. From the spec: + // "When a channel ID referenced by a frame is not already present in the + // Channel Bank, a new channel is opened, tagged with the current L1 + // block, and appended to the channel-queue" + self.channels.push_back(Channel::new(block_number, frame)); + } + } + + // Enforce max_channel_bank_size. From the spec: + // "After successfully inserting a new frame, the ChannelBank is pruned: channels + // are dropped in FIFO order, until total_size <= MAX_CHANNEL_BANK_SIZE." + { + while self.total_frame_data_len() as u64 > self.max_channel_bank_size { + let _dropped_channel = self.channels.pop_front().unwrap(); + + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "dropped channel: {} (frames_data_len: {})", + _dropped_channel.id, + _dropped_channel.frames_data_len + ); + } + } + + // Decode batches from channel (if ready) + if let Some(channel_index) = self.channel_index(frame_channel_id) { + if self.channels[channel_index].is_ready() { + let channel = self.channels.remove(channel_index).unwrap(); + + #[cfg(not(target_os = "zkvm"))] + log::debug!("received channel: {}", channel.id); + + self.batches.push_back(channel.read_batches(block_number)?); + } + } + } + } + + Ok(()) + } + + pub fn read_batches(&mut self) -> Option> { + self.batches.pop_front() + } + + fn total_frame_data_len(&self) -> usize { + let mut out = 0; + for channel in &self.channels { + out += channel.frames_data_len; + } + out + } + + fn channel_index(&self, channel_id: u128) -> Option { + self.channels.iter().position(|c| c.id == channel_id) + } +} + +#[derive(Debug)] +struct Channel { + id: u128, + open_l1_block: u64, + // From the spec: + // "the sum of all buffered frame data of the channel, with an additional frame-overhead of + // 200 bytes per frame." + frames_data_len: usize, + frames: Vec, + expected_frames_len: Option, +} + +impl Channel { + const FRAME_OVERHEAD: usize = 200; + + fn new(open_l1_block: u64, frame: Frame) -> Self { + let expected_frames_len = if frame.is_last { + Some(frame.frame_number as usize + 1) + } else { + None + }; + + Self { + id: frame.channel_id, + open_l1_block, + frames_data_len: Self::FRAME_OVERHEAD + frame.frame_data.len(), + frames: vec![frame], + expected_frames_len, + } + } + + fn contains(&self, frame_number: u16) -> bool { + self.frames + .iter() + .any(|existing_frame| existing_frame.frame_number == frame_number) + } + + fn process_frame(&mut self, frame: Frame) { + // From the spec: + // "Duplicate frames (by frame number) for frames that have not been pruned from the + // channel-bank are dropped." + if self.contains(frame.frame_number) { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "channel {} dropping duplicate frame {}", + self.id, + frame.frame_number + ); + + return; + } + + // From the spec: + // "Duplicate closes (new frame is_last == 1, but the channel has already seen a closing + // frame and has not yet been pruned from the channel-bank) are dropped." + if frame.is_last { + if self.expected_frames_len.is_some() { + #[cfg(not(target_os = "zkvm"))] + log::debug!( + "channel {} dropping duplicate close-frame {}", + self.id, + frame.frame_number + ); + + return; + } + self.expected_frames_len = Some(frame.frame_number as usize + 1); + } + + self.frames_data_len += Self::FRAME_OVERHEAD + frame.frame_data.len(); + self.frames.push(frame); + } + + fn read_batches(&self, l1_block_number: BlockNumber) -> Result> { + let decompressed = self.decompress()?; + let mut channel_data = decompressed.as_slice(); + let mut batches = Vec::new(); + + while !channel_data.is_empty() { + let batch_data = Header::decode_bytes(&mut channel_data, false) + .context("failed to decode batch data")?; + + let mut batch = Batch::decode(&mut &batch_data[..])?; + batch.inclusion_block_number = l1_block_number; + + batches.push(batch); + } + + Ok(batches) + } + + fn is_ready(&self) -> bool { + self.expected_frames_len == Some(self.frames.len()) + } + + fn decompress(&self) -> Result> { + let compressed = { + let mut buf = Vec::new(); + + let mut sorted_frames: Vec<&Frame> = self.frames.iter().collect(); + sorted_frames.sort_by_key(|f| f.frame_number); + + for frame in sorted_frames { + buf.extend(&frame.frame_data) + } + + buf + }; + + // From the spec: + // "When decompressing a channel, we limit the amount of decompressed data to + // MAX_RLP_BYTES_PER_CHANNEL (currently 10,000,000 bytes), in order to avoid "zip-bomb" + // types of attack (where a small compressed input decompresses to a humongous amount + // of data). If the decompressed data exceeds the limit, things proceeds as though the + // channel contained only the first MAX_RLP_BYTES_PER_CHANNEL decompressed bytes." + let mut decompressed = Vec::new(); + Decoder::new(compressed.as_slice())? + .take(MAX_RLP_BYTES_PER_CHANNEL) + .read_to_end(&mut decompressed) + .context("failed to decompress")?; + + Ok(decompressed) + } +} + +#[derive(Debug, Default, Clone)] +struct Frame { + pub channel_id: u128, + pub frame_number: u16, + pub frame_data: Vec, + pub is_last: bool, +} + +impl Frame { + const HEADER_SIZE: usize = 22; + + pub fn process_l1_transaction(tx_essence: &EthereumTxEssence) -> Result> { + let (version, mut frame_data) = tx_essence.data().split_first().context("invalid data")?; + ensure!(version == &0, "Invalid version: {}", version); + + let mut frames = Vec::new(); + while !frame_data.is_empty() { + let frame = Frame::parse(frame_data)?; + frame_data = { + let bytes_read = Self::HEADER_SIZE + frame.frame_data.len() + 1; + &frame_data[bytes_read..] + }; + frames.push(frame); + } + + Ok(frames) + } + + fn parse(data: &[u8]) -> Result { + ensure!(Self::HEADER_SIZE < data.len(), "Insufficient frame data"); + + let channel_id = u128::from_be_bytes(data[0..16].try_into()?); + let frame_number = u16::from_be_bytes(data[16..18].try_into()?); + let frame_data_len = u32::from_be_bytes(data[18..22].try_into()?); + + let frame_data_end = Self::HEADER_SIZE + frame_data_len as usize; + ensure!(frame_data_end <= data.len(), "frame_data_end too large"); + ensure!(data[frame_data_end] <= 1, "Invalid byte at frame_data_end"); + + let frame_data = data[22..frame_data_end].to_vec(); + let is_last = data[frame_data_end] != 0; + + let frame = Self { + channel_id, + frame_number, + frame_data, + is_last, + }; + + Ok(frame) + } +} diff --git a/lib/src/optimism/batcher_db.rs b/lib/src/optimism/batcher_db.rs new file mode 100644 index 00000000..ad571310 --- /dev/null +++ b/lib/src/optimism/batcher_db.rs @@ -0,0 +1,164 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::collections::HashMap; + +use anyhow::{ensure, Result}; +use serde::{Deserialize, Serialize}; +use zeth_primitives::{ + block::Header, + receipt::Receipt, + transactions::{ + ethereum::EthereumTxEssence, optimism::OptimismTxEssence, Transaction, TxEssence, + }, + trie::MptNode, + RlpBytes, +}; + +use crate::optimism::{config::OPTIMISM_CHAIN_SPEC, deposits, system_config}; + +/// Input for extracting deposits. +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct BlockInput { + /// Header of the block. + pub block_header: Header, + /// Transactions of the block. + pub transactions: Vec>, + /// Transaction receipts of the block or `None` if not required. + pub receipts: Option>, +} + +pub trait BatcherDb { + fn get_full_op_block(&mut self, block_no: u64) -> Result>; + fn get_op_block_header(&mut self, block_no: u64) -> Result
; + fn get_full_eth_block(&mut self, block_no: u64) -> Result>; + fn get_eth_block_header(&mut self, block_no: u64) -> Result
; +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct MemDb { + pub full_op_block: HashMap>, + pub op_block_header: HashMap, + pub full_eth_block: HashMap>, + pub eth_block_header: HashMap, +} + +impl MemDb { + pub fn new() -> Self { + MemDb { + full_op_block: HashMap::new(), + op_block_header: HashMap::new(), + full_eth_block: HashMap::new(), + eth_block_header: HashMap::new(), + } + } +} + +impl Default for MemDb { + fn default() -> Self { + Self::new() + } +} + +impl BatcherDb for MemDb { + fn get_full_op_block(&mut self, block_no: u64) -> Result> { + let op_block = self.full_op_block.remove(&block_no).unwrap(); + assert_eq!(block_no, op_block.block_header.number); + + // Validate tx list + { + let mut tx_trie = MptNode::default(); + for (tx_no, tx) in op_block.transactions.iter().enumerate() { + let trie_key = tx_no.to_rlp(); + tx_trie.insert_rlp(&trie_key, tx)?; + } + ensure!( + tx_trie.hash() == op_block.block_header.transactions_root, + "Invalid op block transaction data!" + ); + } + + // Validate receipts + ensure!( + op_block.receipts.is_none(), + "Op blocks should not contain receipts" + ); + + Ok(op_block) + } + + fn get_op_block_header(&mut self, block_no: u64) -> Result
{ + let op_block = self.op_block_header.remove(&block_no).unwrap(); + assert_eq!(block_no, op_block.number); + + Ok(op_block) + } + + fn get_full_eth_block(&mut self, block_no: u64) -> Result> { + let eth_block = self.full_eth_block.remove(&block_no).unwrap(); + assert_eq!(block_no, eth_block.block_header.number); + + // Validate tx list + { + let mut tx_trie = MptNode::default(); + for (tx_no, tx) in eth_block.transactions.iter().enumerate() { + let trie_key = tx_no.to_rlp(); + tx_trie.insert_rlp(&trie_key, tx)?; + } + ensure!( + tx_trie.hash() == eth_block.block_header.transactions_root, + "Invalid eth block transaction data!" + ); + } + + // Validate receipts + if eth_block.receipts.is_some() { + let mut receipt_trie = MptNode::default(); + for (tx_no, receipt) in eth_block.receipts.as_ref().unwrap().iter().enumerate() { + let trie_key = tx_no.to_rlp(); + receipt_trie.insert_rlp(&trie_key, receipt)?; + } + ensure!( + receipt_trie.hash() == eth_block.block_header.receipts_root, + "Invalid eth block receipt data!" + ); + } else { + let can_contain_deposits = deposits::can_contain( + &OPTIMISM_CHAIN_SPEC.deposit_contract, + ð_block.block_header.logs_bloom, + ); + let can_contain_config = system_config::can_contain( + &OPTIMISM_CHAIN_SPEC.system_config_contract, + ð_block.block_header.logs_bloom, + ); + ensure!( + !can_contain_deposits, + "Eth block has no receipts, but bloom filter indicates it has deposits" + ); + ensure!( + !can_contain_config, + "Eth block has no receipts, but bloom filter indicates it has config updates" + ); + } + + Ok(eth_block) + } + + fn get_eth_block_header(&mut self, block_no: u64) -> Result
{ + let eth_block = self.eth_block_header.remove(&block_no).unwrap(); + assert_eq!(block_no, eth_block.number); + + Ok(eth_block) + } +} diff --git a/lib/src/optimism/config.rs b/lib/src/optimism/config.rs new file mode 100644 index 00000000..16ec5bdc --- /dev/null +++ b/lib/src/optimism/config.rs @@ -0,0 +1,72 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use ruint::uint; +use serde::{Deserialize, Serialize}; +use zeth_primitives::{address, Address}; + +use super::system_config::SystemConfig; + +/// A Chain Configuration +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ChainConfig { + /// The initial system config value + pub system_config: SystemConfig, + // The L1 attributes depositor address + pub l1_attributes_depositor: Address, + /// The L1 attributes contract + pub l1_attributes_contract: Address, + /// The batch inbox address + pub batch_inbox: Address, + /// The deposit contract address + pub deposit_contract: Address, + /// The L1 system config contract + pub system_config_contract: Address, + /// The maximum byte size of all pending channels + pub max_channel_bank_size: u64, + /// The max timeout for a channel (as measured by the frame L1 block number) + pub channel_timeout: u64, + /// Number of L1 blocks in a sequence window + pub seq_window_size: u64, + /// Maximum timestamp drift + pub max_seq_drift: u64, + /// Network blocktime + pub blocktime: u64, +} + +impl ChainConfig { + pub const fn optimism() -> Self { + Self { + system_config: SystemConfig { + batch_sender: address!("6887246668a3b87f54deb3b94ba47a6f63f32985"), + gas_limit: uint!(30_000_000_U256), + l1_fee_overhead: uint!(188_U256), + l1_fee_scalar: uint!(684000_U256), + unsafe_block_signer: address!("AAAA45d9549EDA09E70937013520214382Ffc4A2"), + }, + l1_attributes_depositor: address!("deaddeaddeaddeaddeaddeaddeaddeaddead0001"), + l1_attributes_contract: address!("4200000000000000000000000000000000000015"), + batch_inbox: address!("ff00000000000000000000000000000000000010"), + deposit_contract: address!("bEb5Fc579115071764c7423A4f12eDde41f106Ed"), + system_config_contract: address!("229047fed2591dbec1eF1118d64F7aF3dB9EB290"), + max_channel_bank_size: 100_000_000, + channel_timeout: 300, + seq_window_size: 3600, + max_seq_drift: 600, + blocktime: 2, + } + } +} + +pub const OPTIMISM_CHAIN_SPEC: ChainConfig = ChainConfig::optimism(); diff --git a/lib/src/optimism/deposits.rs b/lib/src/optimism/deposits.rs new file mode 100644 index 00000000..76804f72 --- /dev/null +++ b/lib/src/optimism/deposits.rs @@ -0,0 +1,153 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use alloy_sol_types::{sol_data, SolType}; +use anyhow::{ensure, Context}; +use zeth_primitives::{ + fixed_bytes, keccak256, + receipt::Log, + transactions::{ + ethereum::{EthereumTxEssence, TransactionKind}, + optimism::{OptimismTxEssence, TxEssenceOptimismDeposited}, + Transaction, + }, + Address, Bloom, BloomInput, B256, U160, U256, +}; + +use super::{batcher_db::BlockInput, config::ChainConfig}; + +/// Signature of the deposit transaction event, i.e. +/// keccak-256 hash of "TransactionDeposited(address,address,uint256,bytes)" +const TRANSACTION_DEPOSITED_SIGNATURE: B256 = + fixed_bytes!("b3813568d9991fc951961fcb4c784893574240a28925604d09fc577c55bb7c32"); +/// Version of the deposit transaction event. +const TRANSACTION_DEPOSITED_VERSION: B256 = B256::ZERO; + +/// Extracts deposits from the given block. +pub fn extract_transactions( + config: &ChainConfig, + input: &BlockInput, +) -> anyhow::Result>> { + let block_hash = input.block_header.hash(); + + // if the bloom filter does not contain the corresponding topics, we have the guarantee + // that there are no deposits in the block + if !can_contain(&config.deposit_contract, &input.block_header.logs_bloom) { + return Ok(vec![]); + } + + let receipts = input.receipts.as_ref().context("receipts missing")?; + + let mut deposits = Vec::new(); + + let mut log_index = 0_usize; + for receipt in receipts { + let receipt = &receipt.payload; + + // skip failed transactions + if !receipt.success { + log_index += receipt.logs.len(); + continue; + } + // we could skip the transaction if the Bloom filter does not contain the deposit log, but + // since hashing is quite expensive on the guest, it seems faster to always check the + // logs + + // parse all the logs for deposit transactions + for log in &receipt.logs { + if log.address == config.deposit_contract + && log.topics[0] == TRANSACTION_DEPOSITED_SIGNATURE + { + deposits.push( + to_deposit_transaction(block_hash, log_index, log) + .context("invalid deposit")?, + ); + } + + log_index += 1; + } + } + + Ok(deposits) +} + +/// Returns whether the given Bloom filter can contain a deposit log. +pub fn can_contain(address: &Address, bloom: &Bloom) -> bool { + let input = BloomInput::Raw(address.as_slice()); + if !bloom.contains_input(input) { + return false; + } + let input = BloomInput::Raw(TRANSACTION_DEPOSITED_SIGNATURE.as_slice()); + if !bloom.contains_input(input) { + return false; + } + true +} + +/// Converts a deposit log into a transaction. +fn to_deposit_transaction( + block_hash: B256, + log_index: usize, + log: &Log, +) -> anyhow::Result> { + let from = U160::try_from_be_slice(&log.topics[1][12..]) + .context("invalid from")? + .into(); + let to = U160::try_from_be_slice(&log.topics[2][12..]) + .context("invalid to")? + .into(); + + // TODO: it is not 100% defined, what happens if the version is not 0 + // it is assumed that this is an error and must not be ignored + ensure!( + log.topics[3] == TRANSACTION_DEPOSITED_VERSION, + "invalid version" + ); + + // the log data is just an ABI encoded `bytes` type representing the opaque_data + let opaque_data: Vec = + sol_data::Bytes::abi_decode(&log.data, true).context("invalid data")?; + + ensure!(opaque_data.len() >= 73, "invalid opaque_data"); + let mint = U256::try_from_be_slice(&opaque_data[0..32]).context("invalid mint")?; + let value = U256::try_from_be_slice(&opaque_data[32..64]).context("invalid value")?; + let gas_limit = U256::try_from_be_slice(&opaque_data[64..72]).context("invalid gas_limit")?; + let is_creation = opaque_data[72] != 0; + let data = opaque_data[73..].to_vec(); + + // compute the source hash + let h = keccak256([block_hash.0, U256::from(log_index).to_be_bytes()].concat()); + let source_hash = keccak256([U256::from(0).to_be_bytes(), h.0].concat()); + + // construct the transaction + let essence = OptimismTxEssence::OptimismDeposited(TxEssenceOptimismDeposited { + source_hash, + from, + to: if is_creation { + TransactionKind::Create + } else { + TransactionKind::Call(to) + }, + mint, + value, + gas_limit, + is_system_tx: false, + data: data.into(), + }); + + Ok(Transaction { + essence, + signature: Default::default(), + }) +} diff --git a/lib/src/optimism/mod.rs b/lib/src/optimism/mod.rs new file mode 100644 index 00000000..51894e71 --- /dev/null +++ b/lib/src/optimism/mod.rs @@ -0,0 +1,383 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use core::iter::once; + +use alloy_sol_types::{sol, SolInterface}; +use anyhow::{bail, ensure, Context, Result}; +#[cfg(not(target_os = "zkvm"))] +use log::info; +use serde::{Deserialize, Serialize}; +use zeth_primitives::{ + batch::Batch, + keccak::keccak, + transactions::{ + ethereum::TransactionKind, + optimism::{OptimismTxEssence, TxEssenceOptimismDeposited}, + Transaction, TxEssence, + }, + trie::MptNode, + uint, Address, BlockHash, BlockNumber, FixedBytes, RlpBytes, B256, U256, +}; + +use crate::{ + consts::ONE, + optimism::{ + batcher::{Batcher, BlockInfo}, + batcher_db::BatcherDb, + config::ChainConfig, + }, +}; + +pub mod batcher; +pub mod batcher_channel; +pub mod batcher_db; +pub mod config; +pub mod deposits; +pub mod system_config; + +sol! { + /// The values stored by the L1 Attributes Predeployed Contract. + #[derive(Debug)] + interface OpSystemInfo { + function setL1BlockValues( + /// L1 block attributes. + uint64 number, + uint64 timestamp, + uint256 basefee, + bytes32 hash, + /// Sequence number in the current epoch. + uint64 sequence_number, + /// A versioned hash of the current authorized batcher sender. + bytes32 batcher_hash, + /// The L1 fee overhead to apply to L1 cost computation of transactions. + uint256 l1_fee_overhead, + /// The L1 fee scalar to apply to L1 cost computation of transactions. + uint256 l1_fee_scalar + ); + } +} + +/// Represents the input for the derivation process. +#[derive(Debug, Clone, Deserialize, Serialize)] +pub struct DeriveInput { + /// Database containing the blocks. + pub db: D, + /// Block number of the L2 head. + pub op_head_block_no: u64, + /// Block count for the operation. + pub op_derive_block_count: u64, +} + +/// Represents the output of the derivation process. +#[derive(Debug, Clone, Deserialize, Eq, PartialEq, Serialize)] +pub struct DeriveOutput { + /// Ethereum tail block. + pub eth_tail: (BlockNumber, BlockHash), + /// Optimism head block. + pub op_head: (BlockNumber, BlockHash), + /// Derived Optimism blocks. + pub derived_op_blocks: Vec<(BlockNumber, BlockHash)>, +} + +/// Implementation of the actual derivation process. +pub struct DeriveMachine { + /// Input for the derivation process. + pub derive_input: DeriveInput, + + op_head_block_hash: BlockHash, + op_block_no: u64, + op_block_seq_no: u64, + op_batcher: Batcher, +} + +impl DeriveMachine { + /// Creates a new instance of DeriveMachine. + pub fn new(chain_config: &ChainConfig, mut derive_input: DeriveInput) -> Result { + let op_block_no = derive_input.op_head_block_no; + + // read system config from op_head (seq_no/epoch_no..etc) + let op_head = derive_input.db.get_full_op_block(op_block_no)?; + let op_head_block_hash = op_head.block_header.hash(); + + #[cfg(not(target_os = "zkvm"))] + info!( + "Fetched Op head (block no {}) {}", + op_block_no, op_head_block_hash + ); + + // the first transaction in a block MUST be a L1 attributes deposited transaction + let l1_attributes_tx = &op_head + .transactions + .first() + .context("block is empty")? + .essence; + if let Err(err) = validate_l1_attributes_deposited_tx(chain_config, l1_attributes_tx) { + bail!( + "First transaction in block is not a valid L1 attributes deposited transaction: {}", + err + ) + } + // decode the L1 attributes deposited transaction + let set_l1_block_values = { + let call = OpSystemInfo::OpSystemInfoCalls::abi_decode(l1_attributes_tx.data(), true) + .context("invalid L1 attributes data")?; + match call { + OpSystemInfo::OpSystemInfoCalls::setL1BlockValues(x) => x, + } + }; + + let op_block_seq_no = set_l1_block_values.sequence_number; + + // check that the correct L1 block is in the database + let eth_block_no = set_l1_block_values.number; + let eth_head = derive_input.db.get_full_eth_block(eth_block_no)?; + ensure!( + eth_head.block_header.hash() == set_l1_block_values.hash, + "Ethereum head block hash mismatch" + ); + #[cfg(not(target_os = "zkvm"))] + info!( + "Fetched Eth head (block no {}) {}", + eth_block_no, set_l1_block_values.hash + ); + + let op_batcher = { + // copy the chain config and update the system config + let mut op_chain_config = chain_config.clone(); + op_chain_config.system_config.batch_sender = + Address::from_slice(&set_l1_block_values.batcher_hash.as_slice()[12..]); + op_chain_config.system_config.l1_fee_overhead = set_l1_block_values.l1_fee_overhead; + op_chain_config.system_config.l1_fee_scalar = set_l1_block_values.l1_fee_scalar; + + Batcher::new( + op_chain_config, + BlockInfo { + hash: op_head_block_hash, + timestamp: op_head.block_header.timestamp.try_into().unwrap(), + }, + ð_head, + )? + }; + + Ok(DeriveMachine { + derive_input, + op_head_block_hash, + op_block_no, + op_block_seq_no, + op_batcher, + }) + } + + pub fn derive(&mut self) -> Result { + let target_block_no = + self.derive_input.op_head_block_no + self.derive_input.op_derive_block_count; + + let mut derived_op_blocks = Vec::new(); + let mut process_next_eth_block = false; + + while self.op_block_no < target_block_no { + #[cfg(not(target_os = "zkvm"))] + info!( + "op_block_no = {}, eth_block_no = {}", + self.op_block_no, self.op_batcher.state.current_l1_block_number + ); + + // Process next Eth block. We do this on every iteration, except the first iteration. + // (The first iteration is handled by Batcher::new().) + if process_next_eth_block { + let eth_block = self + .derive_input + .db + .get_full_eth_block(self.op_batcher.state.current_l1_block_number + 1) + .context("block not found")?; + + self.op_batcher + .process_l1_block(ð_block) + .context("failed to create batcher transactions")?; + } + process_next_eth_block = true; + + // Process batches + while let Some(op_batch) = self.op_batcher.read_batch()? { + // Process the batch + self.op_block_no += 1; + + #[cfg(not(target_os = "zkvm"))] + info!( + "Read batch for Op block {}: timestamp={}, epoch={}, tx count={}, parent hash={:?}", + self.op_block_no, + op_batch.essence.timestamp, + op_batch.essence.epoch_num, + op_batch.essence.transactions.len(), + op_batch.essence.parent_hash, + ); + + // Update sequence number (and fetch deposits if start of new epoch) + let deposits = + if op_batch.essence.epoch_num == self.op_batcher.state.epoch.number + 1 { + self.op_block_seq_no = 0; + self.op_batcher.state.do_next_epoch()?; + + self.op_batcher + .state + .epoch + .deposits + .iter() + .map(|tx| tx.to_rlp()) + .collect() + } else { + self.op_block_seq_no += 1; + + Vec::new() + }; + + // Obtain new Op head + let new_op_head = { + let new_op_head = self + .derive_input + .db + .get_op_block_header(self.op_block_no) + .context("block not found")?; + + // Verify new op head has the expected parent + assert_eq!( + new_op_head.parent_hash, + self.op_batcher.state.safe_head.hash + ); + + // Verify that the new op head transactions are consistent with the batch + // transactions + { + // From the spec: + // The first transaction MUST be a L1 attributes deposited transaction, + // followed by an array of zero-or-more user-deposited transactions. + let l1_attributes_tx = self.derive_l1_attributes_deposited_tx(&op_batch); + let derived_transactions = once(l1_attributes_tx.to_rlp()) + .chain(deposits) + .chain(op_batch.essence.transactions.iter().map(|tx| tx.to_vec())) + .enumerate(); + + let mut tx_trie = MptNode::default(); + for (tx_no, tx) in derived_transactions { + let trie_key = tx_no.to_rlp(); + tx_trie.insert(&trie_key, tx)?; + } + if tx_trie.hash() != new_op_head.transactions_root { + bail!("Invalid op block transaction data! Transaction trie root does not match") + } + } + + new_op_head + }; + + let new_op_head_hash = new_op_head.hash(); + + #[cfg(not(target_os = "zkvm"))] + info!( + "Derived Op block {} w/ hash {}", + new_op_head.number, new_op_head_hash + ); + + self.op_batcher.state.safe_head = BlockInfo { + hash: new_op_head_hash, + timestamp: new_op_head.timestamp.try_into().unwrap(), + }; + + derived_op_blocks.push((new_op_head.number, new_op_head_hash)); + + if self.op_block_no == target_block_no { + break; + } + } + } + + Ok(DeriveOutput { + eth_tail: ( + self.op_batcher.state.current_l1_block_number, + self.op_batcher.state.current_l1_block_hash, + ), + op_head: (self.derive_input.op_head_block_no, self.op_head_block_hash), + derived_op_blocks, + }) + } + + fn derive_l1_attributes_deposited_tx( + &mut self, + op_batch: &Batch, + ) -> Transaction { + let batcher_hash = { + let all_zero: FixedBytes<12> = FixedBytes::ZERO; + all_zero.concat_const::<20, 32>(self.op_batcher.config.system_config.batch_sender.0) + }; + + let set_l1_block_values = + OpSystemInfo::OpSystemInfoCalls::setL1BlockValues(OpSystemInfo::setL1BlockValuesCall { + number: self.op_batcher.state.epoch.number, + timestamp: self.op_batcher.state.epoch.timestamp, + basefee: self.op_batcher.state.epoch.base_fee_per_gas, + hash: self.op_batcher.state.epoch.hash, + sequence_number: self.op_block_seq_no, + batcher_hash, + l1_fee_overhead: self.op_batcher.config.system_config.l1_fee_overhead, + l1_fee_scalar: self.op_batcher.config.system_config.l1_fee_scalar, + }); + + let source_hash: B256 = { + let l1_block_hash = op_batch.essence.epoch_hash.0; + let seq_number = U256::from(self.op_block_seq_no).to_be_bytes::<32>(); + let source_hash_sequencing = keccak([l1_block_hash, seq_number].concat()); + keccak([ONE.to_be_bytes::<32>(), source_hash_sequencing].concat()).into() + }; + let config = &self.op_batcher.config; + + Transaction { + essence: OptimismTxEssence::OptimismDeposited(TxEssenceOptimismDeposited { + source_hash, + from: config.l1_attributes_depositor, + to: TransactionKind::Call(config.l1_attributes_contract), + mint: Default::default(), + value: Default::default(), + gas_limit: uint!(1_000_000_U256), + is_system_tx: false, + data: set_l1_block_values.abi_encode().into(), + }), + signature: Default::default(), + } + } +} + +fn validate_l1_attributes_deposited_tx(config: &ChainConfig, tx: &OptimismTxEssence) -> Result<()> { + match tx { + OptimismTxEssence::Ethereum(_) => { + bail!("No Optimism deposit transaction"); + } + OptimismTxEssence::OptimismDeposited(op) => { + ensure!( + op.from == config.l1_attributes_depositor, + "Invalid from address" + ); + ensure!( + matches!(op.to, TransactionKind::Call(addr) if addr == config.l1_attributes_contract), + "Invalid to address" + ); + ensure!(op.mint == U256::ZERO, "Invalid mint value"); + ensure!(op.value == U256::ZERO, "Invalid value"); + ensure!(op.gas_limit == uint!(1_000_000_U256), "Invalid gas limit"); + ensure!(!op.is_system_tx, "Invalid is_system_tx value"); + } + } + + Ok(()) +} diff --git a/lib/src/optimism/system_config.rs b/lib/src/optimism/system_config.rs new file mode 100644 index 00000000..d5574165 --- /dev/null +++ b/lib/src/optimism/system_config.rs @@ -0,0 +1,149 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use anyhow::{self, bail, ensure, Context, Ok}; +use serde::{Deserialize, Serialize}; +use zeth_primitives::{ + b256, transactions::ethereum::EthereumTxEssence, Address, Bloom, BloomInput, B256, U256, +}; + +use super::batcher_db::BlockInput; + +/// Signature of the deposit transaction event, i.e. +/// keccak-256 hash of "ConfigUpdate(uint256,uint8,bytes)" +const CONFIG_UPDATE_SIGNATURE: B256 = + b256!("1d2b0bda21d56b8bd12d4f94ebacffdfb35f5e226f84b461103bb8beab6353be"); +/// Version of the deposit transaction event. +const CONFIG_UPDATE_VERSION: B256 = B256::ZERO; + +/// Optimism system config contract values +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SystemConfig { + /// Batch sender address + pub batch_sender: Address, + /// L2 gas limit + pub gas_limit: U256, + /// Fee overhead + pub l1_fee_overhead: U256, + /// Fee scalar + pub l1_fee_scalar: U256, + /// Sequencer's signer for unsafe blocks + pub unsafe_block_signer: Address, +} + +impl SystemConfig { + /// Updates the system config based on the given input. Returns whether the config was + /// updated. + pub fn update( + &mut self, + system_config_contract: &Address, + input: &BlockInput, + ) -> anyhow::Result { + let mut updated = false; + + // if the bloom filter does not contain the corresponding topics, we have the guarantee + // that there are no config updates in the block + if !can_contain(system_config_contract, &input.block_header.logs_bloom) { + return Ok(updated); + } + + #[cfg(not(target_os = "zkvm"))] + log::info!("Process config"); + + let receipts = input.receipts.as_ref().context("receipts missing")?; + for receipt in receipts { + let receipt = &receipt.payload; + + // skip failed transactions + if !receipt.success { + continue; + } + + for log in &receipt.logs { + // the log event contract address must match the system config contract + // the first log event topic must match the ConfigUpdate signature + if &log.address == system_config_contract + && log.topics[0] == CONFIG_UPDATE_SIGNATURE + { + updated = true; + + // the second topic determines the version + ensure!(log.topics[1] == CONFIG_UPDATE_VERSION, "invalid version"); + + // the third topic determines the type of update + let update_type: u64 = U256::from_be_bytes(log.topics[2].0) + .try_into() + .expect("invalid update type"); + + // TODO: use proper ABI decoding of the data + match update_type { + // type 0: batcherHash overwrite, as bytes32 payload + 0 => { + let addr_bytes = log + .data + .get(76..96) + .context("invalid batch sender address")?; + + self.batch_sender = Address::from_slice(addr_bytes); + } + // type 1: overhead and scalar overwrite, as two packed uint256 entries + 1 => { + let fee_overhead = log.data.get(64..96).context("invalid data")?; + let fee_scalar = log.data.get(96..128).context("invalid data")?; + + self.l1_fee_overhead = U256::try_from_be_slice(fee_overhead) + .context("invalid overhead")?; + self.l1_fee_scalar = + U256::try_from_be_slice(fee_scalar).context("invalid scalar")?; + } + // type 2: gasLimit overwrite, as uint64 payload + 2 => { + let gas_limit = log.data.get(64..96).context("invalid data")?; + + self.gas_limit = + U256::try_from_be_slice(gas_limit).context("invalid gas limit")?; + } + // type 3: unsafeBlockSigner overwrite, as address payload + 3 => { + let addr_bytes = log + .data + .get(76..96) + .context("invalid unsafe block signer address")?; + + self.unsafe_block_signer = Address::from_slice(addr_bytes); + } + _ => { + bail!("invalid update type"); + } + } + } + } + } + + Ok(updated) + } +} + +/// Returns whether the given Bloom filter can contain a config update log. +pub fn can_contain(address: &Address, bloom: &Bloom) -> bool { + let input = BloomInput::Raw(address.as_slice()); + if !bloom.contains_input(input) { + return false; + } + let input = BloomInput::Raw(CONFIG_UPDATE_SIGNATURE.as_slice()); + if !bloom.contains_input(input) { + return false; + } + true +} diff --git a/primitives/src/batch.rs b/primitives/src/batch.rs new file mode 100644 index 00000000..3ba27114 --- /dev/null +++ b/primitives/src/batch.rs @@ -0,0 +1,99 @@ +// Copyright 2023 RISC Zero, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::cmp::Ordering; + +use alloy_primitives::{BlockNumber, Bytes, B256}; +use alloy_rlp::{Decodable, Encodable}; +use alloy_rlp_derive::{RlpDecodable, RlpEncodable}; +use bytes::Buf; + +pub type RawTransaction = Bytes; + +#[derive(Debug, Clone, Eq, PartialEq, RlpEncodable, RlpDecodable)] +pub struct BatchEssence { + pub parent_hash: B256, + pub epoch_num: u64, + pub epoch_hash: B256, + pub timestamp: u64, + pub transactions: Vec, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct Batch { + pub inclusion_block_number: BlockNumber, + pub essence: BatchEssence, +} + +impl PartialOrd for Batch { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for Batch { + fn cmp(&self, other: &Self) -> Ordering { + self.essence.timestamp.cmp(&other.essence.timestamp) + } +} + +impl Batch { + pub fn new( + inclusion_block_number: BlockNumber, + parent_hash: B256, + epoch_num: u64, + epoch_hash: B256, + timestamp: u64, + ) -> Self { + Self { + inclusion_block_number, + essence: BatchEssence { + parent_hash, + epoch_num, + epoch_hash, + timestamp, + transactions: Vec::new(), + }, + } + } +} + +impl Encodable for Batch { + #[inline] + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { + out.put_u8(0); + self.essence.encode(out); + } + + #[inline] + fn length(&self) -> usize { + self.essence.length() + 1 + } +} + +impl Decodable for Batch { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + match buf.first() { + Some(0) => { + buf.advance(1); + Ok(Self { + inclusion_block_number: 0, + essence: BatchEssence::decode(buf)?, + }) + } + Some(_) => Err(alloy_rlp::Error::Custom("invalid version")), + None => Err(alloy_rlp::Error::InputTooShort), + } + } +} diff --git a/primitives/src/ethers.rs b/primitives/src/ethers.rs index b9828532..346101ee 100644 --- a/primitives/src/ethers.rs +++ b/primitives/src/ethers.rs @@ -21,13 +21,15 @@ use ethers_core::types::{ AccessList as EthersAccessList, AccessListItem as EthersAccessListItem, }, Block as EthersBlock, Bytes as EthersBytes, EIP1186ProofResponse, - Transaction as EthersTransaction, Withdrawal as EthersWithdrawal, H160 as EthersH160, - H256 as EthersH256, U256 as EthersU256, + Transaction as EthersTransaction, TransactionReceipt as EthersReceipt, + Withdrawal as EthersWithdrawal, H160 as EthersH160, H256 as EthersH256, U256 as EthersU256, + U64, }; use crate::{ access_list::{AccessList, AccessListItem}, block::Header, + receipt::{Log, Receipt, ReceiptPayload}, transactions::{ ethereum::{ EthereumTxEssence, TransactionKind, TxEssenceEip1559, TxEssenceEip2930, TxEssenceLegacy, @@ -46,6 +48,12 @@ pub fn from_ethers_u256(v: EthersU256) -> U256 { U256::from_limbs(v.0) } +/// Convert an `U256` type to the `EthersU256` type. +#[inline] +pub fn to_ethers_u256(v: U256) -> EthersU256 { + EthersU256(v.into_limbs()) +} + /// Convert an `EthersH160` type to the `Address` type. #[inline] pub fn from_ethers_h160(v: EthersH160) -> Address { @@ -257,6 +265,40 @@ impl TryFrom for Withdrawal { } } +impl TryFrom for Receipt { + type Error = anyhow::Error; + + fn try_from(receipt: EthersReceipt) -> Result { + Ok(Receipt { + tx_type: receipt + .transaction_type + .context("transaction_type missing")? + .as_u64() + .try_into() + .context("invalid transaction_type")?, + payload: ReceiptPayload { + success: receipt.status.context("status missing")? == U64::one(), + cumulative_gas_used: from_ethers_u256(receipt.cumulative_gas_used), + logs_bloom: Bloom::from_slice(receipt.logs_bloom.as_bytes()), + logs: receipt + .logs + .into_iter() + .map(|log| { + let address = log.address.0.into(); + let topics = log.topics.into_iter().map(from_ethers_h256).collect(); + let data = log.data.0.into(); + Log { + address, + topics, + data, + } + }) + .collect(), + }, + }) + } +} + /// Conversion from `EIP1186ProofResponse` to the local [StateAccount]. impl From for StateAccount { fn from(response: EIP1186ProofResponse) -> Self { diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index 49ad2de3..97cd1341 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -25,6 +25,7 @@ pub mod withdrawal; #[cfg(feature = "ethers")] pub mod ethers; +pub mod batch; #[cfg(feature = "revm")] pub mod revm; diff --git a/testing/ef-tests/src/ethers.rs b/testing/ef-tests/src/ethers.rs index d55908c0..df9a3e36 100644 --- a/testing/ef-tests/src/ethers.rs +++ b/testing/ef-tests/src/ethers.rs @@ -15,7 +15,8 @@ use std::collections::BTreeSet; use ethers_core::types::{ - Block, Bloom, Bytes, EIP1186ProofResponse, StorageProof, Transaction, H256, U256, + Block, Bloom, Bytes, EIP1186ProofResponse, StorageProof, Transaction, TransactionReceipt, H256, + U256, }; use zeth_primitives::U256 as LibU256; @@ -65,6 +66,13 @@ impl Provider for TestProvider { }) } + fn get_block_receipts( + &mut self, + _query: &BlockQuery, + ) -> anyhow::Result> { + unimplemented!() + } + fn get_proof(&mut self, query: &ProofQuery) -> Result { let indices = query .indices diff --git a/testing/ef-tests/testguest/Cargo.lock b/testing/ef-tests/testguest/Cargo.lock index a324b011..fb89e894 100644 --- a/testing/ef-tests/testguest/Cargo.lock +++ b/testing/ef-tests/testguest/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + [[package]] name = "ahash" version = "0.8.6" @@ -87,6 +93,35 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.39", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7e42aa2983db6676af5d762bc8d9371dd74f5948739790d3080c3d652a957b" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -564,6 +599,15 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + [[package]] name = "cpufeatures" version = "0.2.11" @@ -645,6 +689,12 @@ dependencies = [ "syn 2.0.39", ] +[[package]] +name = "dary_heap" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca" + [[package]] name = "data-encoding" version = "2.4.0" @@ -722,6 +772,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "ecdsa" version = "0.16.9" @@ -1194,6 +1250,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.2" @@ -1526,6 +1591,30 @@ version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +[[package]] +name = "libflate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf" +dependencies = [ + "adler32", + "core2", + "crc32fast", + "dary_heap", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524" +dependencies = [ + "core2", + "hashbrown 0.13.2", + "rle-decode-fast", +] + [[package]] name = "libloading" version = "0.7.4" @@ -2372,6 +2461,12 @@ dependencies = [ "libm", ] +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + [[package]] name = "rlp" version = "0.5.2" @@ -2928,6 +3023,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.39", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -3632,12 +3739,14 @@ dependencies = [ name = "zeth-lib" version = "0.1.0" dependencies = [ + "alloy-sol-types", "anyhow", "chrono", "ethers-core", "ethers-providers", "flate2", "hashbrown 0.14.2", + "libflate", "log", "once_cell", "revm",