diff --git a/Cargo.lock b/Cargo.lock index 0038369..b92f737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -76,12 +76,12 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.1.29" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb07629a5d0645d29f68d2fb6f4d0cf15c89ec0965be915f303967180929743f" +checksum = "abf770dad29577cd3580f3dd09005799224a912b8cdfdd6dc04d030d42b3df4e" dependencies = [ "num_enum", - "strum 0.26.3", + "strum", ] [[package]] @@ -378,11 +378,10 @@ dependencies = [ [[package]] name = "alloy-sol-macro" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "183bcfc0f3291d9c41a3774172ee582fb2ce6eb6569085471d8f225de7bb86fc" +source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" dependencies = [ - "alloy-sol-macro-expander 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "alloy-sol-macro-input 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "alloy-sol-macro-expander 0.8.0", + "alloy-sol-macro-input 0.8.0", "proc-macro-error", "proc-macro2", "quote", @@ -391,12 +390,13 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0458ccb02a564228fcd76efb8eb5a520521a8347becde37b402afec9a1b83859" dependencies = [ - "alloy-sol-macro-expander 0.8.0 (git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0)", - "alloy-sol-macro-input 0.8.0 (git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0)", - "proc-macro-error", + "alloy-sol-macro-expander 0.8.3", + "alloy-sol-macro-input 0.8.3", + "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.77", @@ -405,65 +405,65 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c4d842beb7a6686d04125603bc57614d5ed78bf95e4753274db3db4ba95214" +source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" dependencies = [ - "alloy-sol-macro-input 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "alloy-sol-macro-input 0.8.0", "const-hex", - "heck 0.5.0", + "heck", "indexmap 2.5.0", "proc-macro-error", "proc-macro2", "quote", "syn 2.0.77", - "syn-solidity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn-solidity 0.8.0", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-expander" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc65475025fc1e84bf86fc840f04f63fcccdcf3cf12053c99918e4054dfbc69" dependencies = [ - "alloy-sol-macro-input 0.8.0 (git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0)", + "alloy-sol-macro-input 0.8.3", "const-hex", - "heck 0.5.0", + "heck", "indexmap 2.5.0", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", "syn 2.0.77", - "syn-solidity 0.8.0 (git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0)", + "syn-solidity 0.8.3", "tiny-keccak", ] [[package]] name = "alloy-sol-macro-input" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1306e8d3c9e6e6ecf7a39ffaf7291e73a5f655a2defd366ee92c2efebcdf7fee" +source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" dependencies = [ "const-hex", "dunce", - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.77", - "syn-solidity 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn-solidity 0.8.0", ] [[package]] name = "alloy-sol-macro-input" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed10f0715a0b69fde3236ff3b9ae5f6f7c97db5a387747100070d3016b9266b" dependencies = [ "const-hex", "dunce", - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.77", - "syn-solidity 0.8.0 (git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0)", + "syn-solidity 0.8.3", ] [[package]] @@ -482,7 +482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "577e262966e92112edbd15b1b2c0947cc434d6e8311df96d3329793fe8047da9" dependencies = [ "alloy-primitives", - "alloy-sol-macro 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "alloy-sol-macro 0.8.3", "const-hex", ] @@ -493,7 +493,7 @@ source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f dependencies = [ "alloy-json-abi", "alloy-primitives", - "alloy-sol-macro 0.8.0 (git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0)", + "alloy-sol-macro 0.8.0", "const-hex", "serde", ] @@ -596,9 +596,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "ark-ff" @@ -810,17 +810,17 @@ checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -908,7 +908,7 @@ dependencies = [ [[package]] name = "bn254" version = "0.1.0" -source = "git+https://github.com/scroll-tech/bn254#1773ed6c51f14652272056370cf135ff5d7a01c5" +source = "git+https://github.com/scroll-tech/bn254#c9f170c6e39cfbc1ff14b9648f125823978041b3" dependencies = [ "ff", "getrandom", @@ -953,9 +953,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.17.1" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -965,9 +965,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] @@ -989,9 +989,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.15" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "shlex", ] @@ -1017,9 +1017,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.16" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "3e5a21b8495e732f1b3c364c9949b201ca7bae518c502c80256c96ad79eaf6ac" dependencies = [ "clap_builder", "clap_derive", @@ -1027,9 +1027,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "8cf2dd12af7a047ad9d6da2b6b249759a22a7abc0f474c1dae1777afa4b21a73" dependencies = [ "anstream", "anstyle", @@ -1043,7 +1043,7 @@ version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "syn 2.0.77", @@ -1122,9 +1122,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -1231,9 +1231,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", @@ -1637,9 +1637,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -1647,14 +1647,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" -[[package]] -name = "gobuild" -version = "0.1.0-alpha.2" -source = "git+https://github.com/scroll-tech/gobuild.git#24935c2b8f677841f22acd6710957621bb294e0e" -dependencies = [ - "cc", -] - [[package]] name = "group" version = "0.13.0" @@ -1705,12 +1697,6 @@ dependencies = [ "serde", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -1822,9 +1808,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http", @@ -1855,9 +1841,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" dependencies = [ "bytes", "futures-channel", @@ -1875,9 +1861,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1974,9 +1960,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is-terminal" @@ -2043,9 +2029,9 @@ dependencies = [ [[package]] name = "keccak-asm" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422fbc7ff2f2f5bdffeb07718e5a5324dca72b0c9293d50df4026652385e3314" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" dependencies = [ "digest 0.10.7", "sha3-asm", @@ -2120,9 +2106,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -2135,11 +2121,11 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -2233,13 +2219,13 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-derive" -version = "0.3.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -2416,9 +2402,9 @@ dependencies = [ [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -2457,9 +2443,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.11" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", "thiserror", @@ -2517,7 +2503,7 @@ checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "poseidon-bn254" version = "0.1.0" -source = "git+https://github.com/scroll-tech/poseidon-bn254?branch=master#a1174dac3d854bd91556b54274551326a94b11e6" +source = "git+https://github.com/scroll-tech/poseidon-bn254?branch=master#526a64a81419bcab6bd8280a8a3f9808189e0373" dependencies = [ "bn254", "itertools 0.13.0", @@ -2603,6 +2589,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -2746,9 +2754,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" dependencies = [ "bitflags 2.6.0", ] @@ -3053,9 +3061,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.35" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -3066,9 +3074,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "once_cell", "rustls-pki-types", @@ -3095,9 +3103,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.7" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -3163,11 +3171,12 @@ dependencies = [ "alloy", "poseidon-bn254", "rkyv", + "sbv-utils", "serde", "serde_json", "serde_with", "tiny-keccak", - "zktrie", + "zktrie-ng", ] [[package]] @@ -3190,11 +3199,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3225,9 +3234,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.29.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e0cc0f1cf93f4969faf3ea1c7d8a9faed25918d96affa959720823dfe86d4f3" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "rand", "secp256k1-sys", @@ -3235,9 +3244,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1433bd67156263443f14d603720b082dd3121779323fce20cba2aa07b874bc1b" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] @@ -3291,18 +3300,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", @@ -3311,9 +3320,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "indexmap 2.5.0", "itoa", @@ -3377,9 +3386,9 @@ dependencies = [ [[package]] name = "sha3-asm" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d79b758b7cb2085612b11a235055e485605a5103faccdd633f35bd7aee69dd" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" dependencies = [ "cc", "cfg-if", @@ -3510,32 +3519,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - [[package]] name = "strum" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ - "strum_macros 0.26.4", -] - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", + "strum_macros", ] [[package]] @@ -3544,7 +3534,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -3572,9 +3562,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.10.1" +version = "12.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1944ea8afd197111bca0c0edea1e1f56abb3edd030e240c1035cc0e3ff51fec" +checksum = "9fdf97c441f18a4f92425b896a4ec7a27e03631a0b1047ec4e34e9916a9a167e" dependencies = [ "debugid", "memmap2", @@ -3584,9 +3574,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.10.1" +version = "12.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddaccaf1bf8e73c4f64f78dbb30aadd6965c71faa4ff3fba33f8d7296cf94a87" +checksum = "bc8ece6b129e97e53d1fbb3f61d33a6a9e5369b11d01228c068094d6d134eaea" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -3618,8 +3608,7 @@ dependencies = [ [[package]] name = "syn-solidity" version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284c41c2919303438fcf8dede4036fd1e82d4fc0fbb2b279bd2a1442c909ca92" +source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" dependencies = [ "paste", "proc-macro2", @@ -3629,8 +3618,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.0" -source = "git+https://github.com/scroll-tech/alloy-core?branch=v0.8.0#3c8299a45f4722c024a0c34a1ef9b6453b7b3f45" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b95156f8b577cb59dc0b1df15c6f29a10afc5f8a7ac9786b0b5c68c19149278" dependencies = [ "paste", "proc-macro2", @@ -3832,9 +3822,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -3844,9 +3834,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -3863,9 +3853,9 @@ checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap 2.5.0", "toml_datetime", @@ -4006,15 +3996,15 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] @@ -4370,25 +4360,19 @@ dependencies = [ ] [[package]] -name = "zktrie" -version = "0.3.0" -source = "git+https://github.com/scroll-tech/zktrie.git?branch=main#1a1da01f0e3a4c3f3361b25f829a38173538953a" -dependencies = [ - "gobuild", - "zktrie_rust", -] - -[[package]] -name = "zktrie_rust" -version = "0.3.0" -source = "git+https://github.com/scroll-tech/zktrie.git?branch=main#1a1da01f0e3a4c3f3361b25f829a38173538953a" +name = "zktrie-ng" +version = "0.1.0" +source = "git+https://github.com/scroll-tech/zktrie-ng?branch=master#d749dca019145bc7898564647945cd0898a842d1" dependencies = [ + "alloy-primitives", + "hashbrown 0.14.5", "hex", - "lazy_static", - "log", - "num", "num-derive", "num-traits", - "strum 0.24.1", - "strum_macros 0.24.3", + "once_cell", + "poseidon-bn254", + "revm-primitives", + "strum", + "thiserror", + "tracing", ] diff --git a/Cargo.toml b/Cargo.toml index 886d85a..f91e7d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ tiny-keccak = "2.0" # dependencies from scroll-tech poseidon-bn254 = { git = "https://github.com/scroll-tech/poseidon-bn254", branch = "master", features = ["bn254"] } -zktrie = { git = "https://github.com/scroll-tech/zktrie.git", branch = "main", features= ["rs_zktrie"] } +zktrie-ng = { git = "https://github.com/scroll-tech/zktrie-ng", branch = "master", features = ["scroll"] } # binary dependencies anyhow = "1.0" diff --git a/crates/bin/src/commands/run_file.rs b/crates/bin/src/commands/run_file.rs index 684dd58..c8badcf 100644 --- a/crates/bin/src/commands/run_file.rs +++ b/crates/bin/src/commands/run_file.rs @@ -3,8 +3,9 @@ use anyhow::bail; use clap::Args; use sbv::{ core::{ChunkInfo, EvmExecutorBuilder, HardforkConfig}, - primitives::{types::BlockTrace, Block, B256}, + primitives::{types::BlockTrace, zk_trie::db::HashMapDb, Block, B256}, }; +use std::rc::Rc; use std::{cell::RefCell, path::PathBuf}; use tiny_keccak::{Hasher, Keccak}; use tokio::task::JoinSet; @@ -75,17 +76,17 @@ impl RunFileCommand { let fork_config = fork_config(traces[0].chain_id()); let (chunk_info, zktrie_db) = ChunkInfo::from_block_traces(&traces); + let zktrie_db = Rc::new(RefCell::new(zktrie_db)); let tx_bytes_hasher = RefCell::new(Keccak::v256()); - let mut executor = EvmExecutorBuilder::new(zktrie_db.clone()) + let mut executor = EvmExecutorBuilder::new(HashMapDb::default(), zktrie_db.clone()) .hardfork_config(fork_config) - .with_execute_hooks(|hooks| { + .with_hooks(&traces[0], |hooks| { hooks.add_tx_rlp_handler(|_, rlp| { tx_bytes_hasher.borrow_mut().update(rlp); }); - }) - .build(&traces[0])?; + })?; executor.handle_block(&traces[0])?; for trace in traces[1..].iter() { @@ -93,7 +94,7 @@ impl RunFileCommand { executor.handle_block(trace)?; } - let post_state_root = executor.commit_changes(&zktrie_db); + let post_state_root = executor.commit_changes(zktrie_db.clone())?; if post_state_root != chunk_info.post_state_root() { bail!("post state root mismatch"); } diff --git a/crates/bin/src/main.rs b/crates/bin/src/main.rs index ab1b2fb..22eb275 100644 --- a/crates/bin/src/main.rs +++ b/crates/bin/src/main.rs @@ -5,7 +5,6 @@ extern crate sbv; use clap::Parser; use sbv::core::HardforkConfig; -use sbv::primitives::init_hash_scheme; #[cfg(feature = "dev")] use tracing_subscriber::EnvFilter; @@ -43,8 +42,6 @@ async fn main() -> anyhow::Result<()> { ) .init(); - init_hash_scheme(); - let cmd = Cli::parse(); #[cfg(feature = "metrics")] diff --git a/crates/bin/src/utils.rs b/crates/bin/src/utils.rs index 1786a62..36ab091 100644 --- a/crates/bin/src/utils.rs +++ b/crates/bin/src/utils.rs @@ -1,8 +1,8 @@ -use sbv::primitives::zk_trie::ZkMemoryDb; use sbv::{ core::{EvmExecutorBuilder, HardforkConfig, VerificationError}, - primitives::Block, + primitives::{zk_trie::db::HashMapDb, Block}, }; +use std::cell::RefCell; use std::rc::Rc; pub fn verify( @@ -39,17 +39,17 @@ fn verify_inner( let zktrie_db = cycle_track!( { - let mut zktrie_db = ZkMemoryDb::new(); + let mut zktrie_db = HashMapDb::default(); measure_duration_millis!( build_zktrie_db_duration_milliseconds, - l2_trace.build_zktrie_db(&mut zktrie_db) + l2_trace.build_zktrie_db(&mut zktrie_db).unwrap() ); - Rc::new(zktrie_db) + Rc::new(RefCell::new(zktrie_db)) }, "build ZktrieState" ); - let mut executor = EvmExecutorBuilder::new(zktrie_db.clone()) + let mut executor = EvmExecutorBuilder::new(HashMapDb::default(), zktrie_db.clone()) .hardfork_config(*fork_config) .build(&l2_trace)?; @@ -66,7 +66,7 @@ fn verify_inner( update_metrics_counter!(verification_error); e })?; - let revm_root_after = executor.commit_changes(&zktrie_db); + let revm_root_after = executor.commit_changes(zktrie_db.clone())?; #[cfg(feature = "profiling")] if let Ok(report) = guard.report().build() { diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 0401b9d..d0554f0 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -33,7 +33,7 @@ tracing-subscriber.workspace = true [features] debug-account = ["sbv-utils/debug-account"] debug-storage = ["sbv-utils/debug-storage"] -dev = ["sbv-utils/dev"] +dev = ["sbv-primitives/dev", "sbv-utils/dev"] metrics = ["sbv-utils/metrics"] # sp1 related diff --git a/crates/core/src/chunk.rs b/crates/core/src/chunk.rs index 7438032..e04aeea 100644 --- a/crates/core/src/chunk.rs +++ b/crates/core/src/chunk.rs @@ -1,6 +1,5 @@ use revm::primitives::B256; -use sbv_primitives::{zk_trie::ZkMemoryDb, Block}; -use std::rc::Rc; +use sbv_primitives::{zk_trie::db::HashMapDb, Block}; use tiny_keccak::{Hasher, Keccak}; /// A chunk is a set of continuous blocks. @@ -22,7 +21,7 @@ pub struct ChunkInfo { impl ChunkInfo { /// Construct by block traces - pub fn from_block_traces(traces: &[T]) -> (Self, Rc) { + pub fn from_block_traces(traces: &[T]) -> (Self, HashMapDb) { let chain_id = traces.first().unwrap().chain_id(); let prev_state_root = traces .first() @@ -41,14 +40,13 @@ impl ChunkInfo { let mut data_hash = B256::ZERO; data_hasher.finalize(&mut data_hash.0); - let mut zktrie_db = ZkMemoryDb::new(); + let mut zktrie_db = HashMapDb::default(); for trace in traces.iter() { measure_duration_millis!( build_zktrie_db_duration_milliseconds, - trace.build_zktrie_db(&mut zktrie_db) + trace.build_zktrie_db(&mut zktrie_db).unwrap() ); } - let zktrie_db = Rc::new(zktrie_db); let info = ChunkInfo { chain_id, @@ -118,6 +116,7 @@ mod tests { use revm::primitives::b256; use sbv_primitives::types::BlockTrace; use std::cell::RefCell; + use std::rc::Rc; const TRACES_STR: [&str; 4] = [ include_str!("../../../testdata/mainnet_blocks/8370400.json"), @@ -140,17 +139,17 @@ mod tests { let fork_config = HardforkConfig::default_from_chain_id(traces[0].chain_id()); let (chunk_info, zktrie_db) = ChunkInfo::from_block_traces(&traces); + let zktrie_db = Rc::new(RefCell::new(zktrie_db)); let tx_bytes_hasher = RefCell::new(Keccak::v256()); - let mut executor = EvmExecutorBuilder::new(zktrie_db.clone()) + let mut executor = EvmExecutorBuilder::new(HashMapDb::default(), zktrie_db.clone()) .hardfork_config(fork_config) - .with_execute_hooks(|hooks| { + .with_hooks(&traces[0], |hooks| { hooks.add_tx_rlp_handler(|_, rlp| { tx_bytes_hasher.borrow_mut().update(rlp); }); }) - .build(&traces[0]) .unwrap(); executor.handle_block(&traces[0]).unwrap(); @@ -159,7 +158,7 @@ mod tests { executor.handle_block(trace).unwrap(); } - let post_state_root = executor.commit_changes(&zktrie_db); + let post_state_root = executor.commit_changes(zktrie_db.clone()).unwrap(); assert_eq!(post_state_root, chunk_info.post_state_root); drop(executor); // drop executor to release Rc diff --git a/crates/core/src/database.rs b/crates/core/src/database.rs index f535f60..96ac65b 100644 --- a/crates/core/src/database.rs +++ b/crates/core/src/database.rs @@ -1,85 +1,75 @@ -use crate::error::ZkTrieError; +use crate::error::DatabaseError; use once_cell::sync::Lazy; use revm::{ db::{AccountState, DatabaseRef}, primitives::{AccountInfo, Address, Bytecode, B256, U256}, }; use sbv_primitives::{ - init_hash_scheme, - zk_trie::{SharedMemoryDb, ZkMemoryDb, ZkTrie}, + zk_trie::{ + db::{KVDatabase, KVDatabaseItem}, + hash::{key_hasher::NoCacheHasher, poseidon::Poseidon}, + scroll_types::Account, + trie::ZkTrie, + }, Block, }; -use std::rc::Rc; -use std::{cell::RefCell, collections::HashMap, convert::Infallible, fmt}; +use std::{cell::RefCell, collections::HashMap, fmt}; -type Result = std::result::Result; +type Result = std::result::Result; -type StorageTrieLazyFn = Box ZkTrie>; +type StorageTrieLazyFn = Box ZkTrie>; +type LazyStorageTrie = Lazy, StorageTrieLazyFn>; -/// A read-only in-memory database that consists of account and storage information. -pub struct ReadOnlyDB { - /// In-memory map of code hash to bytecode. - code_db: HashMap, +/// A database that consists of account and storage information. +pub struct EvmDatabase { + /// Map of code hash to bytecode. + code_db: CodeDb, /// The initial storage roots of accounts, used for after commit. /// Need to be updated after zkTrie commit. prev_storage_roots: RefCell>, /// Storage trie cache, avoid re-creating trie for the same account. /// Need to invalidate before `update`, otherwise the trie root may be outdated. - storage_trie_refs: RefCell, StorageTrieLazyFn>>>, + storage_trie_refs: RefCell>>, /// Current uncommitted zkTrie root based on the block trace. committed_zktrie_root: B256, /// The underlying zkTrie database. - zktrie_db: Rc, + zktrie_db: ZkDb, /// Current view of zkTrie database. - zktrie_db_ref: ZkTrie, + zktrie: ZkTrie, } -impl fmt::Debug for ReadOnlyDB { +impl fmt::Debug for EvmDatabase { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("ReadOnlyDB") - .field("code_db", &self.code_db.len()) + f.debug_struct("EvmDatabase") .field("committed_zktrie_root", &self.committed_zktrie_root) .finish() } } -impl ReadOnlyDB { +impl EvmDatabase { /// Initialize an EVM database from a block trace. - pub fn new(l2_trace: T, zktrie_db: &Rc) -> Result { - let size_hint = l2_trace.codes().len(); - Self::new_with_size_hint(l2_trace, zktrie_db, size_hint) - } - - /// Initialize an EVM database from a block trace with size hint of code database. - pub fn new_with_size_hint( - l2_trace: T, - zktrie_db: &Rc, - size_hint: usize, - ) -> Result { - init_hash_scheme(); - + pub fn new(l2_trace: T, mut code_db: CodeDb, zktrie_db: ZkDb) -> Result { cycle_tracker_start!("insert CodeDB"); - let mut code_db = HashMap::with_capacity(size_hint); for code in l2_trace.codes() { let hash = revm::primitives::keccak256(code); - code_db.entry(hash).or_insert_with(|| { - dev_trace!("insert code {:?}", hash); - Bytecode::new_raw(revm::primitives::Bytes::from(code.to_vec())) - }); + code_db + .or_put(hash.as_slice(), code) + .map_err(DatabaseError::code_db)?; } cycle_tracker_end!("insert CodeDB"); - let uncommitted_zktrie_root = l2_trace.root_before(); + let committed_zktrie_root = l2_trace.root_before(); + + let zktrie = ZkTrie::new_with_root(zktrie_db.clone(), NoCacheHasher, committed_zktrie_root) + .map_err(DatabaseError::zk_trie)?; - Ok(ReadOnlyDB { + Ok(EvmDatabase { code_db, prev_storage_roots: Default::default(), storage_trie_refs: Default::default(), - committed_zktrie_root: uncommitted_zktrie_root, - zktrie_db: zktrie_db.clone(), - zktrie_db_ref: zktrie_db - .new_ref_trie(&uncommitted_zktrie_root.0) - .ok_or(ZkTrieError::ZkTrieRootNotFound)?, + committed_zktrie_root, + zktrie_db, + zktrie, }) } @@ -107,13 +97,13 @@ impl ReadOnlyDB { .unwrap_or_default() } - /// Get the zkTrie root. + /// Get the committed zkTrie root. #[inline] pub(crate) fn committed_zktrie_root(&self) -> B256 { self.committed_zktrie_root } - /// Get the zkTrie root. + /// Set the committed zkTrie root. #[inline] pub(crate) fn updated_committed_zktrie_root(&mut self, new_root: B256) { self.committed_zktrie_root = new_root; @@ -128,17 +118,18 @@ impl ReadOnlyDB { cycle_tracker_start!("insert CodeDB"); for code in l2_trace.codes() { let hash = revm::primitives::keccak256(code); - self.code_db.entry(hash).or_insert_with(|| { - dev_trace!("insert code {:?}", hash); - Bytecode::new_raw(revm::primitives::Bytes::from(code.to_vec())) - }); + self.code_db + .or_put(hash.as_slice(), code) + .map_err(DatabaseError::code_db)?; } cycle_tracker_end!("insert CodeDB"); - self.zktrie_db_ref = self - .zktrie_db - .new_ref_trie(&l2_trace.root_before().0) - .ok_or(ZkTrieError::ZkTrieRootNotFound)?; + self.zktrie = ZkTrie::new_with_root( + self.zktrie_db.clone(), + NoCacheHasher, + l2_trace.root_before(), + ) + .map_err(DatabaseError::zk_trie)?; Ok(()) } @@ -157,95 +148,111 @@ impl ReadOnlyDB { } } -impl DatabaseRef for ReadOnlyDB { - type Error = Infallible; +impl DatabaseRef + for EvmDatabase +{ + type Error = DatabaseError; /// Get basic account information. - fn basic_ref(&self, address: Address) -> Result, Self::Error> { - Ok(measure_duration_micros!( + fn basic_ref(&self, address: Address) -> Result> { + let Some(account) = measure_duration_micros!( zktrie_get_duration_microseconds, - self.zktrie_db_ref.get_account(address.as_slice()) + self.zktrie.get::(address) ) - .map(|account_data| { - let code_size = - u64::from_be_bytes((&account_data[0][16..24]).try_into().unwrap()) as usize; - let nonce = u64::from_be_bytes((&account_data[0][24..]).try_into().unwrap()); - let balance = U256::from_be_bytes(account_data[1]); - let code_hash = B256::from(account_data[3]); - let poseidon_code_hash = B256::from(account_data[4]); - - let storage_root = B256::from(account_data[2]); - self.prev_storage_roots - .borrow_mut() - .entry(address) - .or_insert(storage_root.0.into()); - - let zktrie_db = self.zktrie_db.clone(); - self.storage_trie_refs.borrow_mut().insert( - address, + .map_err(DatabaseError::zk_trie)? + else { + return Ok(None); + }; + + self.prev_storage_roots + .borrow_mut() + .entry(address) + .or_insert(account.storage_root); + let zktrie_db = self.zktrie_db.clone(); + self.storage_trie_refs + .borrow_mut() + .entry(address) + .or_insert_with(|| { Lazy::new(Box::new(move || { - zktrie_db - .new_ref_trie(&storage_root.0) + ZkTrie::new_with_root(zktrie_db.clone(), NoCacheHasher, account.storage_root) .expect("storage trie associated with account not found") - })), - ); - AccountInfo { - balance, - nonce, - code_size, - code_hash, - poseidon_code_hash, - code: self.code_db.get(&code_hash).cloned(), - } - })) + })) + }); + + let mut info = AccountInfo::from(account); + info.code = self + .code_db + .get(&account.code_hash) + .map_err(DatabaseError::code_db)? + .map(|v| Bytecode::new_legacy(v.into_bytes().into())); + + Ok(Some(info)) } /// Get account code by its code hash. - fn code_by_hash_ref(&self, hash: B256) -> Result { + fn code_by_hash_ref(&self, hash: B256) -> Result { // Sometimes the code in previous account info is not contained, // and the CacheDB has already loaded the previous account info, // then the upcoming trace contains code (meaning the code is used in this new block), // we can't directly update the CacheDB, so we offer the code by hash here. // However, if the code still cannot be found, this is an error. - self.code_db.get(&hash).cloned().ok_or_else(|| { - unreachable!( - "Code is either loaded or not needed (like EXTCODESIZE), code hash: {:?}", - hash - ); - }) + self.code_db + .get(&hash) + .map_err(DatabaseError::code_db)? + .map(|v| Bytecode::new_legacy(v.into_bytes().into())) + .ok_or_else(|| { + unreachable!( + "Code is either loaded or not needed (like EXTCODESIZE), code hash: {:?}", + hash + ); + }) } /// Get storage value of address at index. - fn storage_ref(&self, address: Address, index: U256) -> Result { + fn storage_ref(&self, address: Address, index: U256) -> Result { + dev_trace!("get storage of {:?} at index {:?}", address, index); let mut storage_trie_refs = self.storage_trie_refs.borrow_mut(); let trie = storage_trie_refs .entry(address) .or_insert_with_key(|address| { let storage_root = measure_duration_micros!( zktrie_get_duration_microseconds, - self.zktrie_db_ref.get_account(address.as_slice()) + self.zktrie.get::(address) ) - .map(|account_data| B256::from(account_data[2])) + .expect("unexpected zktrie error") + .map(|acc| acc.storage_root) .unwrap_or_default(); + dev_debug!("storage root of {:?} is {:?}", address, storage_root); + let zktrie_db = self.zktrie_db.clone(); Lazy::new(Box::new(move || { - zktrie_db - .clone() - .new_ref_trie(&storage_root.0) + ZkTrie::new_with_root(zktrie_db.clone(), NoCacheHasher, storage_root) .expect("storage trie associated with account not found") })) }); + #[cfg(debug_assertions)] + { + let current_root = trie.root().unwrap_ref(); + let expected_root = self + .zktrie + .get::(address) + .expect("unexpected zktrie error") + .map(|acc| acc.storage_root) + .unwrap_or_default(); + assert_eq!(*current_root, expected_root); + } + Ok(measure_duration_micros!( zktrie_get_duration_microseconds, - trie.get_store(&index.to_be_bytes::<32>()) + trie.get::(index.to_be_bytes::<32>()) ) - .map(|store_data| U256::from_be_bytes(store_data)) + .map_err(DatabaseError::zk_trie)? .unwrap_or_default()) } /// Get block hash by block number. - fn block_hash_ref(&self, _: u64) -> Result { + fn block_hash_ref(&self, _: u64) -> Result { unreachable!("BLOCKHASH is disabled") } } diff --git a/crates/core/src/error.rs b/crates/core/src/error.rs index d3a6080..322f6c5 100644 --- a/crates/core/src/error.rs +++ b/crates/core/src/error.rs @@ -1,24 +1,21 @@ -use revm::primitives::alloy_primitives::SignatureError; -use revm::primitives::{EVMError, B256}; -use std::convert::Infallible; +use revm::primitives::{alloy_primitives::SignatureError, EVMError, B256}; +use std::error::Error; /// Error variants encountered during manipulation of a zkTrie. #[derive(Debug, thiserror::Error)] -pub enum ZkTrieError { - #[error("zktrie root not found")] - ZkTrieRootNotFound, +pub enum DatabaseError { + #[error("error encountered from code db: {0}")] + CodeDb(Box), + #[error("error encountered from zkTrie: {0}")] + ZkTrie(Box), } /// Error variants encountered during verification of transactions in a L2 block. #[derive(Debug, thiserror::Error)] pub enum VerificationError { - /// Malformed trace. - #[error("malformed trace, unexpected zktrie error: {source}")] - MalformedTrace { - /// The source error that occurred while parsing the trace. - #[from] - source: ZkTrieError, - }, + /// Error while operating on the database. + #[error("database error: {0}")] + Database(#[from] DatabaseError), /// Error while recovering signer from an ECDSA signature. #[error("invalid signature for tx_hash={tx_hash}: {source}")] InvalidSignature { @@ -39,7 +36,7 @@ pub enum VerificationError { /// The tx hash. tx_hash: B256, /// The source error originating in [`revm`]. - source: EVMError, + source: EVMError, }, /// Root mismatch error #[error("root_after in trace doesn't match with root_after in revm: root_trace={root_trace}, root_revm={root_revm}")] @@ -50,3 +47,21 @@ pub enum VerificationError { root_revm: B256, }, } + +impl DatabaseError { + pub(crate) fn code_db(err: E) -> Self { + dev_error!( + "code_db error {err} occurred in:\n{}", + std::backtrace::Backtrace::force_capture() + ); + DatabaseError::CodeDb(Box::new(err)) + } + + pub(crate) fn zk_trie(err: E) -> Self { + dev_error!( + "zk_trie error {err} occurred in:\n{}", + std::backtrace::Backtrace::force_capture() + ); + DatabaseError::ZkTrie(Box::new(err)) + } +} diff --git a/crates/core/src/executor/builder.rs b/crates/core/src/executor/builder.rs index 57e5512..b17fdd0 100644 --- a/crates/core/src/executor/builder.rs +++ b/crates/core/src/executor/builder.rs @@ -1,70 +1,86 @@ -use crate::error::ZkTrieError; -use crate::{executor::hooks::ExecuteHooks, EvmExecutor, HardforkConfig, ReadOnlyDB}; -use core::fmt; +use crate::error::DatabaseError; +use crate::{executor::hooks::ExecuteHooks, EvmDatabase, EvmExecutor, HardforkConfig}; use revm::db::CacheDB; -use sbv_primitives::{zk_trie::ZkMemoryDb, Block}; -use std::rc::Rc; +use sbv_primitives::zk_trie::db::KVDatabase; +use sbv_primitives::Block; +use std::fmt::{self, Debug}; /// Builder for EVM executor. -pub struct EvmExecutorBuilder<'e, H> { +pub struct EvmExecutorBuilder { hardfork_config: H, - execute_hooks: ExecuteHooks<'e>, - zktrie_db: Rc, + code_db: CodeDb, + zktrie_db: ZkDb, } -impl fmt::Debug for EvmExecutorBuilder<'_, ()> { +impl Debug for EvmExecutorBuilder { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("EvmExecutorBuilder") .field("hardfork_config", &self.hardfork_config) - .field("execute_hooks", &self.execute_hooks) + .field("code_db", &"...") .field("zktrie_db", &"...") .finish() } } -impl<'e> EvmExecutorBuilder<'e, ()> { +impl EvmExecutorBuilder<(), CodeDb, ZkDb> { /// Create a new builder. - pub fn new(zktrie_db: Rc) -> Self { + pub fn new(code_db: CodeDb, zktrie_db: ZkDb) -> Self { Self { hardfork_config: (), - execute_hooks: ExecuteHooks::default(), + code_db, zktrie_db, } } } -impl<'e, H> EvmExecutorBuilder<'e, H> { +impl EvmExecutorBuilder { /// Set hardfork config. - pub fn hardfork_config

(self, hardfork_config: H1) -> EvmExecutorBuilder<'e, H1> { + pub fn hardfork_config

(self, hardfork_config: H1) -> EvmExecutorBuilder { EvmExecutorBuilder { hardfork_config, - execute_hooks: self.execute_hooks, + code_db: self.code_db, zktrie_db: self.zktrie_db, } } - /// Modify execute hooks. - pub fn with_execute_hooks(mut self, modify: impl FnOnce(&mut ExecuteHooks<'e>)) -> Self { - modify(&mut self.execute_hooks); - self + /// Set code db. + pub fn code_db(self, code_db: CodeDb1) -> EvmExecutorBuilder { + EvmExecutorBuilder { + hardfork_config: self.hardfork_config, + code_db, + zktrie_db: self.zktrie_db, + } } - /// Set zktrie state. - pub fn zktrie_db(self, zktrie_db: Rc) -> EvmExecutorBuilder<'e, H> { - EvmExecutorBuilder { zktrie_db, ..self } + /// Set zktrie db. + pub fn zktrie_db(self, zktrie_db: ZkDb1) -> EvmExecutorBuilder { + EvmExecutorBuilder { + hardfork_config: self.hardfork_config, + code_db: self.code_db, + zktrie_db, + } } } -impl<'e> EvmExecutorBuilder<'e, HardforkConfig> { +impl + EvmExecutorBuilder +{ /// Initialize an EVM executor from a block trace as the initial state. - pub fn build(self, l2_trace: &T) -> Result, ZkTrieError> { + pub fn with_hooks<'e, T: Block, F: FnOnce(&mut ExecuteHooks<'e, CodeDb, ZkDb>)>( + self, + l2_trace: &T, + 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(ReadOnlyDB::new(l2_trace, &self.zktrie_db)?), + CacheDB::new(EvmDatabase::new(l2_trace, self.code_db, self.zktrie_db)?), "build ReadOnlyDB" ); @@ -72,7 +88,15 @@ impl<'e> EvmExecutorBuilder<'e, HardforkConfig> { hardfork_config: self.hardfork_config, db, spec_id, - hooks: self.execute_hooks, + 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, |_| {}) + } } diff --git a/crates/core/src/executor/hooks.rs b/crates/core/src/executor/hooks.rs index 8e45cb8..1e17d7c 100644 --- a/crates/core/src/executor/hooks.rs +++ b/crates/core/src/executor/hooks.rs @@ -2,18 +2,26 @@ use crate::EvmExecutor; use std::fmt::{Debug, Formatter}; /// Transaction RLP handler. -pub type TxRLPHandler<'a> = dyn Fn(&EvmExecutor, &[u8]) + 'a; +pub type TxRLPHandler<'a, CodeDb, ZkDb> = dyn Fn(&EvmExecutor, &[u8]) + 'a; /// Post transaction execution handler. -pub type PostTxExecutionHandler<'a> = dyn Fn(&EvmExecutor, usize) + 'a; +pub type PostTxExecutionHandler<'a, CodeDb, ZkDb> = dyn Fn(&EvmExecutor, usize) + 'a; /// Hooks for the EVM executor. -#[derive(Default)] -pub struct ExecuteHooks<'a> { - tx_rlp_handlers: Vec>>, - post_tx_execution_handlers: Vec>>, +pub struct ExecuteHooks<'a, CodeDb, ZkDb> { + tx_rlp_handlers: Vec>>, + post_tx_execution_handlers: Vec>>, } -impl<'a> ExecuteHooks<'a> { +impl<'a, CodeDb, ZkDb> Default for ExecuteHooks<'a, CodeDb, ZkDb> { + fn default() -> Self { + Self { + tx_rlp_handlers: Vec::new(), + post_tx_execution_handlers: Vec::new(), + } + } +} + +impl<'a, CodeDb, ZkDb> ExecuteHooks<'a, CodeDb, ZkDb> { /// Create a new hooks. pub fn new() -> Self { Self::default() @@ -22,7 +30,7 @@ impl<'a> ExecuteHooks<'a> { /// Add a transaction RLP handler. pub fn add_tx_rlp_handler(&mut self, handler: F) where - F: Fn(&EvmExecutor, &[u8]) + 'a, + F: Fn(&EvmExecutor, &[u8]) + 'a, { self.tx_rlp_handlers.push(Box::new(handler)); } @@ -30,26 +38,26 @@ impl<'a> ExecuteHooks<'a> { /// Add a post transaction execution handler. pub fn add_post_tx_execution_handler(&mut self, handler: F) where - F: Fn(&EvmExecutor, usize) + 'a, + F: Fn(&EvmExecutor, usize) + 'a, { self.post_tx_execution_handlers.push(Box::new(handler)); } /// Execute transaction RLP handlers. - pub(crate) fn tx_rlp(&self, executor: &EvmExecutor, rlp: &[u8]) { + pub(crate) fn tx_rlp(&self, executor: &EvmExecutor, rlp: &[u8]) { for handler in &self.tx_rlp_handlers { handler(executor, rlp); } } - pub(crate) fn post_tx_execution(&self, executor: &EvmExecutor, tx_index: usize) { + pub(crate) fn post_tx_execution(&self, executor: &EvmExecutor, tx_index: usize) { for handler in &self.post_tx_execution_handlers { handler(executor, tx_index); } } } -impl Debug for ExecuteHooks<'_> { +impl Debug for ExecuteHooks<'_, CodeDb, ZkDb> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("ExecuteHooks") .field("tx_rlp_handlers", &self.tx_rlp_handlers.len()) diff --git a/crates/core/src/executor/mod.rs b/crates/core/src/executor/mod.rs index 308887d..bcfa9a1 100644 --- a/crates/core/src/executor/mod.rs +++ b/crates/core/src/executor/mod.rs @@ -1,36 +1,48 @@ -use crate::{database::ReadOnlyDB, error::VerificationError, error::ZkTrieError, HardforkConfig}; +use crate::{ + database::EvmDatabase, error::DatabaseError, error::VerificationError, HardforkConfig, +}; use revm::db::AccountState; use revm::primitives::{BlockEnv, TxEnv, U256}; use revm::{ db::CacheDB, primitives::{AccountInfo, Env, SpecId, B256, KECCAK_EMPTY, POSEIDON_EMPTY}, }; -use sbv_primitives::{zk_trie::ZkMemoryDb, Block, Transaction, TxTrace}; +use sbv_primitives::{ + zk_trie::{ + db::KVDatabase, + hash::{ + key_hasher::NoCacheHasher, + poseidon::{Poseidon, PoseidonError}, + }, + trie::{ZkTrie, ZkTrieError}, + }, + Block, Transaction, TxTrace, +}; use std::fmt::Debug; -use std::rc::Rc; mod builder; pub use builder::EvmExecutorBuilder; +use sbv_primitives::zk_trie::scroll_types::Account; /// Execute hooks pub mod hooks; /// EVM executor that handles the block. -pub struct EvmExecutor<'a> { +pub struct EvmExecutor<'a, CodeDb, ZkDb> { hardfork_config: HardforkConfig, - db: CacheDB, + db: CacheDB>, spec_id: SpecId, - hooks: hooks::ExecuteHooks<'a>, + hooks: hooks::ExecuteHooks<'a, CodeDb, ZkDb>, } -impl EvmExecutor<'_> { +impl EvmExecutor<'_, CodeDb, ZkDb> { /// Get reference to the DB - pub fn db(&self) -> &CacheDB { + pub fn db(&self) -> &CacheDB> { &self.db } /// Update the DB - pub fn update_db(&mut self, l2_trace: &T) -> Result<(), ZkTrieError> { + pub fn update_db(&mut self, l2_trace: &T) -> Result<(), DatabaseError> { self.db.db.invalidate_storage_root_caches( self.db .accounts @@ -160,17 +172,27 @@ impl EvmExecutor<'_> { } /// Commit pending changes in cache db to zktrie - pub fn commit_changes(&mut self, zktrie_db: &Rc) -> B256 { + pub fn commit_changes(&mut self, zktrie_db: ZkDb) -> Result { measure_duration_millis!( commit_changes_duration_milliseconds, - cycle_track!(self.commit_changes_inner(zktrie_db), "commit_changes") + cycle_track!( + self.commit_changes_inner(zktrie_db) + .map_err(DatabaseError::zk_trie), + "commit_changes" + ) ) } - fn commit_changes_inner(&mut self, zktrie_db: &Rc) -> B256 { - let mut zktrie = zktrie_db - .new_trie(&self.db.db.committed_zktrie_root()) - .expect("infallible"); + fn commit_changes_inner( + &mut self, + zktrie_db: ZkDb, + ) -> Result> { + let mut zktrie = ZkTrie::::new_with_root( + zktrie_db.clone(), + NoCacheHasher, + self.db.db.committed_zktrie_root(), + ) + .expect("infallible"); #[cfg(any(feature = "debug-account", feature = "debug-storage"))] let mut debug_recorder = sbv_utils::DebugRecorder::new(); @@ -180,7 +202,7 @@ impl EvmExecutor<'_> { if db_acc.account_state == AccountState::None { continue; } - let Some(info): Option = db_acc.info() else { + let Some(mut info): Option = db_acc.info() else { continue; }; if info.is_empty() { @@ -190,27 +212,25 @@ impl EvmExecutor<'_> { dev_trace!("committing {addr}, {:?} {db_acc:?}", db_acc.account_state); cycle_tracker_start!("commit account {}", addr); - let mut code_size = 0; let mut storage_root = self.db.db.prev_storage_root(addr); - let mut code_hash = B256::ZERO; - let mut poseidon_code_hash = B256::ZERO; if !db_acc.storage.is_empty() { // get current storage root let storage_root_before = storage_root; // get storage tire cycle_tracker_start!("update storage_tire"); - let mut storage_trie = zktrie_db - .new_trie(storage_root_before.as_ref()) - .expect("unable to get storage trie"); + let mut storage_trie = ZkTrie::::new_with_root( + zktrie_db.clone(), + NoCacheHasher, + storage_root_before, + ) + .expect("unable to get storage trie"); for (key, value) in db_acc.storage.iter() { if !value.is_zero() { measure_duration_micros!( zktrie_update_duration_microseconds, cycle_track!( - storage_trie - .update_store(&key.to_be_bytes::<32>(), &value.to_be_bytes()) - .expect("failed to update storage"), + storage_trie.update(key.to_be_bytes::<32>(), value)?, "Zktrie::update_store" ) ); @@ -218,7 +238,7 @@ impl EvmExecutor<'_> { measure_duration_micros!( zktrie_delete_duration_microseconds, cycle_track!( - storage_trie.delete(&key.to_be_bytes::<32>()), + storage_trie.delete(key.to_be_bytes::<32>())?, "Zktrie::delete" ) ); @@ -230,13 +250,11 @@ impl EvmExecutor<'_> { measure_duration_micros!( zktrie_commit_duration_microseconds, - if storage_trie.is_trie_dirty() { - storage_trie.prepare_root(); - } + storage_trie.commit()? ); cycle_tracker_end!("update storage_tire"); - storage_root = storage_trie.root().into(); + storage_root = *storage_trie.root().unwrap_ref(); #[cfg(feature = "debug-storage")] debug_recorder.record_storage_root(*addr, storage_root); @@ -247,43 +265,29 @@ impl EvmExecutor<'_> { // if account not exist, all fields will be zero. // but if account exist, code_hash will be empty hash if code is empty if info.is_empty_code_hash() { - code_hash = KECCAK_EMPTY.0.into(); - poseidon_code_hash = POSEIDON_EMPTY.0.into(); + info.code_hash = KECCAK_EMPTY.0.into(); + info.poseidon_code_hash = POSEIDON_EMPTY.0.into(); } else { assert_ne!( info.poseidon_code_hash, B256::ZERO, "revm didn't update poseidon_code_hash, revm: {info:?}", ); - code_size = info.code_size as u64; - code_hash = info.code_hash.0.into(); - poseidon_code_hash = info.poseidon_code_hash.0.into(); } + } else { + info.code_hash = B256::ZERO; + info.poseidon_code_hash = B256::ZERO; } #[cfg(feature = "debug-account")] - debug_recorder.record_account( - *addr, - info.nonce, - info.balance, - code_hash, - poseidon_code_hash, - code_size, - storage_root, - ); + debug_recorder.record_account(*addr, info.clone(), storage_root); - let acc_data = [ - U256::from_limbs([info.nonce, code_size, 0, 0]).to_be_bytes(), - info.balance.to_be_bytes(), - storage_root.0, - code_hash.0, - poseidon_code_hash.0, - ]; + let acc_data = Account::from_revm_account_with_storage_root(info, storage_root); measure_duration_micros!( zktrie_update_duration_microseconds, cycle_track!( zktrie - .update_account(addr.as_slice(), &acc_data) + .update(addr, acc_data) .expect("failed to update account"), "Zktrie::update_account" ) @@ -292,22 +296,17 @@ impl EvmExecutor<'_> { cycle_tracker_end!("commit account {}", addr); } - measure_duration_micros!( - zktrie_commit_duration_microseconds, - if zktrie.is_trie_dirty() { - zktrie.prepare_root(); - } - ); + measure_duration_micros!(zktrie_commit_duration_microseconds, zktrie.commit()?); - let root_after = zktrie.root(); + let root_after = *zktrie.root().unwrap_ref(); - self.db.db.updated_committed_zktrie_root(root_after.into()); + self.db.db.updated_committed_zktrie_root(root_after); - B256::from(root_after) + Ok(B256::from(root_after)) } } -impl Debug for EvmExecutor<'_> { +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) diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 5f60dfb..7faee4a 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -7,7 +7,7 @@ mod chunk; pub use chunk::ChunkInfo; mod database; -pub use database::ReadOnlyDB; +pub use database::EvmDatabase; mod error; pub use error::VerificationError; diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index a3b276b..15ffc8f 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -19,8 +19,13 @@ serde = { workspace = true, features = ["derive"] } serde_with.workspace = true tiny-keccak.workspace = true +sbv-utils.workspace = true + poseidon-bn254.workspace = true -zktrie.workspace = true +zktrie-ng.workspace = true [dev-dependencies] -serde_json.workspace = true \ No newline at end of file +serde_json.workspace = true + +[features] +dev = ["sbv-utils/dev"] \ No newline at end of file diff --git a/crates/primitives/src/imp/archived_block_trace_v2.rs b/crates/primitives/src/imp/archived_block_trace_v2.rs deleted file mode 100644 index 6125ecd..0000000 --- a/crates/primitives/src/imp/archived_block_trace_v2.rs +++ /dev/null @@ -1,215 +0,0 @@ -use crate::*; -use eth_types::l2_types::{ArchivedBlockTraceV2, ArchivedTransactionTrace, TransactionTrace}; -use eth_types::{Address, H256}; -use revm_primitives::{AccessListItem, TransactTo, B256, U256}; -use rkyv::Deserialize; - -impl BlockTraceExt for ArchivedBlockTraceV2 { - #[inline(always)] - fn root_before(&self) -> H256 { - H256::from(self.storage_trace.root_before.0) - } - #[inline(always)] - fn root_after(&self) -> H256 { - H256::from(self.storage_trace.root_after.0) - } - #[inline(always)] - fn withdraw_root(&self) -> H256 { - H256::from(self.withdraw_trie_root.0) - } - #[inline(always)] - fn flatten_proofs(&self) -> Option> { - if self.storage_trace.flatten_proofs.is_empty() { - None - } else { - Some( - self.storage_trace - .flatten_proofs - .iter() - .map(|(k, v)| (k.as_h256(), v.as_ref())), - ) - } - } - #[inline(always)] - fn address_hashes(&self) -> impl Iterator { - self.storage_trace - .address_hashes - .iter() - .map(|(k, v)| (k.as_h160(), v.as_h256())) - } - #[inline(always)] - fn store_key_hashes(&self) -> impl Iterator { - self.storage_trace - .store_key_hashes - .iter() - .map(|(k, v)| (k.as_h256(), v.as_h256())) - } - #[inline(always)] - fn account_proofs(&self) -> impl Iterator)> { - self.storage_trace - .proofs - .iter() - .map(|(addr, b)| (addr.as_h160(), b.iter().map(|b| b.as_ref()))) - } - #[inline(always)] - fn storage_proofs( - &self, - ) -> impl Iterator)> { - self.storage_trace - .storage_proofs - .iter() - .flat_map(|(addr, map)| { - map.iter().map(move |(sk, bts)| { - (addr.as_h160(), sk.as_h256(), bts.iter().map(|b| b.as_ref())) - }) - }) - } - #[inline(always)] - fn additional_proofs(&self) -> impl Iterator { - self.storage_trace - .deletion_proofs - .iter() - .map(|s| s.as_ref()) - } - #[inline] - fn codes(&self) -> impl ExactSizeIterator { - self.codes.iter().map(|code| code.code.as_ref()) - } - #[inline] - fn start_l1_queue_index(&self) -> u64 { - self.start_l1_queue_index - } -} - -impl BlockTraceRevmExt for ArchivedBlockTraceV2 { - type Tx = ArchivedTransactionTrace; - #[inline] - fn number(&self) -> u64 { - self.header.number.0[0] - } - #[inline] - fn block_hash(&self) -> B256 { - self.header.hash.0.into() - } - #[inline] - fn chain_id(&self) -> u64 { - self.chain_id - } - #[inline] - fn coinbase(&self) -> revm_primitives::Address { - self.coinbase.address.0.into() - } - #[inline] - fn timestamp(&self) -> U256 { - U256::from_limbs(self.header.timestamp.0) - } - #[inline] - fn gas_limit(&self) -> U256 { - U256::from_limbs(self.header.gas_limit.0) - } - #[inline] - fn base_fee_per_gas(&self) -> Option { - self.header - .base_fee_per_gas - .as_ref() - .map(|b| U256::from_limbs(b.0)) - } - #[inline] - fn difficulty(&self) -> U256 { - U256::from_limbs(self.header.difficulty.0) - } - #[inline] - fn prevrandao(&self) -> Option { - self.header.mix_hash.as_ref().map(|h| B256::from(h.0)) - } - #[inline] - fn transactions(&self) -> impl Iterator { - self.transactions.iter() - } -} - -impl BlockZktrieExt for ArchivedBlockTraceV2 {} - -impl Transaction for ArchivedTransactionTrace { - #[inline] - fn raw_type(&self) -> u8 { - self.type_ - } - #[inline] - fn tx_hash(&self) -> B256 { - B256::new(self.tx_hash.0) - } - #[inline] - fn caller(&self) -> revm_primitives::Address { - self.from.0.into() - } - #[inline] - fn gas_limit(&self) -> u64 { - self.gas - } - #[inline] - fn gas_price(&self) -> U256 { - U256::from_limbs(self.gas_price.0) - } - #[inline] - fn transact_to(&self) -> TransactTo { - match self.to.as_ref() { - Some(to) => TransactTo::Call(to.0.into()), - None => TransactTo::Create, - } - } - #[inline] - fn value(&self) -> U256 { - U256::from_limbs(self.value.0) - } - #[inline] - fn data(&self) -> revm_primitives::Bytes { - revm_primitives::Bytes::copy_from_slice(self.data.as_ref()) - } - #[inline] - fn nonce(&self) -> u64 { - self.nonce - } - #[inline] - fn chain_id(&self) -> u64 { - self.chain_id.0[0] - } - #[inline] - fn access_list(&self) -> Vec { - self.access_list - .as_ref() - .map(|v| { - v.iter() - .map(|e| AccessListItem { - address: e.address.0.into(), - storage_keys: e.storage_keys.iter().map(|s| s.0.into()).collect(), - }) - .collect() - }) - .unwrap_or_default() - } - #[inline] - fn gas_priority_fee(&self) -> Option { - self.gas_tip_cap.as_ref().map(|g| U256::from_limbs(g.0)) - } - #[inline] - fn to_eth_tx( - &self, - block_hash: B256, - block_number: u64, - transaction_index: usize, - base_fee_per_gas: Option, - ) -> eth_types::Transaction { - // FIXME: zero copy here pls - let tx_trace: TransactionTrace = - Deserialize::::deserialize(self, &mut rkyv::Infallible).unwrap(); - tx_trace.to_eth_tx( - Some(H256::from(block_hash.0)), - Some(block_number.into()), - Some((transaction_index as u64).into()), - base_fee_per_gas.map(|b| eth_types::U256(*b.as_limbs())), - ) - } -} - -impl BlockChunkExt for ArchivedBlockTraceV2 {} diff --git a/crates/primitives/src/imp/blanket.rs b/crates/primitives/src/imp/blanket.rs deleted file mode 100644 index 7f47211..0000000 --- a/crates/primitives/src/imp/blanket.rs +++ /dev/null @@ -1,187 +0,0 @@ -use crate::*; -use eth_types::{Address, H256}; -use revm_primitives::{AccessListItem, TransactTo, B256, U256}; - -impl BlockTraceExt for &T { - #[inline(always)] - fn root_before(&self) -> H256 { - (*self).root_before() - } - #[inline(always)] - fn root_after(&self) -> H256 { - (*self).root_after() - } - #[inline(always)] - fn withdraw_root(&self) -> H256 { - (*self).withdraw_root() - } - #[inline(always)] - fn account_proofs(&self) -> impl Iterator)> { - (*self).account_proofs() - } - #[inline(always)] - fn storage_proofs( - &self, - ) -> impl Iterator)> { - (*self).storage_proofs() - } - #[inline(always)] - fn additional_proofs(&self) -> impl Iterator { - (*self).additional_proofs() - } - #[inline(always)] - fn flatten_proofs(&self) -> Option> { - (*self).flatten_proofs() - } - #[inline(always)] - fn address_hashes(&self) -> impl Iterator { - (*self).address_hashes() - } - #[inline(always)] - fn store_key_hashes(&self) -> impl Iterator { - (*self).store_key_hashes() - } - #[inline(always)] - fn codes(&self) -> impl ExactSizeIterator { - (*self).codes() - } - #[inline(always)] - fn start_l1_queue_index(&self) -> u64 { - (*self).start_l1_queue_index() - } -} - -impl BlockTraceRevmExt for &T { - type Tx = T::Tx; - - #[inline(always)] - fn number(&self) -> u64 { - (*self).number() - } - - #[inline(always)] - fn block_hash(&self) -> B256 { - (*self).block_hash() - } - - #[inline(always)] - fn chain_id(&self) -> u64 { - (*self).chain_id() - } - - #[inline(always)] - fn coinbase(&self) -> revm_primitives::Address { - (*self).coinbase() - } - - #[inline(always)] - fn timestamp(&self) -> U256 { - (*self).timestamp() - } - - #[inline(always)] - fn gas_limit(&self) -> U256 { - (*self).gas_limit() - } - - #[inline(always)] - fn base_fee_per_gas(&self) -> Option { - (*self).base_fee_per_gas() - } - - #[inline(always)] - fn difficulty(&self) -> U256 { - (*self).difficulty() - } - - #[inline(always)] - fn prevrandao(&self) -> Option { - (*self).prevrandao() - } - - #[inline(always)] - fn transactions(&self) -> impl Iterator { - (*self).transactions() - } -} - -impl BlockZktrieExt for &T {} - -impl Transaction for &T { - #[inline(always)] - fn raw_type(&self) -> u8 { - (*self).raw_type() - } - #[inline(always)] - fn tx_hash(&self) -> B256 { - (*self).tx_hash() - } - - #[inline(always)] - fn caller(&self) -> revm_primitives::Address { - (*self).caller() - } - - #[inline(always)] - fn gas_limit(&self) -> u64 { - (*self).gas_limit() - } - - #[inline(always)] - fn gas_price(&self) -> U256 { - (*self).gas_price() - } - - #[inline(always)] - fn transact_to(&self) -> TransactTo { - (*self).transact_to() - } - - #[inline(always)] - fn value(&self) -> U256 { - (*self).value() - } - - #[inline(always)] - fn data(&self) -> revm_primitives::Bytes { - (*self).data() - } - - #[inline(always)] - fn nonce(&self) -> u64 { - (*self).nonce() - } - - #[inline(always)] - fn chain_id(&self) -> u64 { - (*self).chain_id() - } - - #[inline(always)] - fn access_list(&self) -> Vec { - (*self).access_list() - } - - #[inline(always)] - fn gas_priority_fee(&self) -> Option { - (*self).gas_priority_fee() - } - - #[inline(always)] - fn to_eth_tx( - &self, - block_hash: B256, - block_number: u64, - transaction_index: usize, - base_fee_per_gas: Option, - ) -> eth_types::Transaction { - (*self).to_eth_tx( - block_hash, - block_number, - transaction_index, - base_fee_per_gas, - ) - } -} - -impl BlockChunkExt for &T {} diff --git a/crates/primitives/src/imp/block_trace.rs b/crates/primitives/src/imp/block_trace.rs deleted file mode 100644 index c00b6e1..0000000 --- a/crates/primitives/src/imp/block_trace.rs +++ /dev/null @@ -1,129 +0,0 @@ -use crate::*; -use eth_types::l2_types::{BlockTrace, TransactionTrace}; -use eth_types::{Address, H256}; -use revm_primitives::{B256, U256}; - -impl BlockTraceExt for BlockTrace { - #[inline(always)] - fn root_before(&self) -> H256 { - self.storage_trace.root_before - } - #[inline(always)] - fn root_after(&self) -> H256 { - self.storage_trace.root_after - } - #[inline(always)] - fn withdraw_root(&self) -> H256 { - self.withdraw_trie_root - } - #[inline(always)] - fn flatten_proofs(&self) -> Option> { - if self.storage_trace.flatten_proofs.is_empty() { - None - } else { - Some( - self.storage_trace - .flatten_proofs - .iter() - .map(|(k, v)| (k, v.as_ref())), - ) - } - } - #[inline(always)] - fn address_hashes(&self) -> impl Iterator { - self.storage_trace - .address_hashes - .iter() - .map(|(k, v)| (k, v)) - } - #[inline(always)] - fn store_key_hashes(&self) -> impl Iterator { - self.storage_trace - .store_key_hashes - .iter() - .map(|(k, v)| (k, v)) - } - #[inline(always)] - fn account_proofs(&self) -> impl Iterator)> { - self.storage_trace - .proofs - .iter() - .map(|(addr, b)| (addr, b.iter().map(|b| b.as_ref()))) - } - #[inline(always)] - fn storage_proofs( - &self, - ) -> impl Iterator)> { - self.storage_trace - .storage_proofs - .iter() - .flat_map(|(addr, map)| { - map.iter() - .map(move |(sk, bts)| (addr, sk, bts.iter().map(|b| b.as_ref()))) - }) - } - #[inline(always)] - fn additional_proofs(&self) -> impl Iterator { - self.storage_trace - .deletion_proofs - .iter() - .map(|s| s.as_ref()) - } - #[inline] - fn codes(&self) -> impl ExactSizeIterator { - self.codes.iter().map(|code| code.code.as_ref()) - } - #[inline] - fn start_l1_queue_index(&self) -> u64 { - self.start_l1_queue_index - } -} - -impl BlockTraceRevmExt for BlockTrace { - type Tx = TransactionTrace; - - #[inline] - fn number(&self) -> u64 { - self.header.number.expect("incomplete block").as_u64() - } - #[inline] - fn block_hash(&self) -> B256 { - self.header.hash.expect("incomplete block").0.into() - } - #[inline] - fn chain_id(&self) -> u64 { - self.chain_id - } - #[inline] - fn coinbase(&self) -> revm_primitives::Address { - self.coinbase.address.0.into() - } - #[inline] - fn timestamp(&self) -> U256 { - U256::from_limbs(self.header.timestamp.0) - } - #[inline] - fn gas_limit(&self) -> U256 { - U256::from_limbs(self.header.gas_limit.0) - } - #[inline] - fn base_fee_per_gas(&self) -> Option { - self.header.base_fee_per_gas.map(|b| U256::from_limbs(b.0)) - } - #[inline] - fn difficulty(&self) -> U256 { - U256::from_limbs(self.header.difficulty.0) - } - #[inline] - fn prevrandao(&self) -> Option { - self.header.mix_hash.map(|h| B256::from(h.0)) - } - #[inline] - fn transactions(&self) -> impl Iterator { - self.transactions.iter() - } -} - -impl BlockZktrieExt for BlockTrace {} - -impl BlockChunkExt for BlockTrace {} diff --git a/crates/primitives/src/imp/block_trace_v2.rs b/crates/primitives/src/imp/block_trace_v2.rs deleted file mode 100644 index c12cfcf..0000000 --- a/crates/primitives/src/imp/block_trace_v2.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::*; -use eth_types::l2_types::{BlockTraceV2, TransactionTrace}; -use eth_types::{Address, H256}; -use revm_primitives::{B256, U256}; - -impl BlockTraceExt for BlockTraceV2 { - #[inline(always)] - fn root_before(&self) -> H256 { - self.storage_trace.root_before - } - #[inline(always)] - fn root_after(&self) -> H256 { - self.storage_trace.root_after - } - #[inline(always)] - fn withdraw_root(&self) -> H256 { - self.withdraw_trie_root - } - #[inline(always)] - fn flatten_proofs(&self) -> Option> { - if self.storage_trace.flatten_proofs.is_empty() { - None - } else { - Some( - self.storage_trace - .flatten_proofs - .iter() - .map(|(k, v)| (k, v.as_ref())), - ) - } - } - #[inline(always)] - fn address_hashes(&self) -> impl Iterator { - self.storage_trace - .address_hashes - .iter() - .map(|(k, v)| (k, v)) - } - #[inline(always)] - fn store_key_hashes(&self) -> impl Iterator { - self.storage_trace - .store_key_hashes - .iter() - .map(|(k, v)| (k, v)) - } - #[inline(always)] - fn account_proofs(&self) -> impl Iterator)> { - self.storage_trace - .proofs - .iter() - .map(|(addr, b)| (addr, b.iter().map(|b| b.as_ref()))) - } - #[inline(always)] - fn storage_proofs( - &self, - ) -> impl Iterator)> { - self.storage_trace - .storage_proofs - .iter() - .flat_map(|(addr, map)| { - map.iter() - .map(move |(sk, bts)| (addr, sk, bts.iter().map(|b| b.as_ref()))) - }) - } - #[inline(always)] - fn additional_proofs(&self) -> impl Iterator { - self.storage_trace - .deletion_proofs - .iter() - .map(|s| s.as_ref()) - } - #[inline] - fn codes(&self) -> impl ExactSizeIterator { - self.codes.iter().map(|code| code.code.as_ref()) - } - #[inline] - fn start_l1_queue_index(&self) -> u64 { - self.start_l1_queue_index - } -} - -impl BlockTraceRevmExt for BlockTraceV2 { - type Tx = TransactionTrace; - #[inline] - fn number(&self) -> u64 { - self.header.number.as_u64() - } - #[inline] - fn block_hash(&self) -> B256 { - self.header.hash.0.into() - } - #[inline] - fn chain_id(&self) -> u64 { - self.chain_id - } - #[inline] - fn coinbase(&self) -> revm_primitives::Address { - self.coinbase.address.0.into() - } - #[inline] - fn timestamp(&self) -> U256 { - U256::from_limbs(self.header.timestamp.0) - } - #[inline] - fn gas_limit(&self) -> U256 { - U256::from_limbs(self.header.gas_limit.0) - } - #[inline] - fn base_fee_per_gas(&self) -> Option { - self.header.base_fee_per_gas.map(|b| U256::from_limbs(b.0)) - } - #[inline] - fn difficulty(&self) -> U256 { - U256::from_limbs(self.header.difficulty.0) - } - #[inline] - fn prevrandao(&self) -> Option { - self.header - .mix_hash - .map(|h| revm_primitives::B256::from(h.0)) - } - #[inline] - fn transactions(&self) -> impl Iterator { - self.transactions.iter() - } -} - -impl BlockZktrieExt for BlockTraceV2 {} - -impl BlockChunkExt for BlockTraceV2 {} diff --git a/crates/primitives/src/imp/mod.rs b/crates/primitives/src/imp/mod.rs deleted file mode 100644 index 4b21688..0000000 --- a/crates/primitives/src/imp/mod.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::Transaction; -use eth_types::l2_types::TransactionTrace; -use eth_types::H256; -use revm_primitives::{AccessListItem, TransactTo, B256, U256}; - -mod archived_block_trace_v2; -mod blanket; -mod block_trace; -mod block_trace_v2; - -impl Transaction for TransactionTrace { - #[inline] - fn raw_type(&self) -> u8 { - self.type_ - } - #[inline] - fn tx_hash(&self) -> B256 { - B256::new(self.tx_hash.0) - } - #[inline] - fn caller(&self) -> revm_primitives::Address { - self.from.0.into() - } - #[inline] - fn gas_limit(&self) -> u64 { - self.gas - } - #[inline] - fn gas_price(&self) -> U256 { - U256::from_limbs(self.gas_price.0) - } - #[inline] - fn transact_to(&self) -> TransactTo { - match self.to { - Some(to) => TransactTo::Call(to.0.into()), - None => TransactTo::Create, - } - } - #[inline] - fn value(&self) -> U256 { - U256::from_limbs(self.value.0) - } - #[inline] - fn data(&self) -> revm_primitives::Bytes { - revm_primitives::Bytes::copy_from_slice(self.data.as_ref()) - } - #[inline] - fn nonce(&self) -> u64 { - self.nonce - } - #[inline] - fn chain_id(&self) -> u64 { - self.chain_id.as_u64() - } - #[inline] - fn access_list(&self) -> Vec { - self.access_list - .as_ref() - .map(|v| { - v.iter() - .map(|e| AccessListItem { - address: e.address.0.into(), - storage_keys: e - .storage_keys - .iter() - .map(|s| s.to_fixed_bytes().into()) - .collect(), - }) - .collect() - }) - .unwrap_or_default() - } - #[inline] - fn gas_priority_fee(&self) -> Option { - self.gas_tip_cap.map(|g| U256::from_limbs(g.0)) - } - #[inline] - fn to_eth_tx( - &self, - block_hash: B256, - block_number: u64, - transaction_index: usize, - base_fee_per_gas: Option, - ) -> eth_types::Transaction { - self.to_eth_tx( - Some(H256::from(block_hash.0)), - Some(block_number.into()), - Some((transaction_index as u64).into()), - base_fee_per_gas.map(|b| eth_types::U256(*b.as_limbs())), - ) - } -} diff --git a/crates/primitives/src/lib.rs b/crates/primitives/src/lib.rs index 4bf1ddb..00ba421 100644 --- a/crates/primitives/src/lib.rs +++ b/crates/primitives/src/lib.rs @@ -1,4 +1,6 @@ //! Stateless Block Verifier primitives library. +#[macro_use] +extern crate sbv_utils; use crate::types::{TxL1Msg, TypedTransaction}; use alloy::{ @@ -7,8 +9,11 @@ use alloy::{ primitives::{Bytes, ChainId, Signature, SignatureError, TxKind}, }; use std::fmt::Debug; -use std::sync::Once; -use zktrie::ZkMemoryDb; +use zktrie_ng::{ + db::KVDatabase, + hash::poseidon::Poseidon, + trie::{Node, MAGIC_NODE_BYTES}, +}; /// Predeployed contracts pub mod predeployed; @@ -19,21 +24,7 @@ pub use alloy::consensus as alloy_consensus; pub use alloy::consensus::Transaction; pub use alloy::primitives as alloy_primitives; pub use alloy::primitives::{Address, B256, U256}; -pub use zktrie as zk_trie; - -/// Initialize the hash scheme for zkTrie. -pub fn init_hash_scheme() { - static INIT: Once = Once::new(); - INIT.call_once(|| { - zktrie::init_hash_scheme_simple(|a: &[u8; 32], b: &[u8; 32], domain: &[u8; 32]| { - use poseidon_bn254::{hash_with_domain, Fr, PrimeField}; - let a = Fr::from_bytes(a).into_option()?; - let b = Fr::from_bytes(b).into_option()?; - let domain = Fr::from_bytes(domain).into_option()?; - Some(hash_with_domain(&[a, b], domain).to_repr()) - }); - }); -} +pub use zktrie_ng as zk_trie; /// Blanket trait for block trace extensions. pub trait Block: Debug { @@ -89,10 +80,18 @@ pub trait Block: Debug { /// Update zktrie state from trace #[inline] - fn build_zktrie_db(&self, zktrie_db: &mut ZkMemoryDb) { - for (_, bytes) in self.flatten_proofs() { - zktrie_db.add_node_bytes(bytes, None).unwrap(); + fn build_zktrie_db(&self, db: &mut Db) -> Result<(), Db::Error> { + for (k, bytes) in self.flatten_proofs() { + if bytes == MAGIC_NODE_BYTES { + continue; + } + let node = Node::::try_from(bytes).expect("invalid node"); + let node_hash = node.get_or_calculate_node_hash().expect("infallible"); + debug_assert_eq!(k.as_slice(), node_hash.as_slice()); + dev_trace!("put zktrie node: {:?}", node); + db.put_owned(node_hash.as_slice(), node.canonical_value(false))?; } + Ok(()) } /// Number of l1 transactions diff --git a/crates/sbv/Cargo.toml b/crates/sbv/Cargo.toml index 44817ac..4a07c1c 100644 --- a/crates/sbv/Cargo.toml +++ b/crates/sbv/Cargo.toml @@ -17,7 +17,7 @@ sbv-utils.workspace = true [features] 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"] +dev = ["sbv-core/dev", "sbv-utils/dev", "sbv-primitives/dev"] metrics = ["sbv-core/metrics", "sbv-utils/metrics"] # sp1 related diff --git a/crates/utils/src/utils/debug.rs b/crates/utils/src/utils/debug.rs index 6c7ea33..8996462 100644 --- a/crates/utils/src/utils/debug.rs +++ b/crates/utils/src/utils/debug.rs @@ -1,4 +1,4 @@ -use revm::primitives::{Address, B256, U256}; +use revm::primitives::{AccountInfo, Address, B256, U256}; use std::collections::BTreeMap; #[derive(Debug, serde::Serialize)] @@ -39,25 +39,16 @@ impl DebugRecorder { /// Record the account data. #[cfg(feature = "debug-account")] #[allow(clippy::too_many_arguments)] - pub fn record_account( - &mut self, - addr: Address, - nonce: u64, - balance: U256, - code_hash: B256, - poseidon_code_hash: B256, - code_size: u64, - storage_root: B256, - ) { + pub fn record_account(&mut self, addr: Address, info: AccountInfo, storage_root: B256) { self.accounts.insert( addr, AccountData { addr, - nonce, - balance, - code_hash, - poseidon_code_hash, - code_size, + nonce: info.nonce, + balance: info.balance, + code_hash: info.code_hash, + poseidon_code_hash: info.poseidon_code_hash, + code_size: info.code_size as u64, storage_root, }, );