diff --git a/Cargo.lock b/Cargo.lock index cb59f0a2c3..a4d3fee6b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "ahash" version = "0.8.11" @@ -50,6 +56,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.18" @@ -72,10 +93,27 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae09ffd7c29062431dd86061deefe4e3c6f07fa0d674930095f8dcedb0baf02c" dependencies = [ - "alloy-eips", + "alloy-eips 0.6.4", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.6.4", + "auto_impl", + "c-kzg", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-consensus" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4138dc275554afa6f18c4217262ac9388790b2fc393c2dfe03c51d357abf013" +dependencies = [ + "alloy-eips 0.9.2", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.9.2", + "alloy-trie", "auto_impl", "c-kzg", "derive_more 1.0.0", @@ -105,6 +143,18 @@ dependencies = [ "serde", ] +[[package]] +name = "alloy-eip7702" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabf647eb4650c91a9d38cb6f972bb320009e7e9d61765fb688a86f1563b33e8" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more 1.0.0", + "serde", +] + [[package]] name = "alloy-eips" version = "0.6.4" @@ -112,10 +162,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b6aa3961694b30ba53d41006131a2fca3bdab22e4c344e46db2c639e7c2dfdd" dependencies = [ "alloy-eip2930", - "alloy-eip7702", + "alloy-eip7702 0.4.1", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.6.4", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2 0.10.8", +] + +[[package]] +name = "alloy-eips" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52dd5869ed09e399003e0e0ec6903d981b2a92e74c5d37e6b40890bad2517526" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702 0.5.0", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.9.2", "c-kzg", "derive_more 1.0.0", "once_cell", @@ -125,9 +193,9 @@ dependencies = [ [[package]] name = "alloy-json-abi" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84c506bf264110fa7e90d9924f742f40ef53c6572ea56a0b0bd714a567ed389" +checksum = "731ea743b3d843bc657e120fb1d1e9cc94f5dab8107e35a82125a63e6420a102" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -145,7 +213,7 @@ dependencies = [ "alloy-sol-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tracing", ] @@ -155,13 +223,13 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea94b8ceb5c75d7df0a93ba0acc53b55a22b47b532b600a800a87ef04eb5b0b4" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.6.4", + "alloy-eips 0.6.4", "alloy-json-rpc", "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", - "alloy-serde", + "alloy-serde 0.6.4", "alloy-signer", "alloy-sol-types", "async-trait", @@ -169,7 +237,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -178,18 +246,18 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df9f3e281005943944d15ee8491534a1c7b3cbf7a7de26f8c433b842b93eb5f9" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.6.4", + "alloy-eips 0.6.4", "alloy-primitives", - "alloy-serde", + "alloy-serde 0.6.4", "serde", ] [[package]] name = "alloy-primitives" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fce5dbd6a4f118eecc4719eaa9c7ffc31c315e6c5ccde3642db927802312425" +checksum = "788bb18e8f61d5d9340b52143f27771daf7e1dccbaf2741621d2493f9debf52e" dependencies = [ "alloy-rlp", "arbitrary", @@ -201,7 +269,6 @@ dependencies = [ "foldhash", "getrandom", "hashbrown 0.15.0", - "hex-literal", "indexmap", "itoa", "k256", @@ -224,8 +291,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c1f9eede27bf4c13c099e8e64d54efd7ce80ef6ea47478aa75d5d74e2dba3b" dependencies = [ "alloy-chains", - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.6.4", + "alloy-eips 0.6.4", "alloy-json-rpc", "alloy-network", "alloy-network-primitives", @@ -247,7 +314,7 @@ dependencies = [ "schnellru", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tracing", "url", @@ -256,9 +323,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" +checksum = "f542548a609dca89fcd72b3b9f355928cf844d4363c5eed9c5273a3dd225e097" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -267,9 +334,9 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" +checksum = "5a833d97bf8a5f0f878daf2c8451fff7de7f9de38baa5a45d936ec718d81255a" dependencies = [ "proc-macro2", "quote", @@ -305,12 +372,12 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8a477281940d82d29315846c7216db45b15e90bcd52309da9f54bcf7ad94a11" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.6.4", + "alloy-eips 0.6.4", "alloy-network-primitives", "alloy-primitives", "alloy-rlp", - "alloy-serde", + "alloy-serde 0.6.4", "alloy-sol-types", "derive_more 1.0.0", "itertools 0.13.0", @@ -329,6 +396,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "alloy-serde" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0465c71d4dced7525f408d84873aeebb71faf807d22d74c4a426430ccd9b55" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + [[package]] name = "alloy-signer" version = "0.6.4" @@ -340,14 +418,14 @@ dependencies = [ "auto_impl", "elliptic-curve", "k256", - "thiserror", + "thiserror 1.0.63", ] [[package]] name = "alloy-sol-macro" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9343289b4a7461ed8bab8618504c995c049c082b70c7332efd7b32125633dc05" +checksum = "a07b74d48661ab2e4b50bb5950d74dbff5e61dd8ed03bb822281b706d54ebacb" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -359,9 +437,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4222d70bec485ceccc5d8fd4f2909edd65b5d5e43d4aca0b5dcee65d519ae98f" +checksum = "19cc9c7f20b90f9be1a8f71a3d8e283a43745137b0837b1a1cb13159d37cad72" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -377,9 +455,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e17f2677369571b976e51ea1430eb41c3690d344fef567b840bfc0b01b6f83a" +checksum = "713b7e6dfe1cb2f55c80fb05fd22ed085a1b4e48217611365ed0ae598a74c6ac" dependencies = [ "const-hex", "dunce", @@ -392,9 +470,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa64d80ae58ffaafdff9d5d84f58d03775f66c84433916dc9a64ed16af5755da" +checksum = "1eda2711ab2e1fb517fc6e2ffa9728c9a232e296d16810810e6957b781a1b8bc" dependencies = [ "serde", "winnow", @@ -402,9 +480,9 @@ dependencies = [ [[package]] name = "alloy-sol-types" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6520d427d4a8eb7aa803d852d7a52ceb0c519e784c292f64bb339e636918cf27" +checksum = "e3b478bc9c0c4737a04cd976accde4df7eba0bdc0d90ad6ff43d58bc93cf79c1" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -425,7 +503,7 @@ dependencies = [ "futures-utils-wasm", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "tokio", "tower 0.5.1", "tracing", @@ -448,6 +526,22 @@ dependencies = [ "url", ] +[[package]] +name = "alloy-trie" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6917c79e837aa7b77b7a6dae9f89cbe15313ac161c4d3cfaf8909ef21f3d22d8" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "arrayvec", + "derive_more 1.0.0", + "nybbles", + "serde", + "smallvec", + "tracing", +] + [[package]] name = "anes" version = "0.1.6" @@ -650,6 +744,9 @@ name = "arrayvec" version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +dependencies = [ + "serde", +] [[package]] name = "async-stream" @@ -675,9 +772,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", @@ -727,7 +824,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -832,6 +929,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "brotli" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -1021,9 +1139,9 @@ dependencies = [ [[package]] name = "const-hex" -version = "1.12.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +checksum = "4b0485bab839b018a8f1723fc5391819fea5f8f0f32288ef8a735fd096b6160c" dependencies = [ "cfg-if", "cpufeatures", @@ -1362,7 +1480,7 @@ dependencies = [ "serde", "serde_json", "sha3", - "thiserror", + "thiserror 1.0.63", "uint", ] @@ -1410,7 +1528,7 @@ dependencies = [ "pin-project", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", ] [[package]] @@ -1435,7 +1553,7 @@ dependencies = [ "serde_json", "strum", "tempfile", - "thiserror", + "thiserror 1.0.63", "tiny-keccak", "unicode-xid", ] @@ -1444,8 +1562,8 @@ dependencies = [ name = "example-block-traces" version = "0.0.0" dependencies = [ - "alloy-consensus", - "alloy-eips", + "alloy-consensus 0.6.4", + "alloy-eips 0.6.4", "alloy-provider", "anyhow", "indicatif", @@ -1491,7 +1609,7 @@ dependencies = [ name = "example-uniswap-get-reserves" version = "0.0.0" dependencies = [ - "alloy-eips", + "alloy-eips 0.6.4", "alloy-provider", "alloy-sol-types", "anyhow", @@ -1504,7 +1622,7 @@ dependencies = [ name = "example-uniswap-v2-usdc-swap" version = "0.0.0" dependencies = [ - "alloy-eips", + "alloy-eips 0.6.4", "alloy-provider", "alloy-sol-types", "alloy-transport-http", @@ -1590,9 +1708,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" [[package]] name = "foreign-types" @@ -1852,12 +1970,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - [[package]] name = "hmac" version = "0.12.1" @@ -2268,6 +2380,32 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "maili-protocol" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfcd6cd2bab854872c24d551308cb84df4c20db38593b4392d68cacd75d4c60c" +dependencies = [ + "alloc-no-stdlib", + "alloy-consensus 0.9.2", + "alloy-eips 0.9.2", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.9.2", + "alloy-sol-types", + "async-trait", + "brotli", + "derive_more 1.0.0", + "miniz_oxide 0.8.2", + "op-alloy-consensus", + "op-alloy-genesis", + "rand", + "serde", + "thiserror 2.0.10", + "tracing", + "unsigned-varint", +] + [[package]] name = "memchr" version = "2.7.4" @@ -2295,6 +2433,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "1.0.1" @@ -2446,6 +2593,17 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" +[[package]] +name = "nybbles" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983bb634df7248924ee0c4c3a749609b5abcb082c28fffe3254b3eb3602b307" +dependencies = [ + "const-hex", + "serde", + "smallvec", +] + [[package]] name = "object" version = "0.36.5" @@ -2467,6 +2625,37 @@ version = "11.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +[[package]] +name = "op-alloy-consensus" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442518bf0ef88f4d79409527565b8cdee235c891f2e2a829497caec5ed9d8d1c" +dependencies = [ + "alloy-consensus 0.9.2", + "alloy-eips 0.9.2", + "alloy-primitives", + "alloy-rlp", + "alloy-serde 0.9.2", + "derive_more 1.0.0", + "serde", + "thiserror 2.0.10", +] + +[[package]] +name = "op-alloy-genesis" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2af7fee1fa297569199b524493e50355eab3f1bff75cef492036eb4a3ffb5e" +dependencies = [ + "alloy-consensus 0.9.2", + "alloy-eips 0.9.2", + "alloy-primitives", + "alloy-sol-types", + "serde", + "serde_repr", + "thiserror 2.0.10", +] + [[package]] name = "opaque-debug" version = "0.3.1" @@ -2631,7 +2820,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", - "thiserror", + "thiserror 1.0.63", "ucd-trie", ] @@ -3107,7 +3296,7 @@ dependencies = [ name = "revm-database" version = "1.0.0" dependencies = [ - "alloy-eips", + "alloy-eips 0.6.4", "alloy-provider", "alloy-sol-types", "alloy-transport", @@ -3198,6 +3387,7 @@ dependencies = [ "alloy-sol-types", "anyhow", "indicatif", + "maili-protocol", "once_cell", "revm", "revm-database", @@ -3294,7 +3484,7 @@ dependencies = [ "revm-statetest-types", "serde", "serde_json", - "thiserror", + "thiserror 1.0.63", "triehash", "walkdir", ] @@ -3454,9 +3644,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" dependencies = [ "rand", ] @@ -3703,18 +3893,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.209" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -3734,6 +3924,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -3820,6 +4021,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "snowbridge-amcl" @@ -3963,9 +4167,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "0.8.12" +version = "0.8.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f76fe0a3e1476bdaa0775b9aec5b869ed9520c2b2fedfe9c6df3618f8ea6290b" +checksum = "31e89d8bf2768d277f40573c83a02a099e96d96dd3104e13ea676194e61ac4b0" dependencies = [ "paste", "proc-macro2", @@ -4033,7 +4237,16 @@ version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.63", +] + +[[package]] +name = "thiserror" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ac7f54ca534db81081ef1c1e7f6ea8a3ef428d2fc069097c079443d24124d3" +dependencies = [ + "thiserror-impl 2.0.10", ] [[package]] @@ -4047,6 +4260,17 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "thiserror-impl" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9465d30713b56a37ede7185763c3492a91be2f5fa68d958c44e41ab9248beb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -4223,9 +4447,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -4234,9 +4458,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -4245,9 +4469,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -4331,6 +4555,12 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/crates/optimism/Cargo.toml b/crates/optimism/Cargo.toml index 8190befb22..6666c87457 100644 --- a/crates/optimism/Cargo.toml +++ b/crates/optimism/Cargo.toml @@ -27,6 +27,9 @@ revm.workspace = true precompile = { workspace = true, features = ["secp256r1"] } inspector.workspace = true +# optimism +maili-protocol = "0.1.2" + # static precompile sets. once_cell = { version = "1.19", default-features = false, features = ["alloc"] } diff --git a/crates/optimism/src/evm.rs b/crates/optimism/src/evm.rs index d1674a7806..0c29e2f786 100644 --- a/crates/optimism/src/evm.rs +++ b/crates/optimism/src/evm.rs @@ -2,11 +2,13 @@ use crate::{ handler::{ precompiles::OpPrecompileProvider, OpExecution, OpHandler, OpPreExecution, OpValidation, }, - L1BlockInfo, OpSpec, OpTransaction, + OpSpec, OpTransaction, }; use inspector::{inspector_context::InspectorContext, InspectorEthFrame}; +use maili_protocol::L1BlockInfoTx; use revm::{ context::{block::BlockEnv, tx::TxEnv, CfgEnv, Context}, + context_interface::Journal, context_interface::result::{EVMError, InvalidTransaction}, database_interface::Database, Evm, JournaledState, @@ -16,7 +18,28 @@ use revm::{ pub type OpError = EVMError<::Error, InvalidTransaction>; /// Optimism Context -pub type OpContext = Context, CfgEnv, DB, L1BlockInfo>; +pub type OpContext = Context, CfgEnv, DB, L1BlockInfoTx>; + +/// Defines functionality to retrieve the [`L1BlockInfoTx`]. +pub trait L1BlockInfoGetter { + /// Returns the [`L1BlockInfoTx`] of the context. + fn l1_block_info(&self) -> &L1BlockInfoTx; + + /// Returns the mutable reference to the [`L1BlockInfoTx`] of the context. + fn l1_block_info_mut(&mut self) -> &mut L1BlockInfoTx; +} + +impl> L1BlockInfoGetter + for Context +{ + fn l1_block_info(&self) -> &L1BlockInfoTx { + &self.chain + } + + fn l1_block_info_mut(&mut self) -> &mut L1BlockInfoTx { + &mut self.chain + } +} /// Optimism EVM type pub type OpEvm = Evm, OpContext, OpHandler, OpError>>; @@ -24,7 +47,7 @@ pub type OpEvm = Evm, OpContext, OpHandler, Op pub type InspCtxType = InspectorContext< INSP, DB, - Context, DB, JournaledState, L1BlockInfo>, + Context, DB, JournaledState, L1BlockInfoTx>, >; pub type InspectorOpEvm = Evm< diff --git a/crates/optimism/src/handler.rs b/crates/optimism/src/handler.rs index 9b5256b43c..5f62a8ed08 100644 --- a/crates/optimism/src/handler.rs +++ b/crates/optimism/src/handler.rs @@ -8,8 +8,9 @@ use crate::{ deposit::{DepositTransaction, DEPOSIT_TRANSACTION_TYPE}, OpTransactionError, OpTxTrait, }, - L1BlockInfoGetter, OpSpec, OpSpecId, OptimismHaltReason, BASE_FEE_RECIPIENT, L1_FEE_RECIPIENT, + L1BlockInfoGetter, OpSpec, OpSpecId, OptimismHaltReason, L1_FEE_RECIPIENT, BASE_FEE_RECIPIENT, }; +use maili_protocol::L1BlockInfoTx; use precompiles::OpPrecompileProvider; use revm::{ context_interface::{ @@ -112,8 +113,8 @@ where // The L1-cost fee is only computed for Optimism non-deposit transactions. let spec = context.cfg().spec(); if context.tx().tx_type() != DEPOSIT_TRANSACTION_TYPE { - let l1_block_info: crate::L1BlockInfo = - super::L1BlockInfo::try_fetch(context.db(), spec)?; + let l1_block_info: L1BlockInfoTx = + crate::l1block::try_fetch(context.db(), spec)?; // Storage L1 block info for later use. *context.l1_block_info_mut() = l1_block_info; diff --git a/crates/optimism/src/l1block.rs b/crates/optimism/src/l1block.rs index 4ea6f47449..c9dfcaad2e 100644 --- a/crates/optimism/src/l1block.rs +++ b/crates/optimism/src/l1block.rs @@ -1,12 +1,10 @@ -use crate::{fast_lz::flz_compress_len, OpSpecId}; -use core::ops::Mul; +use crate::OpSpecId; use revm::{ - context_interface::Journal, database_interface::Database, primitives::{address, Address, U256}, specification::hardfork::SpecId, - Context, }; +use maili_protocol::L1BlockInfoTx; use super::OpSpec; @@ -53,478 +51,56 @@ const L1_COST_INTERCEPT: u64 = 42_585_600; /// const MIN_TX_SIZE_SCALED: u64 = 100 * 1_000_000; -/// L1 block info -/// -/// We can extract L1 epoch data from each L2 block, by looking at the `setL1BlockValues` -/// transaction data. This data is then used to calculate the L1 cost of a transaction. -/// -/// Here is the format of the `setL1BlockValues` transaction data: -/// -/// setL1BlockValues(uint64 _number, uint64 _timestamp, uint256 _basefee, bytes32 _hash, -/// uint64 _sequenceNumber, bytes32 _batcherHash, uint256 _l1FeeOverhead, uint256 _l1FeeScalar) -/// -/// For now, we only care about the fields necessary for L1 cost calculation. -#[derive(Clone, Debug, Default, PartialEq, Eq)] -pub struct L1BlockInfo { - /// The base fee of the L1 origin block. - pub l1_base_fee: U256, - /// The current L1 fee overhead. None if Ecotone is activated. - pub l1_fee_overhead: Option, - /// The current L1 fee scalar. - pub l1_base_fee_scalar: U256, - /// The current L1 blob base fee. None if Ecotone is not activated, except if `empty_scalars` is `true`. - pub l1_blob_base_fee: Option, - /// The current L1 blob base fee scalar. None if Ecotone is not activated. - pub l1_blob_base_fee_scalar: Option, - /// True if Ecotone is activated, but the L1 fee scalars have not yet been set. - pub(crate) empty_scalars: bool, -} - -impl L1BlockInfo { - /// Try to fetch the L1 block info from the database. - pub fn try_fetch(db: &mut DB, spec_id: OpSpec) -> Result { - // Ensure the L1 Block account is loaded into the cache after Ecotone. With EIP-4788, it is no longer the case - // that the L1 block account is loaded into the cache prior to the first inquiry for the L1 block info. - if spec_id.is_enabled_in(SpecId::CANCUN) { - let _ = db.basic(L1_BLOCK_CONTRACT)?; - } - - let l1_base_fee = db.storage(L1_BLOCK_CONTRACT, L1_BASE_FEE_SLOT)?; - - if !spec_id.is_enabled_in(OpSpecId::ECOTONE) { - let l1_fee_overhead = db.storage(L1_BLOCK_CONTRACT, L1_OVERHEAD_SLOT)?; - let l1_fee_scalar = db.storage(L1_BLOCK_CONTRACT, L1_SCALAR_SLOT)?; - - Ok(L1BlockInfo { - l1_base_fee, - l1_fee_overhead: Some(l1_fee_overhead), - l1_base_fee_scalar: l1_fee_scalar, - ..Default::default() - }) - } else { - let l1_blob_base_fee = db.storage(L1_BLOCK_CONTRACT, ECOTONE_L1_BLOB_BASE_FEE_SLOT)?; - let l1_fee_scalars = db - .storage(L1_BLOCK_CONTRACT, ECOTONE_L1_FEE_SCALARS_SLOT)? - .to_be_bytes::<32>(); - - let l1_base_fee_scalar = U256::from_be_slice( - l1_fee_scalars[BASE_FEE_SCALAR_OFFSET..BASE_FEE_SCALAR_OFFSET + 4].as_ref(), - ); - let l1_blob_base_fee_scalar = U256::from_be_slice( - l1_fee_scalars[BLOB_BASE_FEE_SCALAR_OFFSET..BLOB_BASE_FEE_SCALAR_OFFSET + 4] - .as_ref(), - ); - - // Check if the L1 fee scalars are empty. If so, we use the Bedrock cost function. - // The L1 fee overhead is only necessary if `empty_scalars` is true, as it was deprecated in Ecotone. - let empty_scalars = l1_blob_base_fee.is_zero() - && l1_fee_scalars[BASE_FEE_SCALAR_OFFSET..BLOB_BASE_FEE_SCALAR_OFFSET + 4] - == EMPTY_SCALARS; - let l1_fee_overhead = empty_scalars - .then(|| db.storage(L1_BLOCK_CONTRACT, L1_OVERHEAD_SLOT)) - .transpose()?; - - Ok(L1BlockInfo { - l1_base_fee, - l1_base_fee_scalar, - l1_blob_base_fee: Some(l1_blob_base_fee), - l1_blob_base_fee_scalar: Some(l1_blob_base_fee_scalar), - empty_scalars, - l1_fee_overhead, - }) - } - } - - /// Calculate the data gas for posting the transaction on L1. Calldata costs 16 gas per byte - /// after compression. - /// - /// Prior to fjord, calldata costs 16 gas per non-zero byte and 4 gas per zero byte. - /// - /// Prior to regolith, an extra 68 non-zero bytes were included in the rollup data costs to - /// account for the empty signature. - pub fn data_gas(&self, input: &[u8], spec_id: OpSpec) -> U256 { - if spec_id.is_enabled_in(OpSpecId::FJORD) { - let estimated_size = self.tx_estimated_size_fjord(input); - - return estimated_size - .saturating_mul(U256::from(NON_ZERO_BYTE_COST)) - .wrapping_div(U256::from(1_000_000)); - }; - - let mut rollup_data_gas_cost = U256::from(input.iter().fold(0, |acc, byte| { - acc + if *byte == 0x00 { - ZERO_BYTE_COST - } else { - NON_ZERO_BYTE_COST - } - })); - - // Prior to regolith, an extra 68 non zero bytes were included in the rollup data costs. - if !spec_id.is_enabled_in(OpSpecId::REGOLITH) { - rollup_data_gas_cost += U256::from(NON_ZERO_BYTE_COST).mul(U256::from(68)); - } - - rollup_data_gas_cost - } - - // Calculate the estimated compressed transaction size in bytes, scaled by 1e6. - // This value is computed based on the following formula: - // max(minTransactionSize, intercept + fastlzCoef*fastlzSize) - fn tx_estimated_size_fjord(&self, input: &[u8]) -> U256 { - let fastlz_size = flz_compress_len(input) as u64; - - U256::from( - fastlz_size - .saturating_mul(L1_COST_FASTLZ_COEF) - .saturating_sub(L1_COST_INTERCEPT) - .max(MIN_TX_SIZE_SCALED), - ) - } - - /// Calculate the gas cost of a transaction based on L1 block data posted on L2, depending on the [OpSpec] passed. - pub fn calculate_tx_l1_cost(&self, input: &[u8], spec_id: OpSpec) -> U256 { - // If the input is a deposit transaction or empty, the default value is zero. - if input.is_empty() || input.first() == Some(&0x7F) { - return U256::ZERO; - } - - if spec_id.is_enabled_in(OpSpecId::FJORD) { - self.calculate_tx_l1_cost_fjord(input) - } else if spec_id.is_enabled_in(OpSpecId::ECOTONE) { - self.calculate_tx_l1_cost_ecotone(input, spec_id) - } else { - self.calculate_tx_l1_cost_bedrock(input, spec_id) - } - } - - /// Calculate the gas cost of a transaction based on L1 block data posted on L2, pre-Ecotone. - fn calculate_tx_l1_cost_bedrock(&self, input: &[u8], spec_id: OpSpec) -> U256 { - let rollup_data_gas_cost = self.data_gas(input, spec_id); - rollup_data_gas_cost - .saturating_add(self.l1_fee_overhead.unwrap_or_default()) - .saturating_mul(self.l1_base_fee) - .saturating_mul(self.l1_base_fee_scalar) - .wrapping_div(U256::from(1_000_000)) - } - - /// Calculate the gas cost of a transaction based on L1 block data posted on L2, post-Ecotone. - /// - /// [OpSpecId::ECOTONE] L1 cost function: - /// `(calldataGas/16)*(l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar)/1e6` - /// - /// We divide "calldataGas" by 16 to change from units of calldata gas to "estimated # of bytes when compressed". - /// Known as "compressedTxSize" in the spec. - /// - /// Function is actually computed as follows for better precision under integer arithmetic: - /// `calldataGas*(l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar)/16e6` - fn calculate_tx_l1_cost_ecotone(&self, input: &[u8], spec_id: OpSpec) -> U256 { - // There is an edgecase where, for the very first Ecotone block (unless it is activated at Genesis), we must - // use the Bedrock cost function. To determine if this is the case, we can check if the Ecotone parameters are - // unset. - if self.empty_scalars { - return self.calculate_tx_l1_cost_bedrock(input, spec_id); - } - - let rollup_data_gas_cost = self.data_gas(input, spec_id); - let l1_fee_scaled = self.calculate_l1_fee_scaled_ecotone(); - - l1_fee_scaled - .saturating_mul(rollup_data_gas_cost) - .wrapping_div(U256::from(1_000_000 * NON_ZERO_BYTE_COST)) - } - - /// Calculate the gas cost of a transaction based on L1 block data posted on L2, post-Fjord. - /// - /// [OpSpecId::FJORD] L1 cost function: - /// `estimatedSize*(baseFeeScalar*l1BaseFee*16 + blobFeeScalar*l1BlobBaseFee)/1e12` - fn calculate_tx_l1_cost_fjord(&self, input: &[u8]) -> U256 { - let l1_fee_scaled = self.calculate_l1_fee_scaled_ecotone(); - let estimated_size = self.tx_estimated_size_fjord(input); - - estimated_size - .saturating_mul(l1_fee_scaled) - .wrapping_div(U256::from(1_000_000_000_000u64)) +/// Try to fetch the L1 block info from the database. +pub fn try_fetch(db: &mut DB, spec_id: OpSpec) -> Result { + // Ensure the L1 Block account is loaded into the cache after Ecotone. With EIP-4788, it is no longer the case + // that the L1 block account is loaded into the cache prior to the first inquiry for the L1 block info. + if spec_id.is_enabled_in(SpecId::CANCUN) { + let _ = db.basic(L1_BLOCK_CONTRACT)?; } - // l1BaseFee*16*l1BaseFeeScalar + l1BlobBaseFee*l1BlobBaseFeeScalar - fn calculate_l1_fee_scaled_ecotone(&self) -> U256 { - let calldata_cost_per_byte = self - .l1_base_fee - .saturating_mul(U256::from(NON_ZERO_BYTE_COST)) - .saturating_mul(self.l1_base_fee_scalar); - let blob_cost_per_byte = self - .l1_blob_base_fee - .unwrap_or_default() - .saturating_mul(self.l1_blob_base_fee_scalar.unwrap_or_default()); + let l1_base_fee = db.storage(L1_BLOCK_CONTRACT, L1_BASE_FEE_SLOT)?; - calldata_cost_per_byte.saturating_add(blob_cost_per_byte) - } -} - -pub trait L1BlockInfoGetter { - fn l1_block_info(&self) -> &L1BlockInfo; - fn l1_block_info_mut(&mut self) -> &mut L1BlockInfo; -} - -impl> L1BlockInfoGetter - for Context -{ - fn l1_block_info(&self) -> &L1BlockInfo { - &self.chain - } - - fn l1_block_info_mut(&mut self) -> &mut L1BlockInfo { - &mut self.chain - } -} - -#[cfg(test)] -mod tests { - use super::*; - use revm::primitives::{bytes, hex}; - - #[test] - fn test_data_gas_non_zero_bytes() { - let l1_block_info = L1BlockInfo { - l1_base_fee: U256::from(1_000_000), - l1_fee_overhead: Some(U256::from(1_000_000)), - l1_base_fee_scalar: U256::from(1_000_000), - ..Default::default() - }; - - // 0xFACADE = 6 nibbles = 3 bytes - // 0xFACADE = 1111 1010 . 1100 1010 . 1101 1110 - - // Pre-regolith (ie bedrock) has an extra 68 non-zero bytes - // gas cost = 3 non-zero bytes * NON_ZERO_BYTE_COST + NON_ZERO_BYTE_COST * 68 - // gas cost = 3 * 16 + 68 * 16 = 1136 - let input = bytes!("FACADE"); - let bedrock_data_gas = l1_block_info.data_gas(&input, OpSpecId::BEDROCK.into()); - assert_eq!(bedrock_data_gas, U256::from(1136)); - - // Regolith has no added 68 non zero bytes - // gas cost = 3 * 16 = 48 - let regolith_data_gas = l1_block_info.data_gas(&input, OpSpecId::REGOLITH.into()); - assert_eq!(regolith_data_gas, U256::from(48)); - - // Fjord has a minimum compressed size of 100 bytes - // gas cost = 100 * 16 = 1600 - let fjord_data_gas = l1_block_info.data_gas(&input, OpSpecId::FJORD.into()); - assert_eq!(fjord_data_gas, U256::from(1600)); - } + if !spec_id.is_enabled_in(OpSpecId::ECOTONE) { + let l1_fee_overhead = db.storage(L1_BLOCK_CONTRACT, L1_OVERHEAD_SLOT)?; + let l1_fee_scalar = db.storage(L1_BLOCK_CONTRACT, L1_SCALAR_SLOT)?; - #[test] - fn test_data_gas_zero_bytes() { - let l1_block_info = L1BlockInfo { - l1_base_fee: U256::from(1_000_000), - l1_fee_overhead: Some(U256::from(1_000_000)), - l1_base_fee_scalar: U256::from(1_000_000), + Ok(L1BlockInfoTx { + l1_base_fee, + l1_fee_overhead: Some(l1_fee_overhead), + l1_base_fee_scalar: l1_fee_scalar, ..Default::default() - }; - - // 0xFA00CA00DE = 10 nibbles = 5 bytes - // 0xFA00CA00DE = 1111 1010 . 0000 0000 . 1100 1010 . 0000 0000 . 1101 1110 - - // Pre-regolith (ie bedrock) has an extra 68 non-zero bytes - // gas cost = 3 non-zero * NON_ZERO_BYTE_COST + 2 * ZERO_BYTE_COST + NON_ZERO_BYTE_COST * 68 - // gas cost = 3 * 16 + 2 * 4 + 68 * 16 = 1144 - let input = bytes!("FA00CA00DE"); - let bedrock_data_gas = l1_block_info.data_gas(&input, OpSpecId::BEDROCK.into()); - assert_eq!(bedrock_data_gas, U256::from(1144)); - - // Regolith has no added 68 non zero bytes - // gas cost = 3 * 16 + 2 * 4 = 56 - let regolith_data_gas = l1_block_info.data_gas(&input, OpSpecId::REGOLITH.into()); - assert_eq!(regolith_data_gas, U256::from(56)); - - // Fjord has a minimum compressed size of 100 bytes - // gas cost = 100 * 16 = 1600 - let fjord_data_gas = l1_block_info.data_gas(&input, OpSpecId::FJORD.into()); - assert_eq!(fjord_data_gas, U256::from(1600)); - } - - #[test] - fn test_calculate_tx_l1_cost() { - let l1_block_info = L1BlockInfo { - l1_base_fee: U256::from(1_000), - l1_fee_overhead: Some(U256::from(1_000)), - l1_base_fee_scalar: U256::from(1_000), - ..Default::default() - }; - - let input = bytes!("FACADE"); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::REGOLITH.into()); - assert_eq!(gas_cost, U256::from(1048)); - - // Zero rollup data gas cost should result in zero - let input = bytes!(""); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::REGOLITH.into()); - assert_eq!(gas_cost, U256::ZERO); - - // Deposit transactions with the EIP-2718 type of 0x7F should result in zero - let input = bytes!("7FFACADE"); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::REGOLITH.into()); - assert_eq!(gas_cost, U256::ZERO); - } - - #[test] - fn test_calculate_tx_l1_cost_ecotone() { - let mut l1_block_info = L1BlockInfo { - l1_base_fee: U256::from(1_000), - l1_base_fee_scalar: U256::from(1_000), - l1_blob_base_fee: Some(U256::from(1_000)), - l1_blob_base_fee_scalar: Some(U256::from(1_000)), - l1_fee_overhead: Some(U256::from(1_000)), - ..Default::default() - }; - - // calldataGas * (l1BaseFee * 16 * l1BaseFeeScalar + l1BlobBaseFee * l1BlobBaseFeeScalar) / (16 * 1e6) - // = (16 * 3) * (1000 * 16 * 1000 + 1000 * 1000) / (16 * 1e6) - // = 51 - let input = bytes!("FACADE"); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::ECOTONE.into()); - assert_eq!(gas_cost, U256::from(51)); - - // Zero rollup data gas cost should result in zero - let input = bytes!(""); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::ECOTONE.into()); - assert_eq!(gas_cost, U256::ZERO); - - // Deposit transactions with the EIP-2718 type of 0x7F should result in zero - let input = bytes!("7FFACADE"); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::ECOTONE.into()); - assert_eq!(gas_cost, U256::ZERO); - - // If the scalars are empty, the bedrock cost function should be used. - l1_block_info.empty_scalars = true; - let input = bytes!("FACADE"); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::ECOTONE.into()); - assert_eq!(gas_cost, U256::from(1048)); - } - - #[test] - fn calculate_tx_l1_cost_ecotone() { - // rig - - // l1 block info for OP mainnet ecotone block 118024092 - // 1710374401 (ecotone timestamp) - // 1711603765 (block 118024092 timestamp) - // 1720627201 (fjord timestamp) - // - // decoded from - let l1_block_info = L1BlockInfo { - l1_base_fee: U256::from_be_bytes(hex!( - "0000000000000000000000000000000000000000000000000000000af39ac327" - )), // 47036678951 - l1_base_fee_scalar: U256::from(1368), - l1_blob_base_fee: Some(U256::from_be_bytes(hex!( - "0000000000000000000000000000000000000000000000000000000d5ea528d2" - ))), // 57422457042 - l1_blob_base_fee_scalar: Some(U256::from(810949)), - ..Default::default() - }; - - // second tx in OP mainnet ecotone block 118024092 - // - const TX: &[u8] = &hex!("02f8b30a832253fc8402d11f39842c8a46398301388094dc6ff44d5d932cbd77b52e5612ba0529dc6226f180b844a9059cbb000000000000000000000000d43e02db81f4d46cdf8521f623d21ea0ec7562a50000000000000000000000000000000000000000000000008ac7230489e80000c001a02947e24750723b48f886931562c55d9e07f856d8e06468e719755e18bbc3a570a0784da9ce59fd7754ea5be6e17a86b348e441348cd48ace59d174772465eadbd1"); - - // l1 gas used for tx and l1 fee for tx, from OP mainnet block scanner - // - let expected_l1_gas_used = U256::from(2456); - let expected_l1_fee = U256::from_be_bytes(hex!( - "000000000000000000000000000000000000000000000000000006a510bd7431" // 7306020222001 wei - )); - - // test - - let gas_used = l1_block_info.data_gas(TX, OpSpecId::ECOTONE.into()); - - assert_eq!(gas_used, expected_l1_gas_used); - - let l1_fee = l1_block_info.calculate_tx_l1_cost_ecotone(TX, OpSpecId::ECOTONE.into()); - - assert_eq!(l1_fee, expected_l1_fee) - } - - #[test] - fn test_calculate_tx_l1_cost_fjord() { - // l1FeeScaled = baseFeeScalar*l1BaseFee*16 + blobFeeScalar*l1BlobBaseFee - // = 1000 * 1000 * 16 + 1000 * 1000 - // = 17e6 - let l1_block_info = L1BlockInfo { - l1_base_fee: U256::from(1_000), - l1_base_fee_scalar: U256::from(1_000), - l1_blob_base_fee: Some(U256::from(1_000)), - l1_blob_base_fee_scalar: Some(U256::from(1_000)), - ..Default::default() - }; - - // fastLzSize = 4 - // estimatedSize = max(minTransactionSize, intercept + fastlzCoef*fastlzSize) - // = max(100e6, 836500*4 - 42585600) - // = 100e6 - let input = bytes!("FACADE"); - // l1Cost = estimatedSize * l1FeeScaled / 1e12 - // = 100e6 * 17 / 1e6 - // = 1700 - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::FJORD.into()); - assert_eq!(gas_cost, U256::from(1700)); - - // fastLzSize = 202 - // estimatedSize = max(minTransactionSize, intercept + fastlzCoef*fastlzSize) - // = max(100e6, 836500*202 - 42585600) - // = 126387400 - let input = bytes!("02f901550a758302df1483be21b88304743f94f80e51afb613d764fa61751affd3313c190a86bb870151bd62fd12adb8e41ef24f3f000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831000000000000000000000000000000000000000000000000000000000003c1e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000148c89ed219d02f1a5be012c689b4f5b731827bebe000000000000000000000000c001a033fd89cb37c31b2cba46b6466e040c61fc9b2a3675a7f5f493ebd5ad77c497f8a07cdf65680e238392693019b4092f610222e71b7cec06449cb922b93b6a12744e"); - // l1Cost = estimatedSize * l1FeeScaled / 1e12 - // = 126387400 * 17 / 1e6 - // = 2148 - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::FJORD.into()); - assert_eq!(gas_cost, U256::from(2148)); - - // Zero rollup data gas cost should result in zero - let input = bytes!(""); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::FJORD.into()); - assert_eq!(gas_cost, U256::ZERO); - - // Deposit transactions with the EIP-2718 type of 0x7F should result in zero - let input = bytes!("7FFACADE"); - let gas_cost = l1_block_info.calculate_tx_l1_cost(&input, OpSpecId::FJORD.into()); - assert_eq!(gas_cost, U256::ZERO); - } - - #[test] - fn calculate_tx_l1_cost_fjord() { - // rig - - // L1 block info for OP mainnet fjord block 124665056 - // - let l1_block_info = L1BlockInfo { - l1_base_fee: U256::from(1055991687), - l1_base_fee_scalar: U256::from(5227), - l1_blob_base_fee_scalar: Some(U256::from(1014213)), - l1_blob_base_fee: Some(U256::from(1)), - ..Default::default() // L1 fee overhead (l1 gas used) deprecated since Fjord - }; - - // Second tx in OP mainnet Fjord block 124665056 - // - const TX: &[u8] = &hex!("02f904940a8303fba78401d6d2798401db2b6d830493e0943e6f4f7866654c18f536170780344aa8772950b680b904246a761202000000000000000000000000087000a300de7200382b55d40045000000e5d60e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a0000000000000000000000000000000000000000000000000000000000000022482ad56cb0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000120000000000000000000000000dc6ff44d5d932cbd77b52e5612ba0529dc6226f1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044095ea7b300000000000000000000000021c4928109acb0659a88ae5329b5374a3024694c0000000000000000000000000000000000000000000000049b9ca9a6943400000000000000000000000000000000000000000000000000000000000000000000000000000000000021c4928109acb0659a88ae5329b5374a3024694c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024b6b55f250000000000000000000000000000000000000000000000049b9ca9a694340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000415ec214a3950bea839a7e6fbb0ba1540ac2076acd50820e2d5ef83d0902cdffb24a47aff7de5190290769c4f0a9c6fabf63012986a0d590b1b571547a8c7050ea1b00000000000000000000000000000000000000000000000000000000000000c080a06db770e6e25a617fe9652f0958bd9bd6e49281a53036906386ed39ec48eadf63a07f47cf51a4a40b4494cf26efc686709a9b03939e20ee27e59682f5faa536667e"); - - // L1 gas used for tx and L1 fee for tx, from OP mainnet block scanner - // https://optimistic.etherscan.io/tx/0x1059e8004daff32caa1f1b1ef97fe3a07a8cf40508f5b835b66d9420d87c4a4a - let expected_data_gas = U256::from(4471); - let expected_l1_fee = U256::from_be_bytes(hex!( - "00000000000000000000000000000000000000000000000000000005bf1ab43d" - )); - - // test - - let data_gas = l1_block_info.data_gas(TX, OpSpecId::FJORD.into()); - - assert_eq!(data_gas, expected_data_gas); - - let l1_fee = l1_block_info.calculate_tx_l1_cost_fjord(TX); - - assert_eq!(l1_fee, expected_l1_fee) + }) + } else { + let l1_blob_base_fee = db.storage(L1_BLOCK_CONTRACT, ECOTONE_L1_BLOB_BASE_FEE_SLOT)?; + let l1_fee_scalars = db + .storage(L1_BLOCK_CONTRACT, ECOTONE_L1_FEE_SCALARS_SLOT)? + .to_be_bytes::<32>(); + + let l1_base_fee_scalar = U256::from_be_slice( + l1_fee_scalars[BASE_FEE_SCALAR_OFFSET..BASE_FEE_SCALAR_OFFSET + 4].as_ref(), + ); + let l1_blob_base_fee_scalar = U256::from_be_slice( + l1_fee_scalars[BLOB_BASE_FEE_SCALAR_OFFSET..BLOB_BASE_FEE_SCALAR_OFFSET + 4] + .as_ref(), + ); + + // Check if the L1 fee scalars are empty. If so, we use the Bedrock cost function. + // The L1 fee overhead is only necessary if `empty_scalars` is true, as it was deprecated in Ecotone. + let empty_scalars = l1_blob_base_fee.is_zero() + && l1_fee_scalars[BASE_FEE_SCALAR_OFFSET..BLOB_BASE_FEE_SCALAR_OFFSET + 4] + == EMPTY_SCALARS; + let l1_fee_overhead = empty_scalars + .then(|| db.storage(L1_BLOCK_CONTRACT, L1_OVERHEAD_SLOT)) + .transpose()?; + + Ok(L1BlockInfoTx { + l1_base_fee, + l1_base_fee_scalar, + l1_blob_base_fee: Some(l1_blob_base_fee), + l1_blob_base_fee_scalar: Some(l1_blob_base_fee_scalar), + empty_scalars, + l1_fee_overhead, + }) } } diff --git a/crates/optimism/src/lib.rs b/crates/optimism/src/lib.rs index ada77d4fa7..d9e21d8682 100644 --- a/crates/optimism/src/lib.rs +++ b/crates/optimism/src/lib.rs @@ -7,16 +7,15 @@ extern crate alloc as std; pub mod bn128; pub mod evm; +pub mod l1block; pub mod fast_lz; pub mod handler; -pub mod l1block; pub mod result; pub mod spec; pub mod transaction; -pub use l1block::{ - L1BlockInfo, L1BlockInfoGetter, BASE_FEE_RECIPIENT, L1_BLOCK_CONTRACT, L1_FEE_RECIPIENT, -}; +pub use l1block::{L1_FEE_RECIPIENT, BASE_FEE_RECIPIENT}; +pub use evm::L1BlockInfoGetter; pub use result::OptimismHaltReason; pub use spec::*; pub use transaction::{error::OpTransactionError, OpTransaction};