diff --git a/Cargo.lock b/Cargo.lock index d11bcc5..5aadae3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,10 +65,11 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.36" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94c225801d42099570d0674701dddd4142f0ef715282aeb5985042e2ec962df7" +checksum = "d4932d790c723181807738cf1ac68198ab581cd699545b155601332541ee47bd" dependencies = [ + "alloy-primitives", "num_enum", "strum", ] @@ -290,7 +291,7 @@ checksum = "4d0f2d905ebd295e7effec65e5f6868d153936130ae718352771de3e7d03c75c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -374,7 +375,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -389,7 +390,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "syn-solidity", "tiny-keccak", ] @@ -404,7 +405,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "syn-solidity", ] @@ -527,9 +528,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" [[package]] name = "ark-ff" @@ -692,7 +693,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -703,7 +704,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -730,7 +731,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -881,14 +882,14 @@ checksum = "523363cbe1df49b68215efdf500b103ac3b0fb4836aed6d15689a076eadb8fff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] name = "bytemuck" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" +checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" [[package]] name = "byteorder" @@ -922,9 +923,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.28" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e80e3b6a3ab07840e1cae9b0666a63970dc28e8ed5ffbcdacbfc760c281bfc1" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "shlex", ] @@ -979,7 +980,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1062,6 +1063,24 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -1124,7 +1143,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1148,7 +1167,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1159,7 +1178,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1173,7 +1192,7 @@ dependencies = [ "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core", + "parking_lot_core 0.9.10", ] [[package]] @@ -1226,7 +1245,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1324,7 +1343,7 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1451,6 +1470,16 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "funty" version = "2.0.0" @@ -1513,7 +1542,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -1552,6 +1581,15 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" +[[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" @@ -1734,9 +1772,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" dependencies = [ "bytes", "futures-channel", @@ -1904,6 +1942,15 @@ dependencies = [ "str_stack", ] +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + [[package]] name = "ipnet" version = "2.10.1" @@ -1953,9 +2000,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb94a0ffd3f3ee755c20f7d8752f45cac88605a4dcf808abcff72873296ec7b" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -1994,9 +2041,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" @@ -2103,7 +2150,7 @@ checksum = "1bb5c1d8184f13f7d0ccbeeca0def2f9a181bce2624302793005f5ca8aa62e5e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2191,7 +2238,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2272,7 +2319,7 @@ checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2292,9 +2339,9 @@ checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -2313,7 +2360,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2324,9 +2371,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -2372,6 +2419,17 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.3" @@ -2379,7 +2437,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -2390,7 +2462,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.7", "smallvec", "windows-targets", ] @@ -2409,9 +2481,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.13" +version = "2.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" dependencies = [ "memchr", "thiserror", @@ -2435,7 +2507,7 @@ checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2496,7 +2568,7 @@ dependencies = [ "log", "nix", "once_cell", - "parking_lot", + "parking_lot 0.12.3", "smallvec", "symbolic-demangle", "tempfile", @@ -2558,9 +2630,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -2573,7 +2645,7 @@ checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", - "parking_lot", + "parking_lot 0.12.3", "prometheus-client-derive-encode", ] @@ -2585,7 +2657,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2625,7 +2697,7 @@ checksum = "ca414edb151b4c8d125c12566ab0d74dc9cdba36fb80eb7b848c15f495fd32d1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -2706,6 +2778,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.5.7" @@ -2761,9 +2842,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c1f1959e4db12c985c0283656be0925f1539549db1e47c4bd0b8b599e1ef7" +checksum = "a35e8a6bf28cd121053a66aa2e6a2e3eaffad4a60012179f0e864aa5ffeff215" dependencies = [ "bytecheck", ] @@ -2942,7 +3023,7 @@ checksum = "09cb82b74b4810f07e460852c32f522e979787691b0b7b7439fe473e49d49b2f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3029,9 +3110,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.14" +version = "0.23.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" +checksum = "5fbb44d7acc4e873d613422379f69f237a1b141928c02f6bc6ccfddddc2d7993" dependencies = [ "once_cell", "rustls-pki-types", @@ -3051,9 +3132,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -3068,9 +3149,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "rusty-fork" @@ -3263,14 +3344,14 @@ checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "indexmap 2.6.0", "itoa", @@ -3318,7 +3399,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3391,6 +3472,22 @@ dependencies = [ "autocfg", ] +[[package]] +name = "sled" +version = "0.34.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" +dependencies = [ + "crc32fast", + "crossbeam-epoch", + "crossbeam-utils", + "fs2", + "fxhash", + "libc", + "log", + "parking_lot 0.11.2", +] + [[package]] name = "smallvec" version = "1.13.2" @@ -3437,6 +3534,25 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stateful-block-verifier" +version = "2.0.0" +dependencies = [ + "alloy", + "anyhow", + "clap", + "revm", + "sbv", + "serde", + "serde_json", + "sled", + "thiserror", + "tokio", + "tokio-retry", + "tracing-subscriber", + "url", +] + [[package]] name = "stateless-block-verifier" version = "2.0.0" @@ -3494,7 +3610,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3552,9 +3668,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" dependencies = [ "proc-macro2", "quote", @@ -3569,7 +3685,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3638,7 +3754,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3740,7 +3856,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3753,6 +3869,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-retry" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f57eb36ecbe0fc510036adff84824dd3c24bb781e21bfa67b69d556aa85214f" +dependencies = [ + "pin-project", + "rand", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.26.0" @@ -3853,7 +3980,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -3977,9 +4104,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" [[package]] name = "valuable" @@ -4025,9 +4152,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef073ced962d62984fb38a36e5fdc1a2b23c9e0e1fa0689bb97afa4202ef6887" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -4036,24 +4163,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4bfab14ef75323f4eb75fa52ee0a3fb59611977fd3240da19b2cf36ff85030e" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65471f79c1022ffa5291d33520cbbb53b7687b01c2f8e83b57d102eed7ed479d" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -4063,9 +4190,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7bec9830f60924d9ceb3ef99d55c155be8afa76954edffbb5936ff4509474e7" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4073,28 +4200,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c74f6e152a76a2ad448e223b0fc0b6b5747649c3d769cc6bf45737bf97d0ed6" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.94" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42f6c679374623f295a8623adfe63d9284091245c3504bde47c17a3ce2777d9" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.71" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44188d185b5bdcae1052d08bcbcf9091a5524038d4572cc4f4f2bb9d5554ddd9" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -4279,7 +4406,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -4299,7 +4426,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.82", ] [[package]] @@ -4316,6 +4443,7 @@ dependencies = [ "poseidon-bn254", "revm-primitives", "rkyv", + "sled", "strum", "thiserror", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 6998911..3e3ea27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,9 +29,11 @@ async-channel = "2.2" clap = "4" env_logger = "0.9" futures = "0.3" +tokio-retry = "0.3" serde = "1.0" serde_json = "1.0" serde_with = "3.9" +sled = "0.34" tokio = { version = "1", default-features = false } url = "2.5" @@ -90,6 +92,7 @@ ruint = { git = "https://github.com/scroll-tech/uint.git", branch = "v1.12.3" } alloy = { git = "https://github.com/scroll-tech/alloy.git", branch = "v0.3.0" } alloy-eips = { git = "https://github.com/scroll-tech/alloy.git", branch = "v0.3.0" } +alloy-serde = { git = "https://github.com/scroll-tech/alloy.git", branch = "v0.3.0" } alloy-eip2930 = { git = "https://github.com/scroll-tech/alloy-eips", branch = "v0.1.0" } alloy-eip7702 = { git = "https://github.com/scroll-tech/alloy-eips", branch = "v0.1.0" } diff --git a/crates/bin/src/commands/run_file.rs b/crates/bin/src/commands/run_file.rs index 114ac2f..3e57abd 100644 --- a/crates/bin/src/commands/run_file.rs +++ b/crates/bin/src/commands/run_file.rs @@ -6,6 +6,7 @@ use sbv::{ core::{ChunkInfo, EvmExecutorBuilder, HardforkConfig}, primitives::{types::BlockTrace, zk_trie::db::kv::HashMapDb, Block, B256}, }; +use serde::Deserialize; use std::panic::catch_unwind; use std::{cell::RefCell, path::PathBuf}; use tiny_keccak::{Hasher, Keccak}; @@ -77,20 +78,23 @@ impl RunFileCommand { let fork_config = fork_config(traces[0].chain_id()); let (chunk_info, mut zktrie_db) = ChunkInfo::from_block_traces(&traces); + let mut code_db = HashMapDb::default(); let tx_bytes_hasher = RefCell::new(Keccak::v256()); - let mut executor = EvmExecutorBuilder::new(HashMapDb::default(), &mut zktrie_db) + let mut executor = EvmExecutorBuilder::new(&mut code_db, &mut zktrie_db) .hardfork_config(fork_config) - .with_hooks(&traces[0], |hooks| { + .chain_id(traces[0].chain_id()) + .with_hooks(traces[0].root_before(), |hooks| { hooks.add_tx_rlp_handler(|_, rlp| { tx_bytes_hasher.borrow_mut().update(rlp); }); })?; - executor.handle_block(&traces[0])?; + for trace in traces.iter() { + executor.insert_codes(trace)?; + } - for trace in traces[1..].iter() { - executor.update_db(trace)?; + for trace in traces.iter() { executor.handle_block(trace)?; } @@ -116,22 +120,27 @@ async fn read_block_trace(path: &PathBuf) -> anyhow::Result { } fn deserialize_block_trace(trace: &str) -> anyhow::Result { + let block_trace = deserialize_may_wrapped::(trace)?; + if block_trace.storage_trace.flatten_proofs.is_empty() { + dev_warn!("Storage trace is empty, try to deserialize as legacy storage trace"); + let legacy_trace = deserialize_may_wrapped::>(trace)?; + return Ok(legacy_trace.into()); + } + Ok(block_trace) +} +fn deserialize_may_wrapped<'de, T: Deserialize<'de>>(trace: &'de str) -> anyhow::Result { // Try to deserialize `BlockTrace` from JSON. In case of failure, try to // deserialize `BlockTrace` from a JSON-RPC response that has the actual block // trace nested in the value of the key "result". - Ok( - serde_json::from_str::>(trace) - .or_else(|_| { - #[derive(serde::Deserialize, Default, Debug, Clone)] - pub struct BlockTraceJsonRpcResult { - pub result: BlockTrace, - } - Ok::<_, serde_json::Error>( - serde_json::from_str::(trace)?.result, - ) - })? - .into(), - ) + Ok(serde_json::from_str::(trace).or_else(|_| { + #[derive(serde::Deserialize, Default, Debug, Clone)] + pub struct BlockTraceJsonRpcResult { + pub result: T, + } + Ok::<_, serde_json::Error>( + serde_json::from_str::>(trace)?.result, + ) + })?) } async fn run_trace( diff --git a/crates/bin/src/utils.rs b/crates/bin/src/utils.rs index 7782a80..6bc1231 100644 --- a/crates/bin/src/utils.rs +++ b/crates/bin/src/utils.rs @@ -19,6 +19,7 @@ fn verify_inner( fork_config: &HardforkConfig, ) -> Result<(), VerificationError> { dev_trace!("{l2_trace:#?}"); + let root_before = l2_trace.root_before(); let root_after = l2_trace.root_after(); // or with v2 trace @@ -47,10 +48,14 @@ fn verify_inner( }, "build ZktrieState" ); + let mut code_db = HashMapDb::default(); - let mut executor = EvmExecutorBuilder::new(HashMapDb::default(), &mut zktrie_db) + let mut executor = EvmExecutorBuilder::new(&mut code_db, &mut zktrie_db) .hardfork_config(*fork_config) - .build(&l2_trace)?; + .chain_id(l2_trace.chain_id()) + .build(root_before)?; + + executor.insert_codes(&l2_trace)?; // TODO: change to Result::inspect_err when sp1 toolchain >= 1.76 #[allow(clippy::map_identity)] diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index d0554f0..3d62b67 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -17,6 +17,8 @@ hex.workspace = true once_cell.workspace = true revm.workspace = true rkyv.workspace = true +serde.workspace = true +serde_json.workspace = true thiserror.workspace = true tiny-keccak.workspace = true diff --git a/crates/core/src/chunk.rs b/crates/core/src/chunk.rs index 0fb3578..663ce35 100644 --- a/crates/core/src/chunk.rs +++ b/crates/core/src/chunk.rs @@ -143,21 +143,24 @@ mod tests { let fork_config = HardforkConfig::default_from_chain_id(traces[0].chain_id()); let (chunk_info, mut zktrie_db) = ChunkInfo::from_block_traces(&traces); + let mut code_db = HashMapDb::default(); let tx_bytes_hasher = RefCell::new(Keccak::v256()); - let mut executor = EvmExecutorBuilder::new(HashMapDb::default(), &mut zktrie_db) + let mut executor = EvmExecutorBuilder::new(&mut code_db, &mut zktrie_db) .hardfork_config(fork_config) - .with_hooks(&traces[0], |hooks| { + .chain_id(traces[0].chain_id()) + .with_hooks(traces[0].root_before(), |hooks| { hooks.add_tx_rlp_handler(|_, rlp| { tx_bytes_hasher.borrow_mut().update(rlp); }); }) .unwrap(); - executor.handle_block(&traces[0]).unwrap(); + for trace in traces.iter() { + executor.insert_codes(trace).unwrap(); + } - for trace in traces[1..].iter() { - executor.update_db(trace).unwrap(); + for trace in traces.iter() { executor.handle_block(trace).unwrap(); } diff --git a/crates/core/src/data/genesis/genesis.mainnet.json b/crates/core/src/data/genesis/genesis.mainnet.json new file mode 100644 index 0000000..de6dfc9 --- /dev/null +++ b/crates/core/src/data/genesis/genesis.mainnet.json @@ -0,0 +1,95 @@ +{ + "config": { + "chainId": 534352, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "archimedesBlock": 0, + "shanghaiBlock": 0, + "bernoulliBlock": 5220340, + "curieBlock": 7096836, + "clique": { + "period": 3, + "epoch": 30000, + "relaxed_period": true + }, + "scroll": { + "useZktrie": true, + "maxTxPerBlock": 100, + "maxTxPayloadBytesPerBlock": 122880, + "feeVaultAddress": "0x5300000000000000000000000000000000000005", + "l1Config": { + "l1ChainId": "1", + "l1MessageQueueAddress": "0x0d7E906BD9cAFa154b048cFa766Cc1E54E39AF9B", + "scrollChainAddress": "0xa13BAF47339d63B743e7Da8741db5456DAc1E556", + "numL1MessagesPerBlock": "10" + } + } + }, + "nonce": "0x0", + "timestamp": "0x6524e860", + "extraData": "0x4c61206573746f6e7465636f206573746173206d616c6665726d6974612e0000d2ACF5d16a983DB0d909d9D761B8337Fabd6cBd10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "10000000", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0xF9062b8a30e0d7722960e305049FA50b86ba6253": { + "balance": "2000000000000000000" + }, + "0x781e90f1c8Fc4611c9b7497C3B47F99Ef6969CbC": { + "balance": "226156424291633194186662080095093570025917938800079226637565593765455331328" + }, + "0x5300000000000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c806383cc76601161006657806383cc7660146100fc5780638da5cb5b1461010f578063c4d66de814610122578063d4b9f4fa14610135578063f2fde38b1461013e57600080fd5b806326aad7b7146100985780633cb747bf146100b4578063600a2e77146100df578063715018a6146100f2575b600080fd5b6100a160015481565b6040519081526020015b60405180910390f35b6053546100c7906001600160a01b031681565b6040516001600160a01b0390911681526020016100ab565b6100a16100ed36600461054a565b610151565b6100fa6101f6565b005b6100a161010a36600461054a565b61022c565b6052546100c7906001600160a01b031681565b6100fa610130366004610563565b610243565b6100a160005481565b6100fa61014c366004610563565b6102db565b6053546000906001600160a01b031633146101a45760405162461bcd60e51b815260206004820152600e60248201526d37b7363c9036b2b9b9b2b733b2b960911b60448201526064015b60405180910390fd5b6000806101b084610367565b60408051838152602081018890529294509092507ffaa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693910160405180910390a19392505050565b6052546001600160a01b031633146102205760405162461bcd60e51b815260040161019b90610593565b61022a6000610486565b565b602a816028811061023c57600080fd5b0154905081565b6052546001600160a01b0316331461026d5760405162461bcd60e51b815260040161019b90610593565b600154156102b15760405162461bcd60e51b815260206004820152601160248201527063616e6e6f7420696e697469616c697a6560781b604482015260640161019b565b6102b96104d8565b605380546001600160a01b0319166001600160a01b0392909216919091179055565b6052546001600160a01b031633146103055760405162461bcd60e51b815260040161019b90610593565b6001600160a01b03811661035b5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161019b565b61036481610486565b50565b60035460009081906103bb5760405162461bcd60e51b815260206004820152601a60248201527f63616c6c206265666f726520696e697469616c697a6174696f6e000000000000604482015260640161019b565b6001548360005b8215610456576103d36002846105e0565b60000361041f5781602a82602881106103ee576103ee6105ca565b01556104188260028360288110610407576104076105ca565b015460009182526020526040902090565b915061044a565b610447602a8260288110610435576104356105ca565b01548360009182526020526040902090565b91505b600192831c92016103c2565b81602a826028811061046a5761046a6105ca565b0155506000819055600180548082019091559590945092505050565b605280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b60286104e8826001610618565b10156103645761051960028260288110610504576105046105ca565b015460028360288110610407576104076105ca565b6002610526836001610618565b60288110610536576105366105ca565b01558061054281610631565b9150506104db565b60006020828403121561055c57600080fd5b5035919050565b60006020828403121561057557600080fd5b81356001600160a01b038116811461058c57600080fd5b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000826105fd57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b8082018082111561062b5761062b610602565b92915050565b60006001820161064357610643610602565b506001019056fea26469706673582212208fb1cb9933bb17dd0a7c17de7c890919b08d2fd7eb2bede7b41caa32709b30b564736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000052": "0xF9062b8a30e0d7722960e305049FA50b86ba6253" + } + }, + "0x5300000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063715018a61161008c578063bede39b511610066578063bede39b51461018d578063de26c4a1146101a0578063f2fde38b146101b3578063f45e65d8146101c657600080fd5b8063715018a6146101475780638da5cb5b1461014f57806393e59dc11461017a57600080fd5b80630c18c162146100d45780633577afc5146100f05780633d0f963e1461010557806349948e0e14610118578063519b4bd31461012b5780637046559714610134575b600080fd5b6100dd60025481565b6040519081526020015b60405180910390f35b6101036100fe366004610671565b6101cf565b005b61010361011336600461068a565b610291565b6100dd6101263660046106d0565b61031c565b6100dd60015481565b610103610142366004610671565b610361565b610103610416565b600054610162906001600160a01b031681565b6040516001600160a01b0390911681526020016100e7565b600454610162906001600160a01b031681565b61010361019b366004610671565b61044c565b6100dd6101ae3660046106d0565b610533565b6101036101c136600461068a565b610595565b6100dd60035481565b6000546001600160a01b031633146102025760405162461bcd60e51b81526004016101f990610781565b60405180910390fd5b621c9c388111156102555760405162461bcd60e51b815260206004820152601760248201527f657863656564206d6178696d756d206f7665726865616400000000000000000060448201526064016101f9565b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6000546001600160a01b031633146102bb5760405162461bcd60e51b81526004016101f990610781565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f7910160405180910390a15050565b60008061032883610533565b905060006001548261033a91906107b8565b9050633b9aca006003548261034f91906107b8565b61035991906107e5565b949350505050565b6000546001600160a01b0316331461038b5760405162461bcd60e51b81526004016101f990610781565b61039b633b9aca006103e86107b8565b8111156103e15760405162461bcd60e51b8152602060048201526014602482015273657863656564206d6178696d756d207363616c6560601b60448201526064016101f9565b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a90602001610286565b6000546001600160a01b031633146104405760405162461bcd60e51b81526004016101f990610781565b61044a6000610621565b565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b99190610807565b6104fe5760405162461bcd60e51b81526020600482015260166024820152752737ba103bb434ba32b634b9ba32b21039b2b73232b960511b60448201526064016101f9565b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c4490602001610286565b80516000908190815b818110156105865784818151811061055657610556610829565b01602001516001600160f81b0319166000036105775760048301925061057e565b6010830192505b60010161053c565b50506002540160400192915050565b6000546001600160a01b031633146105bf5760405162461bcd60e51b81526004016101f990610781565b6001600160a01b0381166106155760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016101f9565b61061e81610621565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561068357600080fd5b5035919050565b60006020828403121561069c57600080fd5b81356001600160a01b03811681146106b357600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156106e257600080fd5b813567ffffffffffffffff808211156106fa57600080fd5b818401915084601f83011261070e57600080fd5b813581811115610720576107206106ba565b604051601f8201601f19908116603f01168101908382118183101715610748576107486106ba565b8160405282815287602084870101111561076157600080fd5b826020860160208301376000928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b60008160001904831182151516156107e057634e487b7160e01b600052601160045260246000fd5b500290565b60008261080257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561081957600080fd5b815180151581146106b357600080fd5b634e487b7160e01b600052603260045260246000fdfea26469706673582212205ea335809638809cf032c794fd966e2439020737b1dcc2218435cb438286efcf64736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0xF9062b8a30e0d7722960e305049FA50b86ba6253" + } + }, + "0x5300000000000000000000000000000000000003": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c57806379586dd7146100665780638da5cb5b14610079578063efc78401146100a9578063f2fde38b146100e5575b600080fd5b6100646100f8565b005b610064610074366004610356565b610137565b60005461008c906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d56100b736600461042d565b6001600160a01b031660009081526001602052604090205460ff1690565b60405190151581526020016100a0565b6100646100f336600461042d565b610238565b6000546001600160a01b0316331461012b5760405162461bcd60e51b81526004016101229061044f565b60405180910390fd5b61013560006102c4565b565b6000546001600160a01b031633146101615760405162461bcd60e51b81526004016101229061044f565b60005b825181101561023357816001600085848151811061018457610184610486565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508281815181106101d5576101d5610486565b60200260200101516001600160a01b03167f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d83604051610219911515815260200190565b60405180910390a28061022b8161049c565b915050610164565b505050565b6000546001600160a01b031633146102625760405162461bcd60e51b81526004016101229061044f565b6001600160a01b0381166102b85760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f20616464726573730000006044820152606401610122565b6102c1816102c4565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b80356001600160a01b038116811461034157600080fd5b919050565b8035801515811461034157600080fd5b6000806040838503121561036957600080fd5b823567ffffffffffffffff8082111561038157600080fd5b818501915085601f83011261039557600080fd5b81356020828211156103a9576103a9610314565b8160051b604051601f19603f830116810181811086821117156103ce576103ce610314565b6040529283528183019350848101820192898411156103ec57600080fd5b948201945b83861015610411576104028661032a565b855294820194938201936103f1565b96506104209050878201610346565b9450505050509250929050565b60006020828403121561043f57600080fd5b6104488261032a565b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600182016104bc57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212203414b076e92b618bd7c3437159d7bceb2acc3a5c82f51f383465512d9c52e97064736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0xF9062b8a30e0d7722960e305049FA50b86ba6253" + } + }, + "0x5300000000000000000000000000000000000004": { + "balance": "0x0", + "code": "0x6080604052600436106101025760003560e01c806370a0823111610095578063a457c2d711610064578063a457c2d7146102b4578063a9059cbb146102d4578063d0e30db0146102f4578063d505accf146102fc578063dd62ed3e1461031c57600080fd5b806370a08231146102215780637ecebe001461025757806384b0196e1461027757806395d89b411461029f57600080fd5b80632e1a7d4d116100d15780632e1a7d4d146101b0578063313ce567146101d05780633644e515146101ec578063395093511461020157600080fd5b806306fdde0314610116578063095ea7b31461014157806318160ddd1461017157806323b872dd1461019057600080fd5b366101115761010f61033c565b005b600080fd5b34801561012257600080fd5b5061012b61038d565b60405161013891906112fa565b60405180910390f35b34801561014d57600080fd5b5061016161015c366004611330565b61041f565b6040519015158152602001610138565b34801561017d57600080fd5b506002545b604051908152602001610138565b34801561019c57600080fd5b506101616101ab36600461135a565b610439565b3480156101bc57600080fd5b5061010f6101cb366004611396565b61045d565b3480156101dc57600080fd5b5060405160128152602001610138565b3480156101f857600080fd5b5061018261054e565b34801561020d57600080fd5b5061016161021c366004611330565b61055d565b34801561022d57600080fd5b5061018261023c3660046113af565b6001600160a01b031660009081526020819052604090205490565b34801561026357600080fd5b506101826102723660046113af565b61057f565b34801561028357600080fd5b5061028c61059d565b60405161013897969594939291906113ca565b3480156102ab57600080fd5b5061012b610626565b3480156102c057600080fd5b506101616102cf366004611330565b610635565b3480156102e057600080fd5b506101616102ef366004611330565b6106b0565b61010f61033c565b34801561030857600080fd5b5061010f610317366004611460565b6106be565b34801561032857600080fd5b506101826103373660046114d3565b610822565b336103478134610881565b806001600160a01b03167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c3460405161038291815260200190565b60405180910390a250565b60606003805461039c90611506565b80601f01602080910402602001604051908101604052809291908181526020018280546103c890611506565b80156104155780601f106103ea57610100808354040283529160200191610415565b820191906000526020600020905b8154815290600101906020018083116103f857829003601f168201915b5050505050905090565b60003361042d818585610940565b60019150505b92915050565b600033610447858285610a65565b610452858585610adf565b506001949350505050565b336104688183610c83565b6000816001600160a01b03168360405160006040518083038185875af1925050503d80600081146104b5576040519150601f19603f3d011682016040523d82523d6000602084013e6104ba565b606091505b50509050806105065760405162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc81155120819985a5b1959606a1b60448201526064015b60405180910390fd5b816001600160a01b03167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b658460405161054191815260200190565b60405180910390a2505050565b6000610558610db2565b905090565b60003361042d8185856105708383610822565b61057a919061153a565b610940565b6001600160a01b038116600090815260076020526040812054610433565b6000606080828080836105d17f577261707065642045746865720000000000000000000000000000000000000d6005610edd565b6105fc7f31000000000000000000000000000000000000000000000000000000000000016006610edd565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b60606004805461039c90611506565b600033816106438286610822565b9050838110156106a35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016104fd565b6104528286868403610940565b60003361042d818585610adf565b8342111561070e5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016104fd565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c988888861073d8c610f81565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061079882610fa9565b905060006107a882878787610fd6565b9050896001600160a01b0316816001600160a01b03161461080b5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016104fd565b6108168a8a8a610940565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60006020835110156108695761086283610ffe565b9050610433565b8161087484826115bf565b5060ff9050610433565b90565b6001600160a01b0382166108d75760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016104fd565b80600260008282546108e9919061153a565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0383166109a25760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016104fd565b6001600160a01b038216610a035760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016104fd565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6000610a718484610822565b90506000198114610ad95781811015610acc5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016104fd565b610ad98484848403610940565b50505050565b6001600160a01b038316610b435760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016104fd565b6001600160a01b038216610ba55760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016104fd565b6001600160a01b03831660009081526020819052604090205481811015610c1d5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016104fd565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610ad9565b6001600160a01b038216610ce35760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016104fd565b6001600160a01b03821660009081526020819052604090205481811015610d575760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016104fd565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610a58565b505050565b6000306001600160a01b037f000000000000000000000000530000000000000000000000000000000000000416148015610e0b57507f000000000000000000000000000000000000000000000000000000000008275046145b15610e3557507fe5b117a3cd7ae7ed3508e6e6c5a0794536b2a8dee12533c4d7524eae9c85438f90565b610558604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f00cd3d46df44f2cbb950cf84eb2e92aa2ddd23195b1a009173ea59a063357ed3918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b606060ff8314610ef0576108628361103c565b818054610efc90611506565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2890611506565b8015610f755780601f10610f4a57610100808354040283529160200191610f75565b820191906000526020600020905b815481529060010190602001808311610f5857829003601f168201915b50505050509050610433565b6001600160a01b03811660009081526007602052604090208054600181018255905b50919050565b6000610433610fb6610db2565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000610fe78787878761107b565b91509150610ff48161113f565b5095945050505050565b600080829050601f81511115611029578260405163305a27a960e01b81526004016104fd91906112fa565b80516110348261167f565b179392505050565b606060006110498361128c565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156110b25750600090506003611136565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015611106573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661112f57600060019250925050611136565b9150600090505b94509492505050565b6000816004811115611153576111536116a3565b0361115b5750565b600181600481111561116f5761116f6116a3565b036111bc5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104fd565b60028160048111156111d0576111d06116a3565b0361121d5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104fd565b6003816004811115611231576112316116a3565b036112895760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016104fd565b50565b600060ff8216601f81111561043357604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b818110156112da576020818501810151868301820152016112be565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061130d60208301846112b4565b9392505050565b80356001600160a01b038116811461132b57600080fd5b919050565b6000806040838503121561134357600080fd5b61134c83611314565b946020939093013593505050565b60008060006060848603121561136f57600080fd5b61137884611314565b925061138660208501611314565b9150604084013590509250925092565b6000602082840312156113a857600080fd5b5035919050565b6000602082840312156113c157600080fd5b61130d82611314565b60ff60f81b881681526000602060e0818401526113ea60e084018a6112b4565b83810360408501526113fc818a6112b4565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b8181101561144e57835183529284019291840191600101611432565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561147b57600080fd5b61148488611314565b965061149260208901611314565b95506040880135945060608801359350608088013560ff811681146114b657600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156114e657600080fd5b6114ef83611314565b91506114fd60208401611314565b90509250929050565b600181811c9082168061151a57607f821691505b602082108103610fa357634e487b7160e01b600052602260045260246000fd5b8082018082111561043357634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f821115610dad57600081815260208120601f850160051c810160208610156115985750805b601f850160051c820191505b818110156115b7578281556001016115a4565b505050505050565b815167ffffffffffffffff8111156115d9576115d961155b565b6115ed816115e78454611506565b84611571565b602080601f831160018114611622576000841561160a5750858301515b600019600386901b1c1916600185901b1785556115b7565b600085815260208120601f198616915b8281101561165157888601518255948401946001909101908401611632565b508582101561166f5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516020808301519190811015610fa35760001960209190910360031b1b16919050565b634e487b7160e01b600052602160045260246000fdfea26469706673582212207f39e33e122e8e2b0381aa6abea46046f56b05ced66c556a06bb1b80be7f55cf64736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x577261707065642045746865720000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5745544800000000000000000000000000000000000000000000000000000008" + } + }, + "0x5300000000000000000000000000000000000005": { + "balance": "0x0", + "code": "0x6080604052600436106100ab5760003560e01c806384411d651161006457806384411d65146101845780638da5cb5b1461019a5780639e7adc79146101ba578063f2fde38b146101da578063feec756c146101fa578063ff4f35461461021a57600080fd5b80632e1a7d4d146100b75780633cb747bf146100d95780633ccfd60b14610116578063457e1a491461012b57806366d003ac1461014f578063715018a61461016f57600080fd5b366100b257005b600080fd5b3480156100c357600080fd5b506100d76100d2366004610682565b61023a565b005b3480156100e557600080fd5b506002546100f9906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561012257600080fd5b506100d76103ff565b34801561013757600080fd5b5061014160015481565b60405190815260200161010d565b34801561015b57600080fd5b506003546100f9906001600160a01b031681565b34801561017b57600080fd5b506100d761040c565b34801561019057600080fd5b5061014160045481565b3480156101a657600080fd5b506000546100f9906001600160a01b031681565b3480156101c657600080fd5b506100d76101d536600461069b565b610442565b3480156101e657600080fd5b506100d76101f536600461069b565b6104be565b34801561020657600080fd5b506100d761021536600461069b565b610547565b34801561022657600080fd5b506100d7610235366004610682565b6105c3565b6001548110156102ca5760405162461bcd60e51b815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d20776974686472616064820152691dd85b08185b5bdd5b9d60b21b608482015260a4015b60405180910390fd5b478082111561032e5760405162461bcd60e51b815260206004820152602a60248201527f4665655661756c743a20696e73756666696369656e742062616c616e636520746044820152696f20776974686472617760b01b60648201526084016102c1565b6004805483019055600354604080518481526001600160a01b0390921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1600254600354604080516020810182526000808252915163b2267a7b60e01b81526001600160a01b039485169463b2267a7b9488946103c99491909216928592906004016106cb565b6000604051808303818588803b1580156103e257600080fd5b505af11580156103f6573d6000803e3d6000fd5b50505050505050565b476104098161023a565b50565b6000546001600160a01b031633146104365760405162461bcd60e51b81526004016102c190610737565b6104406000610632565b565b6000546001600160a01b0316331461046c5760405162461bcd60e51b81526004016102c190610737565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f1c928c417a10a21c3cddad148c5dba5d710e4b1442d6d8a36de345935ad8461290600090a35050565b6000546001600160a01b031633146104e85760405162461bcd60e51b81526004016102c190610737565b6001600160a01b03811661053e5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016102c1565b61040981610632565b6000546001600160a01b031633146105715760405162461bcd60e51b81526004016102c190610737565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f7e1e96961a397c8aa26162fe259cc837afc95e33aad4945ddc61c18dabb7a6ad90600090a35050565b6000546001600160a01b031633146105ed5760405162461bcd60e51b81526004016102c190610737565b600180549082905560408051828152602081018490527f0d3c80219fe57713b9f9c83d1e51426792d0c14d8e330e65b102571816140965910160405180910390a15050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561069457600080fd5b5035919050565b6000602082840312156106ad57600080fd5b81356001600160a01b03811681146106c457600080fd5b9392505050565b60018060a01b038516815260006020858184015260806040840152845180608085015260005b8181101561070d5786810183015185820160a0015282016106f1565b50600060a0828601015260a0601f19601f8301168501019250505082606083015295945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060408201526060019056fea2646970667358221220063c6c384f745ebcacfdd13320e5b9a50687aae43ff14566761f56273111b97e64736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0xF9062b8a30e0d7722960e305049FA50b86ba6253", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x8ac7230489e80000", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x781e90f1c8Fc4611c9b7497C3B47F99Ef6969CbC", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x8FA3b4570B4C96f8036C13b64971BA65867eEB48" + } + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas": null +} \ No newline at end of file diff --git a/crates/core/src/data/genesis/genesis.sepolia.json b/crates/core/src/data/genesis/genesis.sepolia.json new file mode 100644 index 0000000..15b9855 --- /dev/null +++ b/crates/core/src/data/genesis/genesis.sepolia.json @@ -0,0 +1,98 @@ +{ + "config": { + "chainId": 534351, + "homesteadBlock": 0, + "eip150Block": 0, + "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "archimedesBlock": 0, + "shanghaiBlock": 0, + "shanghaiTime": 0, + "bernoulliBlock": 3747132, + "curieBlock": 4740239, + "darwinTime": 1723622400, + "darwinV2Time": 1724832000, + "clique": { + "period": 3, + "epoch": 30000, + "relaxed_period": true + }, + "scroll": { + "useZktrie": true, + "maxTxPerBlock": 100, + "maxTxPayloadBytesPerBlock": 122880, + "feeVaultAddress": "0x5300000000000000000000000000000000000005", + "l1Config": { + "l1ChainId": "11155111", + "l1MessageQueueAddress": "0xF0B2293F5D834eAe920c6974D50957A1732de763", + "scrollChainAddress": "0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0", + "numL1MessagesPerBlock": "10" + } + } + }, + "nonce": "0x0", + "timestamp": "0x64cfd015", + "extraData": "0x000000000000000000000000000000000000000000000000000000000000000048C3F81f3D998b6652900e1C3183736C238Fe4290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "gasLimit": "8000000", + "difficulty": "0x1", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0x18960EEc21b1878C581937a14c5c3C43008F6b6B": { + "balance": "10000000000000000000" + }, + "0xBa50f5340FB9F3Bd074bD638c9BE13eCB36E603d": { + "balance": "226156424291633194186662080095093570025917938800079226629565593765455331328" + }, + "0x5300000000000000000000000000000000000000": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100935760003560e01c806383cc76601161006657806383cc7660146100fc5780638da5cb5b1461010f578063c4d66de814610122578063d4b9f4fa14610135578063f2fde38b1461013e57600080fd5b806326aad7b7146100985780633cb747bf146100b4578063600a2e77146100df578063715018a6146100f2575b600080fd5b6100a160015481565b6040519081526020015b60405180910390f35b6053546100c7906001600160a01b031681565b6040516001600160a01b0390911681526020016100ab565b6100a16100ed36600461054a565b610151565b6100fa6101f6565b005b6100a161010a36600461054a565b61022c565b6052546100c7906001600160a01b031681565b6100fa610130366004610563565b610243565b6100a160005481565b6100fa61014c366004610563565b6102db565b6053546000906001600160a01b031633146101a45760405162461bcd60e51b815260206004820152600e60248201526d37b7363c9036b2b9b9b2b733b2b960911b60448201526064015b60405180910390fd5b6000806101b084610367565b60408051838152602081018890529294509092507ffaa617c2d8ce12c62637dbce76efcc18dae60574aa95709bdcedce7e76071693910160405180910390a19392505050565b6052546001600160a01b031633146102205760405162461bcd60e51b815260040161019b90610593565b61022a6000610486565b565b602a816028811061023c57600080fd5b0154905081565b6052546001600160a01b0316331461026d5760405162461bcd60e51b815260040161019b90610593565b600154156102b15760405162461bcd60e51b815260206004820152601160248201527063616e6e6f7420696e697469616c697a6560781b604482015260640161019b565b6102b96104d8565b605380546001600160a01b0319166001600160a01b0392909216919091179055565b6052546001600160a01b031633146103055760405162461bcd60e51b815260040161019b90610593565b6001600160a01b03811661035b5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f2061646472657373000000604482015260640161019b565b61036481610486565b50565b60035460009081906103bb5760405162461bcd60e51b815260206004820152601a60248201527f63616c6c206265666f726520696e697469616c697a6174696f6e000000000000604482015260640161019b565b6001548360005b8215610456576103d36002846105e0565b60000361041f5781602a82602881106103ee576103ee6105ca565b01556104188260028360288110610407576104076105ca565b015460009182526020526040902090565b915061044a565b610447602a8260288110610435576104356105ca565b01548360009182526020526040902090565b91505b600192831c92016103c2565b81602a826028811061046a5761046a6105ca565b0155506000819055600180548082019091559590945092505050565b605280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60005b60286104e8826001610618565b10156103645761051960028260288110610504576105046105ca565b015460028360288110610407576104076105ca565b6002610526836001610618565b60288110610536576105366105ca565b01558061054281610631565b9150506104db565b60006020828403121561055c57600080fd5b5035919050565b60006020828403121561057557600080fd5b81356001600160a01b038116811461058c57600080fd5b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000826105fd57634e487b7160e01b600052601260045260246000fd5b500690565b634e487b7160e01b600052601160045260246000fd5b8082018082111561062b5761062b610602565b92915050565b60006001820161064357610643610602565b506001019056fea26469706673582212208fb1cb9933bb17dd0a7c17de7c890919b08d2fd7eb2bede7b41caa32709b30b564736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000052": "0x18960EEc21b1878C581937a14c5c3C43008F6b6B" + } + }, + "0x5300000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100cf5760003560e01c8063715018a61161008c578063bede39b511610066578063bede39b51461018d578063de26c4a1146101a0578063f2fde38b146101b3578063f45e65d8146101c657600080fd5b8063715018a6146101475780638da5cb5b1461014f57806393e59dc11461017a57600080fd5b80630c18c162146100d45780633577afc5146100f05780633d0f963e1461010557806349948e0e14610118578063519b4bd31461012b5780637046559714610134575b600080fd5b6100dd60025481565b6040519081526020015b60405180910390f35b6101036100fe366004610671565b6101cf565b005b61010361011336600461068a565b610291565b6100dd6101263660046106d0565b61031c565b6100dd60015481565b610103610142366004610671565b610361565b610103610416565b600054610162906001600160a01b031681565b6040516001600160a01b0390911681526020016100e7565b600454610162906001600160a01b031681565b61010361019b366004610671565b61044c565b6100dd6101ae3660046106d0565b610533565b6101036101c136600461068a565b610595565b6100dd60035481565b6000546001600160a01b031633146102025760405162461bcd60e51b81526004016101f990610781565b60405180910390fd5b621c9c388111156102555760405162461bcd60e51b815260206004820152601760248201527f657863656564206d6178696d756d206f7665726865616400000000000000000060448201526064016101f9565b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6000546001600160a01b031633146102bb5760405162461bcd60e51b81526004016101f990610781565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f7910160405180910390a15050565b60008061032883610533565b905060006001548261033a91906107b8565b9050633b9aca006003548261034f91906107b8565b61035991906107e5565b949350505050565b6000546001600160a01b0316331461038b5760405162461bcd60e51b81526004016101f990610781565b61039b633b9aca006103e86107b8565b8111156103e15760405162461bcd60e51b8152602060048201526014602482015273657863656564206d6178696d756d207363616c6560601b60448201526064016101f9565b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a90602001610286565b6000546001600160a01b031633146104405760405162461bcd60e51b81526004016101f990610781565b61044a6000610621565b565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b99190610807565b6104fe5760405162461bcd60e51b81526020600482015260166024820152752737ba103bb434ba32b634b9ba32b21039b2b73232b960511b60448201526064016101f9565b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c4490602001610286565b80516000908190815b818110156105865784818151811061055657610556610829565b01602001516001600160f81b0319166000036105775760048301925061057e565b6010830192505b60010161053c565b50506002540160400192915050565b6000546001600160a01b031633146105bf5760405162461bcd60e51b81526004016101f990610781565b6001600160a01b0381166106155760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016101f9565b61061e81610621565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561068357600080fd5b5035919050565b60006020828403121561069c57600080fd5b81356001600160a01b03811681146106b357600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b6000602082840312156106e257600080fd5b813567ffffffffffffffff808211156106fa57600080fd5b818401915084601f83011261070e57600080fd5b813581811115610720576107206106ba565b604051601f8201601f19908116603f01168101908382118183101715610748576107486106ba565b8160405282815287602084870101111561076157600080fd5b826020860160208301376000928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b60008160001904831182151516156107e057634e487b7160e01b600052601160045260246000fd5b500290565b60008261080257634e487b7160e01b600052601260045260246000fd5b500490565b60006020828403121561081957600080fd5b815180151581146106b357600080fd5b634e487b7160e01b600052603260045260246000fdfea26469706673582212205ea335809638809cf032c794fd966e2439020737b1dcc2218435cb438286efcf64736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x18960EEc21b1878C581937a14c5c3C43008F6b6B" + } + }, + "0x5300000000000000000000000000000000000003": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c57806379586dd7146100665780638da5cb5b14610079578063efc78401146100a9578063f2fde38b146100e5575b600080fd5b6100646100f8565b005b610064610074366004610356565b610137565b60005461008c906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d56100b736600461042d565b6001600160a01b031660009081526001602052604090205460ff1690565b60405190151581526020016100a0565b6100646100f336600461042d565b610238565b6000546001600160a01b0316331461012b5760405162461bcd60e51b81526004016101229061044f565b60405180910390fd5b61013560006102c4565b565b6000546001600160a01b031633146101615760405162461bcd60e51b81526004016101229061044f565b60005b825181101561023357816001600085848151811061018457610184610486565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff0219169083151502179055508281815181106101d5576101d5610486565b60200260200101516001600160a01b03167f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d83604051610219911515815260200190565b60405180910390a28061022b8161049c565b915050610164565b505050565b6000546001600160a01b031633146102625760405162461bcd60e51b81526004016101229061044f565b6001600160a01b0381166102b85760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f20616464726573730000006044820152606401610122565b6102c1816102c4565b50565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b80356001600160a01b038116811461034157600080fd5b919050565b8035801515811461034157600080fd5b6000806040838503121561036957600080fd5b823567ffffffffffffffff8082111561038157600080fd5b818501915085601f83011261039557600080fd5b81356020828211156103a9576103a9610314565b8160051b604051601f19603f830116810181811086821117156103ce576103ce610314565b6040529283528183019350848101820192898411156103ec57600080fd5b948201945b83861015610411576104028661032a565b855294820194938201936103f1565b96506104209050878201610346565b9450505050509250929050565b60006020828403121561043f57600080fd5b6104488261032a565b9392505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b634e487b7160e01b600052603260045260246000fd5b6000600182016104bc57634e487b7160e01b600052601160045260246000fd5b506001019056fea26469706673582212203414b076e92b618bd7c3437159d7bceb2acc3a5c82f51f383465512d9c52e97064736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x18960EEc21b1878C581937a14c5c3C43008F6b6B" + } + }, + "0x5300000000000000000000000000000000000004": { + "balance": "0x0", + "code": "0x6080604052600436106101025760003560e01c806370a0823111610095578063a457c2d711610064578063a457c2d7146102b4578063a9059cbb146102d4578063d0e30db0146102f4578063d505accf146102fc578063dd62ed3e1461031c57600080fd5b806370a08231146102215780637ecebe001461025757806384b0196e1461027757806395d89b411461029f57600080fd5b80632e1a7d4d116100d15780632e1a7d4d146101b0578063313ce567146101d05780633644e515146101ec578063395093511461020157600080fd5b806306fdde0314610116578063095ea7b31461014157806318160ddd1461017157806323b872dd1461019057600080fd5b366101115761010f61033c565b005b600080fd5b34801561012257600080fd5b5061012b61037d565b60405161013891906112cf565b60405180910390f35b34801561014d57600080fd5b5061016161015c366004611305565b61040f565b6040519015158152602001610138565b34801561017d57600080fd5b506002545b604051908152602001610138565b34801561019c57600080fd5b506101616101ab36600461132f565b610429565b3480156101bc57600080fd5b5061010f6101cb36600461136b565b61044d565b3480156101dc57600080fd5b5060405160128152602001610138565b3480156101f857600080fd5b50610182610523565b34801561020d57600080fd5b5061016161021c366004611305565b610532565b34801561022d57600080fd5b5061018261023c366004611384565b6001600160a01b031660009081526020819052604090205490565b34801561026357600080fd5b50610182610272366004611384565b610554565b34801561028357600080fd5b5061028c610572565b604051610138979695949392919061139f565b3480156102ab57600080fd5b5061012b6105fb565b3480156102c057600080fd5b506101616102cf366004611305565b61060a565b3480156102e057600080fd5b506101616102ef366004611305565b610685565b61010f61033c565b34801561030857600080fd5b5061010f610317366004611435565b610693565b34801561032857600080fd5b506101826103373660046114a8565b6107f7565b6103463334610856565b60405134815233907fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9060200160405180910390a2565b60606003805461038c906114db565b80601f01602080910402602001604051908101604052809291908181526020018280546103b8906114db565b80156104055780601f106103da57610100808354040283529160200191610405565b820191906000526020600020905b8154815290600101906020018083116103e857829003601f168201915b5050505050905090565b60003361041d818585610915565b60019150505b92915050565b600033610437858285610a3a565b610442858585610ab4565b506001949350505050565b6104573382610c58565b604051600090339083908381818185875af1925050503d8060008114610499576040519150601f19603f3d011682016040523d82523d6000602084013e61049e565b606091505b50509050806104ea5760405162461bcd60e51b81526020600482015260136024820152721dda5d1a191c985dc81155120819985a5b1959606a1b60448201526064015b60405180910390fd5b60405182815233907f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b659060200160405180910390a25050565b600061052d610d87565b905090565b60003361041d81858561054583836107f7565b61054f919061150f565b610915565b6001600160a01b038116600090815260076020526040812054610423565b6000606080828080836105a67f577261707065642045746865720000000000000000000000000000000000000d6005610eb2565b6105d17f31000000000000000000000000000000000000000000000000000000000000016006610eb2565b60408051600080825260208201909252600f60f81b9b939a50919850469750309650945092509050565b60606004805461038c906114db565b6000338161061882866107f7565b9050838110156106785760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084016104e1565b6104428286868403610915565b60003361041d818585610ab4565b834211156106e35760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e6500000060448201526064016104e1565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98888886107128c610f56565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e001604051602081830303815290604052805190602001209050600061076d82610f7e565b9050600061077d82878787610fab565b9050896001600160a01b0316816001600160a01b0316146107e05760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e6174757265000060448201526064016104e1565b6107eb8a8a8a610915565b50505050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b600060208351101561083e5761083783610fd3565b9050610423565b816108498482611594565b5060ff9050610423565b90565b6001600160a01b0382166108ac5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016104e1565b80600260008282546108be919061150f565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b0383166109775760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016104e1565b6001600160a01b0382166109d85760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016104e1565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6000610a4684846107f7565b90506000198114610aae5781811015610aa15760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016104e1565b610aae8484848403610915565b50505050565b6001600160a01b038316610b185760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016104e1565b6001600160a01b038216610b7a5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016104e1565b6001600160a01b03831660009081526020819052604090205481811015610bf25760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b60648201526084016104e1565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610aae565b6001600160a01b038216610cb85760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b60648201526084016104e1565b6001600160a01b03821660009081526020819052604090205481811015610d2c5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b60648201526084016104e1565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610a2d565b505050565b6000306001600160a01b037f0000000000000000000000005fbdb2315678afecb367f032d93f642f64180aa316148015610de057507f000000000000000000000000000000000000000000000000000000000008274f46145b15610e0a57507f624453decb4e78ca99c7630ff9f52222ea6f559f0a6c1bb60b935ef006fa159e90565b61052d604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f00cd3d46df44f2cbb950cf84eb2e92aa2ddd23195b1a009173ea59a063357ed3918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260009060c00160405160208183030381529060405280519060200120905090565b606060ff8314610ec55761083783611011565b818054610ed1906114db565b80601f0160208091040260200160405190810160405280929190818152602001828054610efd906114db565b8015610f4a5780601f10610f1f57610100808354040283529160200191610f4a565b820191906000526020600020905b815481529060010190602001808311610f2d57829003601f168201915b50505050509050610423565b6001600160a01b03811660009081526007602052604090208054600181018255905b50919050565b6000610423610f8b610d87565b8360405161190160f01b8152600281019290925260228201526042902090565b6000806000610fbc87878787611050565b91509150610fc981611114565b5095945050505050565b600080829050601f81511115610ffe578260405163305a27a960e01b81526004016104e191906112cf565b805161100982611654565b179392505050565b6060600061101e83611261565b604080516020808252818301909252919250600091906020820181803683375050509182525060208101929092525090565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115611087575060009050600361110b565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156110db573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166111045760006001925092505061110b565b9150600090505b94509492505050565b600081600481111561112857611128611678565b036111305750565b600181600481111561114457611144611678565b036111915760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016104e1565b60028160048111156111a5576111a5611678565b036111f25760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016104e1565b600381600481111561120657611206611678565b0361125e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016104e1565b50565b600060ff8216601f81111561042357604051632cd44ac360e21b815260040160405180910390fd5b6000815180845260005b818110156112af57602081850181015186830182015201611293565b506000602082860101526020601f19601f83011685010191505092915050565b6020815260006112e26020830184611289565b9392505050565b80356001600160a01b038116811461130057600080fd5b919050565b6000806040838503121561131857600080fd5b611321836112e9565b946020939093013593505050565b60008060006060848603121561134457600080fd5b61134d846112e9565b925061135b602085016112e9565b9150604084013590509250925092565b60006020828403121561137d57600080fd5b5035919050565b60006020828403121561139657600080fd5b6112e2826112e9565b60ff60f81b881681526000602060e0818401526113bf60e084018a611289565b83810360408501526113d1818a611289565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b8181101561142357835183529284019291840191600101611407565b50909c9b505050505050505050505050565b600080600080600080600060e0888a03121561145057600080fd5b611459886112e9565b9650611467602089016112e9565b95506040880135945060608801359350608088013560ff8116811461148b57600080fd5b9699959850939692959460a0840135945060c09093013592915050565b600080604083850312156114bb57600080fd5b6114c4836112e9565b91506114d2602084016112e9565b90509250929050565b600181811c908216806114ef57607f821691505b602082108103610f7857634e487b7160e01b600052602260045260246000fd5b8082018082111561042357634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b601f821115610d8257600081815260208120601f850160051c8101602086101561156d5750805b601f850160051c820191505b8181101561158c57828155600101611579565b505050505050565b815167ffffffffffffffff8111156115ae576115ae611530565b6115c2816115bc84546114db565b84611546565b602080601f8311600181146115f757600084156115df5750858301515b600019600386901b1c1916600185901b17855561158c565b600085815260208120601f198616915b8281101561162657888601518255948401946001909101908401611607565b50858210156116445787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b80516020808301519190811015610f785760001960209190910360031b1b16919050565b634e487b7160e01b600052602160045260246000fdfea264697066735822122075458b204a41338df799effa8b73c6c1a17e612bc3b3311c0cec123c4da7709964736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x577261707065642045746865720000000000000000000000000000000000001a", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x5745544800000000000000000000000000000000000000000000000000000008" + } + }, + "0x5300000000000000000000000000000000000005": { + "balance": "0x0", + "code": "0x6080604052600436106100a05760003560e01c806384411d651161006457806384411d65146101595780638da5cb5b1461016f5780639e7adc791461018f578063f2fde38b146101af578063feec756c146101cf578063ff4f3546146101ef57600080fd5b80633cb747bf146100ac5780633ccfd60b146100e9578063457e1a491461010057806366d003ac14610124578063715018a61461014457600080fd5b366100a757005b600080fd5b3480156100b857600080fd5b506002546100cc906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156100f557600080fd5b506100fe61020f565b005b34801561010c57600080fd5b5061011660015481565b6040519081526020016100e0565b34801561013057600080fd5b506003546100cc906001600160a01b031681565b34801561015057600080fd5b506100fe610371565b34801561016557600080fd5b5061011660045481565b34801561017b57600080fd5b506000546100cc906001600160a01b031681565b34801561019b57600080fd5b506100fe6101aa3660046105ea565b6103a7565b3480156101bb57600080fd5b506100fe6101ca3660046105ea565b610423565b3480156101db57600080fd5b506100fe6101ea3660046105ea565b6104af565b3480156101fb57600080fd5b506100fe61020a36600461061a565b61052b565b60015447908110156102a15760405162461bcd60e51b815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d20776974686472616064820152691dd85b08185b5bdd5b9d60b21b608482015260a4015b60405180910390fd5b6004805482019055600354604080518381526001600160a01b0390921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a1600254600354604080516020810182526000808252915163b2267a7b60e01b81526001600160a01b039485169463b2267a7b94879461033c949190921692859290600401610633565b6000604051808303818588803b15801561035557600080fd5b505af1158015610369573d6000803e3d6000fd5b505050505050565b6000546001600160a01b0316331461039b5760405162461bcd60e51b81526004016102989061069f565b6103a5600061059a565b565b6000546001600160a01b031633146103d15760405162461bcd60e51b81526004016102989061069f565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f1c928c417a10a21c3cddad148c5dba5d710e4b1442d6d8a36de345935ad8461290600090a35050565b6000546001600160a01b0316331461044d5760405162461bcd60e51b81526004016102989061069f565b6001600160a01b0381166104a35760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f20616464726573730000006044820152606401610298565b6104ac8161059a565b50565b6000546001600160a01b031633146104d95760405162461bcd60e51b81526004016102989061069f565b600380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f7e1e96961a397c8aa26162fe259cc837afc95e33aad4945ddc61c18dabb7a6ad90600090a35050565b6000546001600160a01b031633146105555760405162461bcd60e51b81526004016102989061069f565b600180549082905560408051828152602081018490527f0d3c80219fe57713b9f9c83d1e51426792d0c14d8e330e65b102571816140965910160405180910390a15050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156105fc57600080fd5b81356001600160a01b038116811461061357600080fd5b9392505050565b60006020828403121561062c57600080fd5b5035919050565b60018060a01b038516815260006020858184015260806040840152845180608085015260005b818110156106755786810183015185820160a001528201610659565b50600060a0828601015260a0601f19601f8301168501019250505082606083015295945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e657200000000000000000060408201526060019056fea26469706673582212200c5bec0af207d4c7845829d5330f295a5f16702ab8bde670ae90be68974af0a764736f6c63430008100033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x18960EEc21b1878C581937a14c5c3C43008F6b6B", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x8ac7230489e80000", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0xBa50f5340FB9F3Bd074bD638c9BE13eCB36E603d", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x2351C7aD0c8cFEB25c81301EAC922ab1f1980bbe" + } + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "baseFeePerGas": null +} diff --git a/crates/core/src/database.rs b/crates/core/src/database.rs index 32cce45..ae3718c 100644 --- a/crates/core/src/database.rs +++ b/crates/core/src/database.rs @@ -3,12 +3,13 @@ use revm::{ db::DatabaseRef, primitives::{AccountInfo, Address, Bytecode, B256, U256}, }; -use sbv_primitives::zk_trie::db::NodeDb; -use sbv_primitives::zk_trie::hash::ZkHash; use sbv_primitives::{ zk_trie::{ - db::kv::{KVDatabase, KVDatabaseItem}, - hash::{key_hasher::NoCacheHasher, poseidon::Poseidon}, + db::{ + kv::{KVDatabase, KVDatabaseItem}, + NodeDb, + }, + hash::{key_hasher::NoCacheHasher, poseidon::Poseidon, ZkHash}, scroll_types::Account, trie::ZkTrie, }, @@ -21,7 +22,7 @@ type Result = std::result::Result; /// A database that consists of account and storage information. pub struct EvmDatabase<'a, CodeDb, ZkDb> { /// Map of code hash to bytecode. - code_db: CodeDb, + pub(crate) code_db: &'a mut CodeDb, /// Storage root cache, avoid re-query account when storage root is needed storage_root_caches: RefCell>, /// Storage trie cache, avoid re-creating trie for the same account. @@ -44,23 +45,12 @@ impl fmt::Debug for EvmDatabase<'_, CodeDb, Db> { } impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmDatabase<'a, CodeDb, ZkDb> { - /// Initialize an EVM database from a block trace. - pub fn new( - l2_trace: T, - mut code_db: CodeDb, + /// Initialize an EVM database from a zkTrie root. + pub fn new_from_root( + committed_zktrie_root: B256, + code_db: &'a mut CodeDb, zktrie_db: &'a mut NodeDb, ) -> Result { - cycle_tracker_start!("insert CodeDB"); - for code in l2_trace.codes() { - let hash = revm::primitives::keccak256(code); - code_db - .or_put(hash.as_slice(), code) - .map_err(DatabaseError::code_db)?; - } - cycle_tracker_end!("insert CodeDB"); - - let committed_zktrie_root = l2_trace.root_before(); - let zktrie = ZkTrie::new_with_root(zktrie_db, NoCacheHasher, committed_zktrie_root) .map_err(DatabaseError::zk_trie)?; @@ -113,11 +103,14 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmDatabase<'a, CodeDb, } /// Update the database with a new block trace. - pub fn update(&mut self, l2_trace: T) -> Result<()> { - measure_duration_millis!(update_db_duration_milliseconds, self.update_inner(l2_trace)) + pub fn insert_codes(&mut self, l2_trace: T) -> Result<()> { + measure_duration_millis!( + update_db_duration_milliseconds, + self.insert_codes_inner(l2_trace) + ) } - fn update_inner(&mut self, l2_trace: T) -> Result<()> { + fn insert_codes_inner(&mut self, l2_trace: T) -> Result<()> { cycle_tracker_start!("insert CodeDB"); for code in l2_trace.codes() { let hash = revm::primitives::keccak256(code); @@ -126,13 +119,6 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmDatabase<'a, CodeDb, .map_err(DatabaseError::code_db)?; } cycle_tracker_end!("insert CodeDB"); - - self.zktrie = cycle_track!( - ZkTrie::new_with_root(self.zktrie_db, NoCacheHasher, l2_trace.root_before(),), - "ZkTrie::new_with_root" - ) - .map_err(DatabaseError::zk_trie)?; - Ok(()) } } @@ -161,6 +147,18 @@ impl DatabaseRef for EvmDatabase .get(&account.code_hash) .map_err(DatabaseError::code_db)? .map(|v| Bytecode::new_legacy(v.into_bytes().into())); + if let Some(ref code) = info.code { + debug_assert_eq!( + info.code_hash, + code.hash_slow(), + "code hash mismatch for account {address:?}", + ); + assert_eq!( + info.code_size, + code.original_bytes().len(), + "code size mismatch for account {address:?}", + ); + } Ok(Some(info)) } @@ -208,7 +206,9 @@ impl DatabaseRef for EvmDatabase ZkTrie::new_with_root(self.zktrie_db, NoCacheHasher, *storage_root) .inspect_err(|e| { - dev_warn!("storage trie associated with account({address}) not found: {e}") + let backtrace = std::backtrace::Backtrace::force_capture(); + dev_warn!("storage trie associated with account({address}) not found: {e}\n{backtrace}"); + }) .ok() }); diff --git a/crates/core/src/executor/builder.rs b/crates/core/src/executor/builder.rs index de796f7..99bfc2e 100644 --- a/crates/core/src/executor/builder.rs +++ b/crates/core/src/executor/builder.rs @@ -1,56 +1,75 @@ use crate::error::DatabaseError; use crate::{executor::hooks::ExecuteHooks, EvmDatabase, EvmExecutor, HardforkConfig}; use revm::db::CacheDB; +use sbv_primitives::alloy_primitives::ChainId; use sbv_primitives::zk_trie::db::kv::KVDatabase; use sbv_primitives::zk_trie::db::NodeDb; -use sbv_primitives::Block; +use sbv_primitives::B256; use std::fmt::{self, Debug}; /// Builder for EVM executor. -pub struct EvmExecutorBuilder<'a, H, CodeDb, ZkDb> { +pub struct EvmExecutorBuilder<'a, H, C, CodeDb, ZkDb> { hardfork_config: H, - code_db: CodeDb, + chain_id: C, + code_db: &'a mut CodeDb, zktrie_db: &'a mut NodeDb, } -impl Debug for EvmExecutorBuilder<'_, H, CodeDb, ZkDb> { +impl Debug for EvmExecutorBuilder<'_, H, C, CodeDb, ZkDb> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("EvmExecutorBuilder") .field("hardfork_config", &self.hardfork_config) + .field("chain_id", &self.chain_id) .field("code_db", &"...") .field("zktrie_db", &"...") .finish() } } -impl<'a, CodeDb, ZkDb> EvmExecutorBuilder<'a, (), CodeDb, ZkDb> { +impl<'a, CodeDb, ZkDb> EvmExecutorBuilder<'a, (), (), CodeDb, ZkDb> { /// Create a new builder. - pub fn new(code_db: CodeDb, zktrie_db: &'a mut NodeDb) -> Self { + pub fn new(code_db: &'a mut CodeDb, zktrie_db: &'a mut NodeDb) -> Self { Self { hardfork_config: (), + chain_id: (), code_db, zktrie_db, } } } -impl<'a, H, CodeDb, ZkDb> EvmExecutorBuilder<'a, H, CodeDb, ZkDb> { +impl<'a, H, C, CodeDb, ZkDb> EvmExecutorBuilder<'a, H, C, CodeDb, ZkDb> { /// Set hardfork config. pub fn hardfork_config

( self, hardfork_config: H1, - ) -> EvmExecutorBuilder<'a, H1, CodeDb, ZkDb> { + ) -> EvmExecutorBuilder<'a, H1, C, CodeDb, ZkDb> { EvmExecutorBuilder { hardfork_config, + chain_id: self.chain_id, + code_db: self.code_db, + zktrie_db: self.zktrie_db, + } + } + + /// Set chain id. + pub fn chain_id(self, chain_id: C1) -> EvmExecutorBuilder<'a, H, C1, CodeDb, ZkDb> { + EvmExecutorBuilder { + hardfork_config: self.hardfork_config, + chain_id, code_db: self.code_db, zktrie_db: self.zktrie_db, } } /// Set code db. - pub fn code_db(self, code_db: CodeDb1) -> EvmExecutorBuilder<'a, H, CodeDb1, ZkDb> { + pub fn code_db( + self, + code_db: &'a mut CodeDb1, + ) -> EvmExecutorBuilder<'a, H, C, CodeDb1, ZkDb> { EvmExecutorBuilder { hardfork_config: self.hardfork_config, + chain_id: self.chain_id, code_db, zktrie_db: self.zktrie_db, } @@ -59,10 +78,11 @@ impl<'a, H, CodeDb, ZkDb> EvmExecutorBuilder<'a, H, CodeDb, ZkDb> { /// Set zktrie db. pub fn zktrie_db( self, - zktrie_db: &mut NodeDb, - ) -> EvmExecutorBuilder { + zktrie_db: &'a mut NodeDb, + ) -> EvmExecutorBuilder { EvmExecutorBuilder { hardfork_config: self.hardfork_config, + chain_id: self.chain_id, code_db: self.code_db, zktrie_db, } @@ -70,40 +90,36 @@ impl<'a, H, CodeDb, ZkDb> EvmExecutorBuilder<'a, H, CodeDb, ZkDb> { } impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> - EvmExecutorBuilder<'a, HardforkConfig, CodeDb, ZkDb> + EvmExecutorBuilder<'a, HardforkConfig, ChainId, CodeDb, ZkDb> { /// Initialize an EVM executor from a block trace as the initial state. - pub fn with_hooks<'h, T: Block, F: FnOnce(&mut ExecuteHooks<'h, CodeDb, ZkDb>)>( + pub fn with_hooks<'h, F: FnOnce(&mut ExecuteHooks<'h, CodeDb, ZkDb>)>( self, - l2_trace: &T, + root: B256, with_execute_hooks: F, ) -> Result, DatabaseError> { let mut execute_hooks = ExecuteHooks::new(); with_execute_hooks(&mut execute_hooks); - let block_number = l2_trace.number(); - let spec_id = self.hardfork_config.get_spec_id(block_number); - - dev_trace!("use spec id {:?}", spec_id); - let db = cycle_track!( - CacheDB::new(EvmDatabase::new(l2_trace, self.code_db, self.zktrie_db)?), + CacheDB::new(EvmDatabase::new_from_root( + root, + self.code_db, + self.zktrie_db + )?), "build ReadOnlyDB" ); Ok(EvmExecutor { hardfork_config: self.hardfork_config, + chain_id: self.chain_id, db, - spec_id, hooks: execute_hooks, }) } /// Initialize an EVM executor from a block trace as the initial state. - pub fn build<'e, T: Block>( - self, - l2_trace: &T, - ) -> Result, DatabaseError> { - self.with_hooks(l2_trace, |_| {}) + pub fn build<'e>(self, root: B256) -> Result, DatabaseError> { + self.with_hooks(root, |_| {}) } } diff --git a/crates/core/src/executor/mod.rs b/crates/core/src/executor/mod.rs index 838fb4f..0f3bd1d 100644 --- a/crates/core/src/executor/mod.rs +++ b/crates/core/src/executor/mod.rs @@ -2,20 +2,18 @@ use crate::{ database::EvmDatabase, error::DatabaseError, error::VerificationError, HardforkConfig, }; use revm::db::AccountState; +use revm::primitives::alloy_primitives::ChainId; use revm::primitives::{BlockEnv, TxEnv, U256}; use revm::{ db::CacheDB, - primitives::{AccountInfo, Env, SpecId, B256, KECCAK_EMPTY, POSEIDON_EMPTY}, + primitives::{AccountInfo, Env, B256, KECCAK_EMPTY, POSEIDON_EMPTY}, }; use sbv_primitives::{ zk_trie::{ db::kv::KVDatabase, - hash::{ - key_hasher::NoCacheHasher, - poseidon::{Poseidon, PoseidonError}, - }, + hash::{key_hasher::NoCacheHasher, poseidon::Poseidon}, scroll_types::Account, - trie::{ZkTrie, ZkTrieError}, + trie::ZkTrie, }, Block, Transaction, TxTrace, }; @@ -29,9 +27,9 @@ pub mod hooks; /// EVM executor that handles the block. pub struct EvmExecutor<'db, 'h, CodeDb, ZkDb> { + chain_id: ChainId, hardfork_config: HardforkConfig, db: CacheDB>, - spec_id: SpecId, hooks: hooks::ExecuteHooks<'h, CodeDb, ZkDb>, } @@ -41,9 +39,9 @@ impl EvmExecutor<'_, '_, CodeDb, &self.db } - /// Update the DB - pub fn update_db(&mut self, l2_trace: &T) -> Result<(), DatabaseError> { - self.db.db.update(l2_trace) + /// Insert codes from trace into CodeDB + pub fn insert_codes(&mut self, l2_trace: &T) -> Result<(), DatabaseError> { + self.db.db.insert_codes(l2_trace) } /// Handle a block. @@ -62,13 +60,15 @@ impl EvmExecutor<'_, '_, CodeDb, #[inline(always)] fn handle_block_inner(&mut self, l2_trace: &T) -> Result { + let spec_id = self.hardfork_config.get_spec_id(l2_trace.number()); + dev_trace!("use spec id {spec_id:?}",); self.hardfork_config .migrate(l2_trace.number(), &mut self.db) .unwrap(); dev_debug!("handle block {:?}", l2_trace.number()); let mut env = Box::::default(); - env.cfg.chain_id = l2_trace.chain_id(); + env.cfg.chain_id = self.chain_id; env.block = BlockEnv { number: U256::from_limbs([l2_trace.number(), 0, 0, 0]), coinbase: l2_trace.coinbase(), @@ -136,7 +136,7 @@ impl EvmExecutor<'_, '_, CodeDb, { let mut revm = cycle_track!( revm::Evm::builder() - .with_spec_id(self.spec_id) + .with_spec_id(spec_id) .with_db(&mut self.db) .with_env(env) // .with_external_context(CustomPrintTracer::default()) @@ -173,14 +173,11 @@ impl EvmExecutor<'_, '_, CodeDb, pub fn commit_changes(&mut self) -> Result { measure_duration_millis!( commit_changes_duration_milliseconds, - cycle_track!( - self.commit_changes_inner().map_err(DatabaseError::zk_trie), - "commit_changes" - ) + cycle_track!(self.commit_changes_inner(), "commit_changes") ) } - fn commit_changes_inner(&mut self) -> Result> { + fn commit_changes_inner(&mut self) -> Result { let mut zktrie = ZkTrie::::new_with_root( self.db.db.zktrie_db, NoCacheHasher, @@ -189,7 +186,10 @@ impl EvmExecutor<'_, '_, CodeDb, .expect("infallible"); #[cfg(any(feature = "debug-account", feature = "debug-storage"))] - let mut debug_recorder = sbv_utils::DebugRecorder::new(); + let mut debug_recorder = sbv_utils::DebugRecorder::new( + std::any::type_name_of_val(&self), + self.db.db.committed_zktrie_root(), + ); for (addr, db_acc) in self.db.accounts.iter() { // If EVM didn't touch the account, we don't need to update it @@ -202,6 +202,25 @@ impl EvmExecutor<'_, '_, CodeDb, if info.is_empty() { continue; } + if let Some(ref code) = info.code { + self.db + .db + .code_db + .or_put(info.code_hash.as_slice(), code.original_byte_slice()) + .unwrap(); + debug_assert_eq!( + info.code_hash, + code.hash_slow(), + "code hash mismatch for account {addr:?}", + ); + assert_eq!( + info.code_size, + code.original_bytes().len(), + "code size mismatch for account {addr:?}", + ); + #[cfg(any(feature = "debug-account", feature = "debug-storage"))] + debug_recorder.record_code(info.code_hash, code.bytecode().as_ref()); + } dev_trace!("committing {addr}, {:?} {db_acc:?}", db_acc.account_state); cycle_tracker_start!("commit account"); @@ -227,11 +246,9 @@ impl EvmExecutor<'_, '_, CodeDb, measure_duration_micros!( zktrie_update_duration_microseconds, cycle_track!( - storage_trie.update( - self.db.db.zktrie_db, - key.to_be_bytes::<32>(), - value - )?, + storage_trie + .update(self.db.db.zktrie_db, key.to_be_bytes::<32>(), value) + .map_err(DatabaseError::zk_trie)?, "Zktrie::update_store" ) ); @@ -240,7 +257,8 @@ impl EvmExecutor<'_, '_, CodeDb, zktrie_delete_duration_microseconds, cycle_track!( storage_trie - .delete(self.db.db.zktrie_db, key.to_be_bytes::<32>())?, + .delete(self.db.db.zktrie_db, key.to_be_bytes::<32>()) + .map_err(DatabaseError::zk_trie)?, "Zktrie::delete" ) ); @@ -252,7 +270,12 @@ impl EvmExecutor<'_, '_, CodeDb, measure_duration_micros!( zktrie_commit_duration_microseconds, - cycle_track!(storage_trie.commit(self.db.db.zktrie_db)?, "Zktrie::commit") + cycle_track!( + storage_trie + .commit(self.db.db.zktrie_db) + .map_err(DatabaseError::zk_trie)?, + "Zktrie::commit" + ) ); cycle_tracker_end!("update storage_tire"); @@ -301,22 +324,29 @@ impl EvmExecutor<'_, '_, CodeDb, measure_duration_micros!( zktrie_commit_duration_microseconds, - cycle_track!(zktrie.commit(self.db.db.zktrie_db)?, "Zktrie::commit") + cycle_track!( + zktrie + .commit(self.db.db.zktrie_db) + .map_err(DatabaseError::zk_trie)?, + "Zktrie::commit" + ) ); let root_after = *zktrie.root().unwrap_ref(); self.db.db.updated_committed_zktrie_root(root_after); + self.db.accounts.clear(); + self.db.contracts.clear(); + self.db.block_hashes.clear(); + self.db.logs.clear(); + Ok(B256::from(root_after)) } } impl Debug for EvmExecutor<'_, '_, CodeDb, ZkDb> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("EvmExecutor") - .field("db", &self.db) - .field("spec_id", &self.spec_id) - .finish() + f.debug_struct("EvmExecutor").field("db", &self.db).finish() } } diff --git a/crates/core/src/genesis.rs b/crates/core/src/genesis.rs new file mode 100644 index 0000000..39faa22 --- /dev/null +++ b/crates/core/src/genesis.rs @@ -0,0 +1,179 @@ +use crate::hardfork::{SCROLL_MAINNET_CHAIN_ID, SCROLL_TESTNET_CHAIN_ID}; +use once_cell::sync::Lazy; +use revm::primitives::{poseidon, KECCAK_EMPTY, POSEIDON_EMPTY}; +use sbv_primitives::{ + alloy_primitives::{keccak256, Bytes}, + zk_trie::{ + db::{kv::KVDatabase, NodeDb}, + hash::{key_hasher::KeyHasher, HashScheme}, + scroll_types::Account, + trie::{ZkTrie, ZkTrieError}, + }, + Address, B256, U256, +}; +use serde::Deserialize; +use std::borrow::Cow; +use std::collections::HashMap; + +static SCROLL_MAINNET_GENESIS: Lazy = Lazy::new(|| { + serde_json::from_str(include_str!("./data/genesis/genesis.mainnet.json")).unwrap() +}); + +static SCROLL_TESTNET_GENESIS: Lazy = Lazy::new(|| { + serde_json::from_str(include_str!("./data/genesis/genesis.sepolia.json")).unwrap() +}); + +/// Genesis configuration for Scroll networks. +#[derive(Debug)] +pub struct GenesisConfig { + config: Cow<'static, GethGenesisConfig>, +} + +impl GenesisConfig { + /// Create a new genesis configuration from the given chain ID. + pub fn default_from_chain_id(chain_id: u64) -> Self { + match chain_id { + SCROLL_MAINNET_CHAIN_ID => Self::mainnet(), + SCROLL_TESTNET_CHAIN_ID => Self::testnet(), + _ => panic!("unsupported chain id: {}", chain_id), + } + } + + /// Create a new mainnet genesis configuration. + pub fn mainnet() -> Self { + Self { + config: Cow::Borrowed(&*SCROLL_MAINNET_GENESIS), + } + } + + /// Create a new testnet genesis configuration. + pub fn testnet() -> Self { + Self { + config: Cow::Borrowed(&*SCROLL_TESTNET_GENESIS), + } + } + + /// Initialize the code database with the code of the accounts. + pub fn init_code_db(&self, code_db: &mut Db) -> Result<(), Db::Error> { + for acc in self.config.alloc.values() { + if acc.code.is_empty() { + continue; + } + + let code_hash = keccak256(&acc.code); + code_db.put(code_hash.as_ref(), acc.code.as_ref())?; + } + + code_db.put(KECCAK_EMPTY.as_ref(), &[])?; + + Ok(()) + } + + /// Initialize the zkTrie with the accounts. + pub fn init_zktrie + Clone>( + &self, + db: &mut NodeDb, + key_hasher: K, + ) -> Result, ZkTrieError> { + let mut zktrie = ZkTrie::::new(key_hasher.clone()); + for (addr, acc) in self.config.alloc.iter() { + let storage_root = if !acc.storage.is_empty() { + let mut storage_trie = ZkTrie::::new(key_hasher.clone()); + for (key, value) in acc.storage.iter() { + storage_trie.update(db, key.to_be_bytes::<32>(), value)?; + } + storage_trie.commit(db)?; + *storage_trie.root().unwrap_ref() + } else { + B256::ZERO + }; + + zktrie.update( + db, + addr, + Account { + nonce: 0, + code_size: acc.code.len() as u64, + balance: acc.balance, + storage_root, + code_hash: if acc.code.is_empty() { + KECCAK_EMPTY + } else { + keccak256(&acc.code) + }, + poseidon_code_hash: if acc.code.is_empty() { + POSEIDON_EMPTY + } else { + poseidon(&acc.code) + }, + }, + )?; + } + zktrie.commit(db)?; + + Ok(zktrie) + } + + /// Get the genesis coinbase configuration. + #[inline(always)] + pub fn coinbase(&self) -> Address { + self.config.config.scroll.fee_vault_address + } +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GethGenesisConfig { + pub config: GethGenesisBaseConfig, + // pub timestamp: U256, + // pub extra_data: Bytes, + // pub gas_limit: U256, + // pub coinbase: Address, + pub alloc: HashMap, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct GethGenesisBaseConfig { + // pub chain_id: ChainId, + pub scroll: ScrollGenesisConfig, +} + +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct ScrollGenesisConfig { + // pub max_tx_per_block: usize, + // pub max_tx_payload_bytes_per_block: usize, + pub fee_vault_address: Address, + // pub l1_config: ScrollL1Config, +} + +// #[derive(Clone, Debug, Deserialize)] +// #[serde(rename_all = "camelCase")] +// pub struct ScrollL1Config { +// pub l1_chain_id: U64, +// pub l1_message_queue_address: Address, +// pub num_l1_messages_per_block: U64, +// } + +#[derive(Clone, Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AllocAccount { + #[serde(default)] + pub balance: U256, + #[serde(default)] + pub code: Bytes, + #[serde(default)] + pub storage: HashMap, +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_deserialize_genesis() { + let _ = SCROLL_MAINNET_GENESIS.clone(); + let _ = SCROLL_TESTNET_GENESIS.clone(); + } +} diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 5d5779e..8c16077 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -2,6 +2,7 @@ #[macro_use] extern crate sbv_utils; +extern crate core; mod chunk; pub use chunk::ChunkInfo; @@ -15,6 +16,9 @@ pub use error::{DatabaseError, VerificationError}; mod executor; pub use executor::{hooks, EvmExecutor, EvmExecutorBuilder}; +mod genesis; +pub use genesis::GenesisConfig; + mod hardfork; pub use hardfork::HardforkConfig; diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 493b911..a6c8fb5 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -13,7 +13,7 @@ repository.workspace = true workspace = true [dependencies] -alloy = { workspace = true, features = ["consensus", "eips", "k256", "rlp", "rkyv", "serde"] } +alloy = { workspace = true, features = ["consensus", "eips", "k256", "rlp", "rkyv", "rpc-types", "serde"] } rkyv.workspace = true serde = { workspace = true, features = ["derive"] } serde_with.workspace = true @@ -30,4 +30,5 @@ serde_json.workspace = true [features] dev = ["sbv-utils/dev"] sp1 = [] -cycle-tracker = [] \ No newline at end of file +cycle-tracker = [] +sled = ["zktrie-ng/sled"] \ No newline at end of file diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 68a682b..39e8382 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -179,7 +179,7 @@ pub trait TxTrace { fn to(&self) -> TxKind; /// Get `chain_id`. - fn chain_id(&self) -> ChainId; + fn chain_id(&self) -> Option; /// Get `value`. fn value(&self) -> U256; @@ -203,12 +203,10 @@ pub trait TxTrace { /// Try to build a typed transaction fn try_build_typed_tx(&self) -> Result { - let chain_id = self.chain_id(); - let tx = match self.ty() { 0x0 => { let tx = TxLegacy { - chain_id: if self.v() >= 35 { Some(chain_id) } else { None }, + chain_id: self.chain_id(), nonce: self.nonce(), gas_price: self.gas_price(), gas_limit: self.gas_limit(), @@ -221,7 +219,7 @@ pub trait TxTrace { } 0x1 => { let tx = TxEip2930 { - chain_id, + chain_id: self.chain_id().unwrap(), nonce: self.nonce(), gas_price: self.gas_price(), gas_limit: self.gas_limit(), @@ -235,7 +233,7 @@ pub trait TxTrace { } 0x02 => { let tx = TxEip1559 { - chain_id, + chain_id: self.chain_id().unwrap(), nonce: self.nonce(), max_fee_per_gas: self.max_fee_per_gas(), max_priority_fee_per_gas: self.max_priority_fee_per_gas(), @@ -378,7 +376,7 @@ impl TxTrace for &T { (*self).to() } - fn chain_id(&self) -> ChainId { + fn chain_id(&self) -> Option { (*self).chain_id() } diff --git a/crates/primitives/src/types/mod.rs b/crates/primitives/src/types/mod.rs index 4f6fd73..408588f 100644 --- a/crates/primitives/src/types/mod.rs +++ b/crates/primitives/src/types/mod.rs @@ -13,7 +13,9 @@ use zktrie_ng::hash::poseidon::Poseidon; use zktrie_ng::trie::{ArchivedNode, Node, MAGIC_NODE_BYTES}; mod tx; -pub use tx::{ArchivedTransactionTrace, TransactionTrace, TxL1Msg, TypedTransaction}; +pub use tx::{ + AlloyTransaction, ArchivedTransactionTrace, TransactionTrace, TxL1Msg, TypedTransaction, +}; /// Block header #[derive( @@ -621,6 +623,80 @@ impl NodeProof for ArchivedArchivedNodeBytes { } } +impl Block for alloy::rpc::types::Block { + type Node = Bytes; + + type Tx = AlloyTransaction; + + fn number(&self) -> u64 { + self.header.number + } + + fn block_hash(&self) -> B256 { + self.header.hash + } + + fn chain_id(&self) -> u64 { + 0 + } + + fn coinbase(&self) -> Address { + self.header.miner + } + + fn timestamp(&self) -> U256 { + U256::from_limbs([self.header.timestamp, 0, 0, 0]) + } + + fn gas_limit(&self) -> U256 { + U256::from(self.header.gas_limit) + } + + fn gas_used(&self) -> U256 { + U256::from(self.header.gas_used) + } + + fn base_fee_per_gas(&self) -> Option { + self.header.base_fee_per_gas.map(U256::from) + } + + fn difficulty(&self) -> U256 { + self.header.difficulty + } + + fn prevrandao(&self) -> Option { + self.header.mix_hash + } + + fn transactions(&self) -> impl Iterator { + self.transactions.txns() + } + + fn root_before(&self) -> B256 { + unimplemented!() + } + + fn root_after(&self) -> B256 { + unimplemented!() + } + + fn withdraw_root(&self) -> B256 { + self.header.withdrawals_root.unwrap_or_default() + } + + fn codes(&self) -> impl ExactSizeIterator { + [].into_iter() + } + + fn start_l1_queue_index(&self) -> u64 { + unimplemented!() + } + + fn node_proofs(&self) -> impl Iterator { + [].into_iter() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/primitives/src/types/tx.rs b/crates/primitives/src/types/tx.rs index 5b8c372..1085f52 100644 --- a/crates/primitives/src/types/tx.rs +++ b/crates/primitives/src/types/tx.rs @@ -1,3 +1,4 @@ +use crate::alloy_primitives::{BlockHash, TxHash}; use crate::TxTrace; use alloy::{ consensus::{Transaction, TxEnvelope, TxType}, @@ -7,6 +8,7 @@ use alloy::{ rlp::{BufMut, BytesMut, Encodable, Header}, }; use rkyv::rancor; +use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DefaultOnNull}; /// Wrapped Ethereum Transaction @@ -163,13 +165,17 @@ impl TxTrace for TransactionTrace { if self.is_create { TxKind::Create } else { - debug_assert!(self.to.map(|a| !a.is_zero()).unwrap_or(false)); TxKind::Call(self.to.expect("to address must be present")) } } - fn chain_id(&self) -> ChainId { - self.chain_id.to() + fn chain_id(&self) -> Option { + let chain_id: ChainId = self.chain_id.to(); + if self.ty == 0 && chain_id < 35 { + None + } else { + Some(chain_id) + } } fn value(&self) -> U256 { @@ -249,9 +255,13 @@ impl TxTrace for ArchivedTransactionTrace { } } - fn chain_id(&self) -> ChainId { + fn chain_id(&self) -> Option { let chain_id: U64 = self.chain_id.into(); - chain_id.to() + if self.ty == 0 && self.v() < 35 { + None + } else { + Some(chain_id.to()) + } } fn value(&self) -> U256 { @@ -277,6 +287,180 @@ impl TxTrace for ArchivedTransactionTrace { } } +/// Transaction object used in RPC +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct AlloyTransaction { + /// Hash + pub hash: TxHash, + /// Nonce + #[serde(with = "alloy::serde::quantity")] + pub nonce: u64, + /// Block hash + #[serde(default)] + pub block_hash: Option, + /// Block number + #[serde(default, with = "alloy::serde::quantity::opt")] + pub block_number: Option, + /// Transaction Index + #[serde(default, with = "alloy::serde::quantity::opt")] + pub transaction_index: Option, + /// Sender + pub from: Address, + /// Recipient + pub to: Option
, + /// Transferred value + pub value: U256, + /// Gas Price + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + pub gas_price: Option, + /// Gas amount + #[serde(with = "alloy::serde::quantity")] + pub gas: u128, + /// Max BaseFeePerGas the user is willing to pay. + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + pub max_fee_per_gas: Option, + /// The miner's tip. + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + pub max_priority_fee_per_gas: Option, + /// Configured max fee per blob gas for eip-4844 transactions + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + pub max_fee_per_blob_gas: Option, + /// Data + pub input: Bytes, + /// All _flattened_ fields of the transaction signature. + /// + /// Note: this is an option so special transaction types without a signature (e.g. ) can be supported. + #[serde(flatten, skip_serializing_if = "Option::is_none")] + pub signature: Option, + /// The chain id of the transaction, if any. + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + pub chain_id: Option, + /// Contains the blob hashes for eip-4844 transactions. + #[serde(skip_serializing_if = "Option::is_none")] + pub blob_versioned_hashes: Option>, + /// EIP2930 + /// + /// Pre-pay to warm storage access. + #[serde(skip_serializing_if = "Option::is_none")] + pub access_list: Option, + /// EIP2718 + /// + /// Transaction type, + /// Some(4) for EIP-7702 transaction, Some(3) for EIP-4844 transaction, Some(2) for EIP-1559 + /// transaction, Some(1) for AccessList transaction, None or Some(0) for Legacy + #[serde( + default, + rename = "type", + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + #[doc(alias = "tx_type")] + pub transaction_type: Option, + /// The signed authorization list is a list of tuples that store the address to code which the + /// signer desires to execute in the context of their EOA and their signature. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub authorization_list: Option>, + + /// L1Msg queueIndex + #[serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy::serde::quantity::opt" + )] + pub queue_index: Option, +} + +impl TxTrace for AlloyTransaction { + fn tx_hash(&self) -> B256 { + self.hash + } + + fn ty(&self) -> u8 { + self.transaction_type.unwrap_or(0) + } + + fn nonce(&self) -> u64 { + if self.ty() != 0x7e { + self.nonce + } else { + self.queue_index.unwrap() + } + } + + fn gas_limit(&self) -> u128 { + self.gas + } + + fn gas_price(&self) -> u128 { + self.gas_price.unwrap_or(0) + } + + fn max_fee_per_gas(&self) -> u128 { + self.max_fee_per_gas.unwrap_or(0) + } + + fn max_priority_fee_per_gas(&self) -> u128 { + self.max_priority_fee_per_gas.unwrap_or(0) + } + + unsafe fn get_from_unchecked(&self) -> Address { + self.from + } + + fn to(&self) -> TxKind { + match self.to { + Some(addr) => TxKind::Call(addr), + None => TxKind::Create, + } + } + + fn chain_id(&self) -> Option { + self.chain_id + } + + fn value(&self) -> U256 { + self.value + } + + fn data(&self) -> Bytes { + self.input.clone() + } + + fn access_list(&self) -> AccessList { + self.access_list.clone().unwrap_or_default() + } + + fn v(&self) -> u64 { + self.signature.unwrap().v.to() + } + + fn signature(&self) -> Result { + let sig = self.signature.unwrap(); + Signature::from_rs_and_parity(sig.r, sig.s, sig.v.to::()) + } +} + impl Transaction for TypedTransaction { fn chain_id(&self) -> Option { match self { diff --git a/crates/sbv/Cargo.toml b/crates/sbv/Cargo.toml index 0195497..8cdf622 100644 --- a/crates/sbv/Cargo.toml +++ b/crates/sbv/Cargo.toml @@ -19,6 +19,7 @@ debug-account = ["sbv-core/debug-account", "sbv-utils/debug-account"] debug-storage = ["sbv-core/debug-storage", "sbv-utils/debug-storage"] dev = ["sbv-core/dev", "sbv-utils/dev", "sbv-primitives/dev"] metrics = ["sbv-core/metrics", "sbv-utils/metrics"] +sled = ["sbv-primitives/sled"] # sp1 related sp1 = ["sbv-core/sp1", "sbv-primitives/sp1"] diff --git a/crates/stateful/Cargo.toml b/crates/stateful/Cargo.toml new file mode 100644 index 0000000..96cbab2 --- /dev/null +++ b/crates/stateful/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "stateful-block-verifier" +homepage = "https://github.com/scroll-tech/stateless-block-verifier/tree/master/crates/bin" + +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +alloy = { workspace = true, features = ["provider-http", "serde", "transport-http"] } +anyhow.workspace = true +clap = { workspace = true, features = ["derive"] } +revm.workspace = true +sled.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +thiserror.workspace = true +tokio = { workspace = true, features = ["fs", "io-util", "macros", "rt-multi-thread", "signal", "sync", "time"] } +tokio-retry.workspace = true +url.workspace = true + +sbv = { workspace = true, features = ["sled"]} + +tracing-subscriber = { workspace = true, optional = true } + +[features] +default = ["dev"] +dev = ["sbv/dev", "dep:tracing-subscriber"] +debug-account = ["sbv/debug-account"] +debug-storage = ["sbv/debug-storage"] + +[lints] +workspace = true + diff --git a/crates/stateful/src/error.rs b/crates/stateful/src/error.rs new file mode 100644 index 0000000..1e05fa7 --- /dev/null +++ b/crates/stateful/src/error.rs @@ -0,0 +1,31 @@ +use alloy::transports::{RpcError, TransportErrorKind}; +use sbv::primitives::zk_trie::{hash::poseidon::PoseidonError, trie::ZkTrieError}; + +/// Stateful block verifier error +#[derive(thiserror::Error, Debug)] +pub enum Error { + /// Provider error + #[error(transparent)] + Provider(#[from] RpcError), + /// Sled error + #[error(transparent)] + Sled(#[from] sled::Error), + /// Zktrie error + #[error(transparent)] + Zktrie(#[from] ZkTrieError), + /// Evm database error + #[error(transparent)] + EvmDatabase(#[from] sbv::core::DatabaseError), + /// Evm verification error + #[error(transparent)] + EvmVerification(#[from] sbv::core::VerificationError), + /// Invalid block number + #[error("expected sequential block")] + ExpectedSequentialBlock, + /// Post state root mismatch + #[error("post state root mismatch")] + PostStateRootMismatch, + /// Pipeline shutdown + #[error("pipeline shutdown")] + PipelineShutdown, +} diff --git a/crates/stateful/src/lib.rs b/crates/stateful/src/lib.rs new file mode 100644 index 0000000..d98d934 --- /dev/null +++ b/crates/stateful/src/lib.rs @@ -0,0 +1,351 @@ +//! stateful module +#[macro_use] +extern crate sbv; + +use crate::pipeline::Fetcher; +use alloy::providers::{Provider, ReqwestProvider}; +use alloy::rpc::types::Block; +use sbv::{ + core::{EvmExecutorBuilder, GenesisConfig, HardforkConfig}, + primitives::{ + alloy_primitives::ChainId, + types::AlloyTransaction, + zk_trie::{ + db::{kv::SledDb, NodeDb}, + hash::{key_hasher::NoCacheHasher, poseidon::Poseidon, ZkHash}, + }, + }, +}; +use sled::Tree; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; + +mod error; +/// pipeline +pub mod pipeline; +/// sanity check +pub mod sanity_check; +/// utils +pub mod utils; + +pub use error::Error; + +/// Result alias +pub type Result = std::result::Result; + +/// Stateful Block Executor +#[derive(Debug)] +pub struct StatefulBlockExecutor { + db: sled::Db, + provider: ReqwestProvider, + + chain_id: ChainId, + genesis_config: GenesisConfig, + hardfork_config: HardforkConfig, + + metadata: Metadata, + + history_db: HistoryDb, + code_db: SledDb, + zktrie_db: NodeDb, + + pipeline_rx: tokio::sync::mpsc::Receiver>, + shutdown: Arc, +} + +impl StatefulBlockExecutor { + /// Create a new stateful block executor + pub async fn new(db: sled::Db, provider: ReqwestProvider) -> Result { + let chain_id = retry_if_transport_error!(provider.get_chain_id())?; + dev_info!("chain_id: {chain_id}"); + + let genesis_config = GenesisConfig::default_from_chain_id(chain_id); + dev_info!("genesis_config: {genesis_config:?}"); + let hardfork_config = HardforkConfig::default_from_chain_id(chain_id); + dev_info!("hardfork_config: {hardfork_config:?}"); + + let metadata = Metadata::open(&db, chain_id)?; + let history_db = metadata.open_history_db(&db)?; + + let mut code_db = metadata.open_code_db(&db)?; + let mut zktrie_db = metadata.open_zktrie_db(&db)?; + if metadata.needs_init() { + genesis_config.init_code_db(&mut code_db)?; + let zktrie = + genesis_config.init_zktrie::(&mut zktrie_db, NoCacheHasher)?; + history_db.set_block_storage_root(0, *zktrie.root().unwrap_ref())?; + } + + let shutdown = Arc::new(AtomicBool::new(false)); + + let pipeline_rx = Fetcher::spawn( + 20, + provider.clone(), + genesis_config.coinbase(), + chain_id, + metadata.latest_block_number() + 1, + shutdown.clone(), + ); + + Ok(Self { + db, + provider, + chain_id, + genesis_config, + hardfork_config, + metadata, + history_db, + code_db, + zktrie_db, + pipeline_rx, + shutdown, + }) + } + + /// Execute a block + fn execute_block(&mut self, block: &Block) -> Result<()> { + if self.metadata.latest_block_number() + 1 != block.header.number { + return Err(Error::ExpectedSequentialBlock); + } + + let block_number = block.header.number; + let storage_root_before = self + .history_db + .get_block_storage_root(block_number - 1)? + .expect("prev block storage root not found"); + + let mut evm = EvmExecutorBuilder::new(&mut self.code_db, &mut self.zktrie_db) + .chain_id(self.chain_id) + .hardfork_config(self.hardfork_config) + .build(storage_root_before)?; + evm.handle_block(&block)?; + let storage_root_after = evm.commit_changes()?; + self.history_db + .set_block_storage_root(block_number, storage_root_after)?; + + if block.header.state_root != storage_root_after { + return Err(Error::PostStateRootMismatch); + } + self.metadata.set_latest_block_number(block_number)?; + Ok(()) + } + + /// Run forever + pub async fn run(&mut self) -> Result<()> { + let mut blocks_handled = 0; + let mut last_time = std::time::Instant::now(); + loop { + let fetch_start = std::time::Instant::now(); + match self.pipeline_rx.recv().await { + Some(block) => { + let block_number = block.header.number; + + let elapsed = fetch_start.elapsed(); + if elapsed > std::time::Duration::from_millis(500) { + dev_warn!("receive block#{block_number} from pipeline took {elapsed:?}, is the provider overloaded?"); + } + + #[cfg(debug_assertions)] + { + sanity_check::check_stateless( + &self.provider, + self.chain_id, + self.hardfork_config, + self.history_db + .get_block_storage_root(block_number - 1)? + .unwrap(), + &block, + ) + .await?; + } + + let execute_start = std::time::Instant::now(); + match self.execute_block(&block) { + Ok(_) => { + dev_trace!( + "block#{block_number} stateful check ok in {:?}", + execute_start.elapsed() + ); + + blocks_handled += 1; + if last_time.elapsed() > std::time::Duration::from_secs(10) { + let elapsed = last_time.elapsed(); + last_time = std::time::Instant::now(); + let blocks_per_sec = blocks_handled as f64 / elapsed.as_secs_f64(); + dev_info!( + "handled {blocks_handled} blocks in {elapsed:.2?}, {blocks_per_sec:.2} blocks/s, latest block: {block_number}", + ); + if let Ok(latest) = self.provider.get_block_number().await { + let estimate_hours = (latest - block_number) as f64 + / blocks_per_sec + / 60.0 + / 60.0; + dev_info!("estimate time to catch up: {estimate_hours:.2?}h",); + } + + blocks_handled = 0; + } + } + Err(e) => { + dev_error!("block#{block_number} stateful check failed: {e}"); + self.shutdown + .store(true, std::sync::atomic::Ordering::SeqCst); + return Err(e); + } + } + } + None => { + dev_error!("pipeline shutdown"); + return Err(Error::PipelineShutdown); + } + } + } + } + + /// Shutdown the executor + #[inline(always)] + pub fn shutdown(&self) { + self.shutdown + .store(true, std::sync::atomic::Ordering::SeqCst); + } + + /// Get the sled db + #[inline(always)] + pub fn db(&self) -> &sled::Db { + &self.db + } + + /// Get the provider + #[inline(always)] + pub fn provider(&self) -> ReqwestProvider { + self.provider.clone() + } + + /// Get the chain id + #[inline(always)] + pub fn chain_id(&self) -> ChainId { + self.chain_id + } + + /// Get the genesis config + #[inline(always)] + pub fn genesis_config(&self) -> &GenesisConfig { + &self.genesis_config + } + + /// Get the hardfork config + #[inline(always)] + pub fn hardfork_config(&self) -> &HardforkConfig { + &self.hardfork_config + } + + /// Get the metadata + #[inline(always)] + pub fn metadata(&self) -> &Metadata { + &self.metadata + } + + /// Get the history db + #[inline(always)] + pub fn history_db(&self) -> &HistoryDb { + &self.history_db + } +} + +/// Metadata +#[derive(Debug)] +pub struct Metadata { + db: Tree, + chain_id: u64, + latest_block_number: u64, +} + +impl Metadata { + /// Open metadata from sled db + pub fn open(db: &sled::Db, chain_id: u64) -> Result { + let db = db.open_tree(format!("metadata_chain_{chain_id}"))?; + + let latest_block_number = db + .get("latest_block_number")? + .map(|v| u64::from_le_bytes(v.as_ref().try_into().unwrap())) + .unwrap_or_default(); + + Ok(Self { + db, + chain_id, + latest_block_number, + }) + } + + /// Set the latest block number + #[inline(always)] + pub fn set_latest_block_number(&mut self, block_number: u64) -> Result<()> { + self.db + .insert("latest_block_number", &block_number.to_le_bytes())?; + self.latest_block_number = block_number; + Ok(()) + } + + /// Get the latest block number + #[inline(always)] + pub fn latest_block_number(&self) -> u64 { + self.latest_block_number + } + + /// Check if the db needs initialization + #[inline(always)] + pub fn needs_init(&self) -> bool { + self.latest_block_number == 0 + } + + /// Open the code db + #[inline(always)] + pub fn open_code_db(&self, db: &sled::Db) -> Result { + Ok(SledDb::new( + true, + db.open_tree(format!("code_db_chain_{}", self.chain_id))?, + )) + } + + /// Open the zktrie db + #[inline(always)] + pub fn open_zktrie_db(&self, db: &sled::Db) -> Result> { + Ok(NodeDb::new(SledDb::new( + true, + db.open_tree(format!("zktrie_db_chain_{}", self.chain_id))?, + ))) + } + + /// Open the history db + #[inline(always)] + pub fn open_history_db(&self, db: &sled::Db) -> Result { + Ok(HistoryDb { + db: db.open_tree(format!("history_db_chain_{}", self.chain_id))?, + }) + } +} + +/// History database +#[derive(Debug)] +pub struct HistoryDb { + db: Tree, +} + +impl HistoryDb { + /// Set the block storage root + #[inline(always)] + pub fn set_block_storage_root(&self, block_number: u64, storage_root: ZkHash) -> Result<()> { + self.db + .insert(block_number.to_le_bytes(), &storage_root.0)?; + Ok(()) + } + + /// Get the block storage root + #[inline(always)] + pub fn get_block_storage_root(&self, block_number: u64) -> Result> { + Ok(self + .db + .get(block_number.to_le_bytes())? + .map(|v| ZkHash::from_slice(v.as_ref()))) + } +} diff --git a/crates/stateful/src/main.rs b/crates/stateful/src/main.rs new file mode 100644 index 0000000..c529a51 --- /dev/null +++ b/crates/stateful/src/main.rs @@ -0,0 +1,44 @@ +//! This is a simple example of how to use the stateful executor to verify the state transition of the L2 chain. + +use alloy::providers::ProviderBuilder; +use clap::Parser; +use stateful_block_verifier::StatefulBlockExecutor; +use std::path::PathBuf; +use url::Url; + +#[cfg(feature = "dev")] +use tracing_subscriber::EnvFilter; + +#[derive(Parser)] +struct Cli { + /// RPC URL + #[arg(short, long, default_value = "http://localhost:8545")] + url: Url, + /// Path to the sled database + #[arg(short, long)] + db: PathBuf, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + #[cfg(feature = "dev")] + tracing_subscriber::fmt() + .with_env_filter( + EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")), + ) + .init(); + + let cmd = Cli::parse(); + + let provider = ProviderBuilder::new().on_http(cmd.url); + let mut executor = StatefulBlockExecutor::new(sled::open(cmd.db)?, provider.clone()).await?; + + tokio::select! { + _ = executor.run() => {} + _ = tokio::signal::ctrl_c() => { + executor.shutdown(); + } + } + + Ok(()) +} diff --git a/crates/stateful/src/pipeline.rs b/crates/stateful/src/pipeline.rs new file mode 100644 index 0000000..d2e29d0 --- /dev/null +++ b/crates/stateful/src/pipeline.rs @@ -0,0 +1,154 @@ +use crate::utils::patch_fix_block; +use crate::{retry_if_transport_error, Error, Result}; +use alloy::providers::{Provider, ReqwestProvider}; +use alloy::rpc::types::Block; +use sbv::primitives::{alloy_primitives::ChainId, types::AlloyTransaction, Address}; +use std::collections::BinaryHeap; +use std::fmt::Debug; +use std::sync::{ + atomic::{AtomicBool, AtomicU64}, + Arc, +}; +use tokio::sync::Mutex; + +struct OrderedQueue { + queue: BinaryHeap, + sender_index: u64, +} + +/// Fetcher to fetch blocks from the provider. +#[derive(Clone, Debug)] +pub struct Fetcher { + count: usize, + provider: ReqwestProvider, + coinbase: Address, + chain_id: ChainId, + + queue: Arc>, + fetcher_index: Arc, + tx: tokio::sync::mpsc::Sender>, + shutdown: Arc, +} + +#[derive(Eq, PartialEq)] +struct FetchedBlock(Block); + +impl Fetcher { + /// Spawn `count` fetchers to fetch blocks from the provider. + pub fn spawn( + count: usize, + provider: ReqwestProvider, + coinbase: Address, + chain_id: ChainId, + start_block: u64, + shutdown: Arc, + ) -> tokio::sync::mpsc::Receiver> { + let (tx, rx) = tokio::sync::mpsc::channel(count); + + let queue = OrderedQueue { + queue: BinaryHeap::new(), + sender_index: start_block, + }; + + let fetcher = Fetcher { + count, + provider, + coinbase, + chain_id, + queue: Arc::new(Mutex::new(queue)), + fetcher_index: Arc::new(AtomicU64::new(start_block)), + tx, + shutdown: shutdown.clone(), + }; + + for _ in 0..count { + let fetcher = fetcher.clone(); + let shutdown = shutdown.clone(); + tokio::spawn(async move { + fetcher.run().await.ok(); + shutdown.store(true, std::sync::atomic::Ordering::SeqCst); + }); + } + + rx + } + + async fn run(self) -> Result<()> { + while !self.shutdown.load(std::sync::atomic::Ordering::SeqCst) { + loop { + let queue = self.queue.lock().await; + // back pressure + if queue.queue.len() >= self.count { + drop(queue); + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + continue; + } + break; + } + + let block_number = self + .fetcher_index + .fetch_add(1, std::sync::atomic::Ordering::SeqCst); + + // wait for new block + while let Ok(latest_chain_block_number) = + retry_if_transport_error!(self.provider.get_block_number()) + { + if block_number <= latest_chain_block_number { + break; + } + tokio::time::sleep(std::time::Duration::from_secs(1)).await; + } + + let mut block = retry_if_transport_error!(self + .provider + .raw_request::<_, Block>( + "eth_getBlockByNumber".into(), + (format!("0x{:x}", block_number), true), + ))?; + patch_fix_block(&mut block, self.coinbase, self.chain_id); + + dev_trace!( + "block#{} block fetched, state root: {}", + block.header.number, + block.header.state_root + ); + + let mut queue = self.queue.lock().await; + queue.queue.push(FetchedBlock(block)); + while queue + .queue + .peek() + .map(|b| b.0.header.number == queue.sender_index) + .unwrap_or_default() + { + let block = queue.queue.pop().unwrap().0; + if self.tx.send(block).await.is_err() { + return Err(Error::PipelineShutdown); + } + queue.sender_index += 1; + } + } + Ok(()) + } +} + +impl Debug for OrderedQueue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("OrderedQueue") + .field("sender_index", &self.sender_index) + .finish() + } +} + +impl Ord for FetchedBlock { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.header.number.cmp(&other.0.header.number).reverse() + } +} + +impl PartialOrd for FetchedBlock { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} diff --git a/crates/stateful/src/sanity_check.rs b/crates/stateful/src/sanity_check.rs new file mode 100644 index 0000000..4f30779 --- /dev/null +++ b/crates/stateful/src/sanity_check.rs @@ -0,0 +1,132 @@ +use crate::{retry_if_transport_error, Result}; +use alloy::primitives::ChainId; +use alloy::providers::{Provider, ReqwestProvider}; +use revm::primitives::BlockEnv; +use sbv::{ + core::{EvmExecutorBuilder, HardforkConfig}, + primitives::{ + types::{AlloyTransaction, BlockTrace, LegacyStorageTrace}, + zk_trie::db::{kv::HashMapDb, NodeDb}, + Block, Transaction, TxTrace, B256, U256, + }, +}; + +/// Assert that the given L2 trace and block are equal. +pub fn assert_equal(l2_trace: impl Block, block: impl Block) { + let trace_block_env = BlockEnv { + number: U256::from_limbs([l2_trace.number(), 0, 0, 0]), + coinbase: l2_trace.coinbase(), + timestamp: l2_trace.timestamp(), + gas_limit: l2_trace.gas_limit(), + basefee: l2_trace.base_fee_per_gas().unwrap_or_default(), + difficulty: l2_trace.difficulty(), + prevrandao: l2_trace.prevrandao(), + blob_excess_gas_and_price: None, + }; + let block_block_env = BlockEnv { + number: U256::from_limbs([block.number(), 0, 0, 0]), + coinbase: block.coinbase(), + timestamp: block.timestamp(), + gas_limit: block.gas_limit(), + basefee: block.base_fee_per_gas().unwrap_or_default(), + difficulty: block.difficulty(), + prevrandao: block.prevrandao(), + blob_excess_gas_and_price: None, + }; + assert_eq!(trace_block_env, block_block_env, "block_env mismatch"); + for (i, (trace_tx, block_tx)) in l2_trace + .transactions() + .zip(block.transactions()) + .enumerate() + { + let trace_tx = trace_tx.try_build_typed_tx().unwrap(); + let block_tx = block_tx.try_build_typed_tx().unwrap(); + assert_eq!(trace_tx, block_tx, "tx#{i} mismatch {block_tx:?}"); + let trace_tx_signer = trace_tx.get_or_recover_signer().unwrap(); + let block_tx_signer = block_tx.get_or_recover_signer().unwrap(); + assert_eq!(trace_tx_signer, block_tx_signer, "tx#{i} signer mismatch"); + let trace_gas_limit = trace_tx.gas_limit(); + let block_gas_limit = block_tx.gas_limit(); + assert_eq!( + trace_gas_limit, block_gas_limit, + "tx#{i} gas limit mismatch" + ); + let trace_gas_price = trace_tx + .effective_gas_price(l2_trace.base_fee_per_gas().unwrap_or_default().to()) + .map(U256::from); + let block_gas_price = block_tx + .effective_gas_price(l2_trace.base_fee_per_gas().unwrap_or_default().to()) + .map(U256::from); + assert_eq!( + trace_gas_price, block_gas_price, + "tx#{i} gas price mismatch" + ); + assert_eq!(trace_tx.to(), block_tx.to(), "tx#{i} transact_to mismatch"); + assert_eq!(trace_tx.value(), block_tx.value(), "tx#{i} value mismatch"); + assert_eq!(trace_tx.data(), block_tx.data(), "tx#{i} data mismatch"); + assert_eq!( + trace_tx.is_l1_msg(), + block_tx.is_l1_msg(), + "tx#{i} is_l1_msg mismatch" + ); + assert_eq!(trace_tx.nonce(), block_tx.nonce(), "tx#{i} nonce mismatch"); + assert_eq!( + trace_tx.chain_id(), + block_tx.chain_id(), + "tx#{i} chain_id mismatch" + ); + assert_eq!( + trace_tx.access_list(), + block_tx.access_list(), + "tx#{i} access_list mismatch" + ); + assert_eq!( + trace_tx.max_priority_fee_per_gas(), + block_tx.max_priority_fee_per_gas(), + "tx#{i} max_priority_fee_per_gas mismatch" + ); + assert_eq!(trace_tx.rlp(), block_tx.rlp(), "tx#{i} rlp mismatch"); + } +} + +/// Check the stateful execution of the given block. +pub async fn check_stateless( + provider: &ReqwestProvider, + chain_id: ChainId, + hardfork_config: HardforkConfig, + storage_root_before: B256, + block: &alloy::rpc::types::Block, +) -> Result { + let block_number = block.header.number; + let l2_trace = retry_if_transport_error!(provider + .raw_request::<_, BlockTrace>( + "scroll_getBlockTraceByNumberOrHash".into(), + (format!("0x{:x}", block_number),), + ))?; + let l2_trace: BlockTrace = l2_trace.into(); + let root_before = l2_trace.root_before(); + let root_after = l2_trace.root_after(); + + assert_eq!(root_before, storage_root_before); + dev_info!( + "block#{block_number} trace fetched, root_before: {root_before}, root_after: {root_after}" + ); + + { + let mut code_db = HashMapDb::default(); + let mut zktrie_db = NodeDb::new(HashMapDb::default()); + l2_trace.build_zktrie_db(&mut zktrie_db).unwrap(); + let mut executor = EvmExecutorBuilder::new(&mut code_db, &mut zktrie_db) + .hardfork_config(hardfork_config) + .chain_id(chain_id) + .build(root_before)?; + executor.insert_codes(&l2_trace)?; + executor.handle_block(&l2_trace)?; + let revm_root_after = executor.commit_changes()?; + assert_eq!(root_after, revm_root_after); + dev_info!("block#{block_number} stateless check ok"); + } + assert_equal(&l2_trace, block); + + Ok(root_after) +} diff --git a/crates/stateful/src/utils.rs b/crates/stateful/src/utils.rs new file mode 100644 index 0000000..dbb3caf --- /dev/null +++ b/crates/stateful/src/utils.rs @@ -0,0 +1,64 @@ +use alloy::primitives::ChainId; +use alloy::rpc::types::BlockTransactions; +use alloy::transports::{RpcError, TransportErrorKind}; +use sbv::dev_warn; +use sbv::primitives::types::AlloyTransaction; +use sbv::primitives::Address; +use std::future::Future; +use tokio_retry::strategy::{jitter, ExponentialBackoff}; +use tokio_retry::RetryIf; + +/// Retry the given future if it returns a transport error. +#[inline(always)] +pub fn retry_if_transport_error( + f: F, +) -> impl Future>> +where + F: FnMut() -> Fut, + Fut: Future>>, +{ + RetryIf::spawn( + ExponentialBackoff::from_millis(10).map(jitter).take(10), + f, + |e: &RpcError| { + if e.is_transport_error() { + dev_warn!("retrying request due to transport error: {:?}", e); + true + } else { + false + } + }, + ) +} + +/// Retry the given future if it returns a transport error. +#[macro_export] +macro_rules! retry_if_transport_error { + ($fut:expr) => { + $crate::utils::retry_if_transport_error(|| async { $fut.await }).await + }; +} + +/// Patch the given block to fix the miner and chain_id. +#[inline(always)] +pub fn patch_fix_block( + block: &mut alloy::rpc::types::Block, + coinbase: Address, + chain_id: ChainId, +) { + // Clique, which uses header.miner for a different purpose. in particular, header.miner != coinbase. + block.header.miner = coinbase; + + if let BlockTransactions::Full(ref mut txs) = block.transactions { + for (idx, tx) in txs.iter_mut().enumerate() { + let tx_type = tx.transaction_type.unwrap_or(0); + if tx_type == 0 && tx.signature.unwrap().v.to::() >= 35 { + tx.chain_id = Some(chain_id); + dev_trace!( + "block#{block_number} tx#{idx} is Eip155 tx but chain_id is not set", + block_number = block.header.number + ); + } + } + } +} diff --git a/crates/utils/src/utils/debug.rs b/crates/utils/src/utils/debug.rs index 8996462..5cf5b6c 100644 --- a/crates/utils/src/utils/debug.rs +++ b/crates/utils/src/utils/debug.rs @@ -1,5 +1,7 @@ -use revm::primitives::{AccountInfo, Address, B256, U256}; +use revm::primitives::{hex, AccountInfo, Address, B256, U256}; use std::collections::BTreeMap; +use std::io::Write; +use std::path::PathBuf; #[derive(Debug, serde::Serialize)] struct StorageOps { @@ -20,20 +22,30 @@ struct AccountData { } /// Debug recorder for recording account and storage data. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct DebugRecorder { + base_dir: PathBuf, accounts: BTreeMap, storages_roots: BTreeMap, storages: BTreeMap>, + codes: BTreeMap>, } impl DebugRecorder { /// Create a new debug recorder. - pub fn new() -> Self { + pub fn new(prefix: &str, prev_root: B256) -> Self { + let base_dir = PathBuf::from(format!("/tmp/sbv-debug/{prefix}/{prev_root:?}")); + #[cfg(any(feature = "debug-account", feature = "debug-storage"))] - std::fs::create_dir_all("/tmp/sbv-debug").expect("failed to create debug dir"); + std::fs::create_dir_all(&base_dir).expect("failed to create debug dir"); - Self::default() + Self { + base_dir, + accounts: BTreeMap::new(), + storages_roots: BTreeMap::new(), + storages: BTreeMap::new(), + codes: BTreeMap::new(), + } } /// Record the account data. @@ -84,29 +96,45 @@ impl DebugRecorder { ); } } + + /// Record the code + #[cfg(feature = "debug-account")] + pub fn record_code(&mut self, code_hash: B256, code: &[u8]) { + self.codes.insert(code_hash, code.to_owned()); + } } impl Drop for DebugRecorder { fn drop(&mut self) { #[cfg(feature = "debug-account")] { - let output = std::fs::File::create("/tmp/sbv-debug/accounts.csv") + let output = std::fs::File::create(self.base_dir.join("accounts.csv")) .expect("failed to create debug file"); let mut wtr = csv::Writer::from_writer(output); for (_, acc) in self.accounts.iter() { wtr.serialize(acc).expect("failed to write record"); } + + for (code_hash, code) in self.codes.iter() { + let mut output = + std::fs::File::create(self.base_dir.join(format!("code_{code_hash:?}.txt"))) + .expect("failed to create debug file"); + let code = hex::encode(code); + output + .write_all(code.as_bytes()) + .expect("failed to write code"); + } } #[cfg(feature = "debug-storage")] { for (addr, storages) in self.storages.iter() { let storage_root = self.storages_roots.get(addr).copied().unwrap_or_default(); - let output = std::fs::File::create(format!( - "/tmp/sbv-debug/storage_{:?}_{:?}.csv", - addr, storage_root - )) + let output = std::fs::File::create( + self.base_dir + .join(format!("storage_{addr:?}_{storage_root:?}.csv")), + ) .expect("failed to create debug file"); let mut wtr = csv::Writer::from_writer(output); for ops in storages.values() {