From e7599cf2e7f5033ee67f2dd087699b87de254760 Mon Sep 17 00:00:00 2001 From: Jingping Yin Date: Mon, 22 Dec 2025 11:25:32 +0800 Subject: [PATCH] feat: goat osaka hardfork --- Cargo.lock | 1424 ++++++----------- Cargo.toml | 105 +- README.md | 2 +- bin/eth-proofs/src/main.rs | 2 +- bin/guest/Cargo.lock | 808 ++++------ bin/guest/Cargo.toml | 2 +- bin/host/Cargo.toml | 3 + bin/host/input/48816/9831027.bin | Bin 0 -> 152615 bytes crates/executor/guest/Cargo.toml | 2 + crates/executor/guest/src/custom.rs | 198 ++- crates/executor/guest/src/executor.rs | 86 +- crates/executor/guest/src/into_primitives.rs | 148 +- crates/executor/guest/src/io.rs | 45 +- crates/executor/guest/src/lib.rs | 2 +- .../guest/src/tracking/block_executor.rs | 6 +- crates/executor/guest/src/utils.rs | 3 +- crates/executor/host/Cargo.toml | 6 +- .../host/src/bins/persist_report_hook.rs | 8 +- crates/executor/host/src/error.rs | 4 + .../executor/host/src/executor_components.rs | 31 +- crates/executor/host/src/full_executor.rs | 28 +- crates/executor/host/src/host_executor.rs | 237 +-- crates/executor/host/src/lib.rs | 9 +- crates/executor/host/tests/integration.rs | 21 +- crates/mpt/Cargo.toml | 8 +- crates/mpt/src/execution_witness.rs | 106 ++ crates/mpt/src/lib.rs | 77 +- crates/mpt/src/mpt.rs | 163 +- crates/primitives/Cargo.toml | 1 + crates/primitives/src/genesis.rs | 20 +- crates/primitives/src/genesis/2345.json | 1 + crates/primitives/src/genesis/48816.json | 1 + crates/storage/rpc-db/Cargo.toml | 21 +- crates/storage/rpc-db/src/basic.rs | 311 ++++ crates/storage/rpc-db/src/error.rs | 26 + .../storage/rpc-db/src/execution_witness.rs | 139 ++ crates/storage/rpc-db/src/lib.rs | 362 +---- crates/storage/witness-db/Cargo.toml | 2 +- 38 files changed, 2162 insertions(+), 2256 deletions(-) create mode 100644 bin/host/input/48816/9831027.bin create mode 100644 crates/mpt/src/execution_witness.rs create mode 100644 crates/storage/rpc-db/src/basic.rs create mode 100644 crates/storage/rpc-db/src/error.rs create mode 100644 crates/storage/rpc-db/src/execution_witness.rs diff --git a/Cargo.lock b/Cargo.lock index ec7b008..5d15e29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,57 +78,31 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35d744058a9daa51a8cf22a3009607498fcf82d3cf4c5444dd8056cdf651f471" +checksum = "b163ff4acf0eac29af05a911397cc418a76e153467b859398adc26cb9335a611" dependencies = [ "alloy-primitives", "alloy-rlp", - "num_enum 0.7.5", + "num_enum", "serde", "strum 0.27.2", ] [[package]] name = "alloy-consensus" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-eips 0.14.0", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.14.0", - "alloy-trie 0.8.1", - "auto_impl", - "bytes", - "c-kzg", - "derive_more 2.1.0", - "either", - "k256", - "once_cell", - "rand 0.8.5", - "serde", - "serde_json", - "serde_with", - "thiserror 2.0.17", -] - -[[package]] -name = "alloy-consensus" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e318e25fb719e747a7e8db1654170fc185024f3ed5b10f86c08d448a912f6e2" -dependencies = [ - "alloy-eips 1.1.3", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 1.1.3", - "alloy-trie 0.9.1", + "alloy-serde", + "alloy-trie 0.9.2", "alloy-tx-macros", "auto_impl", - "borsh", "c-kzg", - "derive_more 2.1.0", + "derive_more 2.1.1", "either", "k256", "once_cell", @@ -142,28 +116,14 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" -dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.14.0", - "serde", -] - -[[package]] -name = "alloy-consensus-any" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "364380a845193a317bcb7a5398fc86cdb66c47ebe010771dde05f6869bf9e64a" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-consensus 1.1.3", - "alloy-eips 1.1.3", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.1.3", + "alloy-serde", "serde", ] @@ -209,39 +169,18 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-eip2124", "alloy-eip2930", "alloy-eip7702", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.14.0", + "alloy-serde", "auto_impl", "c-kzg", - "derive_more 2.1.0", - "either", - "serde", - "sha2", -] - -[[package]] -name = "alloy-eips" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c4d7c5839d9f3a467900c625416b24328450c65702eb3d8caff8813e4d1d33" -dependencies = [ - "alloy-eip2124", - "alloy-eip2930", - "alloy-eip7702", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 1.1.3", - "auto_impl", - "borsh", - "c-kzg", - "derive_more 2.1.0", + "derive_more 2.1.1", "either", "serde", "serde_with", @@ -251,17 +190,18 @@ dependencies = [ [[package]] name = "alloy-evm" -version = "0.4.0" -source = "git+https://github.com/ziren-patches/evm?branch=patch-0.4.0#57b583d7a27668c1b4fb1f2a655675e1be6b497e" +version = "0.23.0" +source = "git+https://github.com/ziren-patches/evm?branch=patch-0.23.0#bf2c1b5816835b4a581b509598555d7dd01df17d" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-hardforks", + "alloy-op-hardforks", "alloy-primitives", "alloy-sol-types", "anyhow", "auto_impl", - "derive_more 2.1.0", + "derive_more 2.1.1", "op-alloy-consensus", "op-revm", "revm", @@ -270,21 +210,22 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-eips 0.14.0", + "alloy-eips", "alloy-primitives", - "alloy-serde 0.14.0", - "alloy-trie 0.8.1", + "alloy-serde", + "alloy-trie 0.9.2", "serde", + "serde_with", ] [[package]] name = "alloy-hardforks" -version = "0.2.13" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165210652f71dfc094b051602bafd691f506c54050a174b1cba18fb5ef706a3" +checksum = "2d9a33550fc21fd77a3f8b63e99969d17660eec8dcc50a95a80f7c9964f7680b" dependencies = [ "alloy-chains", "alloy-eip2124", @@ -307,22 +248,8 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" -dependencies = [ - "alloy-primitives", - "alloy-sol-types", - "serde", - "serde_json", - "thiserror 2.0.17", - "tracing", -] - -[[package]] -name = "alloy-json-rpc" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f72cf87cda808e593381fb9f005ffa4d2475552b7a6c5ac33d087bf77d82abd0" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "alloy-sol-types", @@ -335,49 +262,23 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" -dependencies = [ - "alloy-consensus 0.14.0", - "alloy-consensus-any 0.14.0", - "alloy-eips 0.14.0", - "alloy-json-rpc 0.14.0", - "alloy-network-primitives 0.14.0", - "alloy-primitives", - "alloy-rpc-types-any 0.14.0", - "alloy-rpc-types-eth 0.14.0", - "alloy-serde 0.14.0", - "alloy-signer 0.14.0", - "alloy-sol-types", - "async-trait", - "auto_impl", - "derive_more 2.1.0", - "futures-utils-wasm", - "serde", - "serde_json", - "thiserror 2.0.17", -] - -[[package]] -name = "alloy-network" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12aeb37b6f2e61b93b1c3d34d01ee720207c76fe447e2a2c217e433ac75b17f5" -dependencies = [ - "alloy-consensus 1.1.3", - "alloy-consensus-any 1.1.3", - "alloy-eips 1.1.3", - "alloy-json-rpc 1.1.3", - "alloy-network-primitives 1.1.3", +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", "alloy-primitives", - "alloy-rpc-types-any 1.1.3", - "alloy-rpc-types-eth 1.1.3", - "alloy-serde 1.1.3", - "alloy-signer 1.1.3", + "alloy-rpc-types-any", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer 1.0.41", "alloy-sol-types", "async-trait", "auto_impl", - "derive_more 2.1.0", + "derive_more 2.1.1", "futures-utils-wasm", "serde", "serde_json", @@ -386,36 +287,23 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" -dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", - "alloy-primitives", - "alloy-serde 0.14.0", - "serde", -] - -[[package]] -name = "alloy-network-primitives" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd29ace62872083e30929cd9b282d82723196d196db589f3ceda67edcc05552" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-consensus 1.1.3", - "alloy-eips 1.1.3", + "alloy-consensus", + "alloy-eips", "alloy-primitives", - "alloy-serde 1.1.3", + "alloy-serde", "serde", ] [[package]] name = "alloy-op-evm" -version = "0.4.0" -source = "git+https://github.com/ziren-patches/evm?branch=patch-0.4.0#57b583d7a27668c1b4fb1f2a655675e1be6b497e" +version = "0.23.0" +source = "git+https://github.com/ziren-patches/evm?branch=patch-0.23.0#bf2c1b5816835b4a581b509598555d7dd01df17d" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", "alloy-op-hardforks", "alloy-primitives", @@ -423,30 +311,31 @@ dependencies = [ "op-alloy-consensus", "op-revm", "revm", + "thiserror 2.0.17", ] [[package]] name = "alloy-op-hardforks" -version = "0.2.13" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3417f4187eaf7f7fb0d7556f0197bca26f0b23c4bb3aca0c9d566dc1c5d727a2" +checksum = "f96fb2fce4024ada5b2c11d4076acf778a0d3e4f011c6dfd2ffce6d0fcf84ee9" dependencies = [ "alloy-chains", "alloy-hardforks", + "alloy-primitives", "auto_impl", ] [[package]] name = "alloy-primitives" version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28" +source = "git+https://github.com/ziren-patches/core.git?branch=patch-alloy-primitives-1.4.1#59313700f710f1373a5b4cdc05c51dc3227d8064" dependencies = [ "alloy-rlp", "bytes", "cfg-if", "const-hex", - "derive_more 2.1.0", + "derive_more 2.1.1", "foldhash 0.2.0", "hashbrown 0.16.1", "indexmap 2.12.1", @@ -461,24 +350,27 @@ dependencies = [ "serde", "sha3", "tiny-keccak", + "zkm-zkvm", ] [[package]] name = "alloy-provider" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-chains", - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", - "alloy-json-rpc 0.14.0", - "alloy-network 0.14.0", - "alloy-network-primitives 0.14.0", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network", + "alloy-network-primitives", "alloy-primitives", "alloy-pubsub", "alloy-rpc-client", - "alloy-rpc-types-eth 0.14.0", - "alloy-signer 0.14.0", + "alloy-rpc-types-debug", + "alloy-rpc-types-eth", + "alloy-rpc-types-trace", + "alloy-signer 1.0.41", "alloy-sol-types", "alloy-transport", "alloy-transport-http", @@ -493,7 +385,7 @@ dependencies = [ "lru 0.13.0", "parking_lot 0.12.5", "pin-project", - "reqwest 0.12.25", + "reqwest 0.12.28", "serde", "serde_json", "thiserror 2.0.17", @@ -505,12 +397,13 @@ dependencies = [ [[package]] name = "alloy-pubsub" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-json-rpc 0.14.0", + "alloy-json-rpc", "alloy-primitives", "alloy-transport", + "auto_impl", "bimap", "futures", "parking_lot 0.12.5", @@ -547,107 +440,85 @@ dependencies = [ [[package]] name = "alloy-rpc-client" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-json-rpc 0.14.0", + "alloy-json-rpc", "alloy-primitives", "alloy-pubsub", "alloy-transport", "alloy-transport-http", "alloy-transport-ws", - "async-stream", "futures", "pin-project", - "reqwest 0.12.25", + "reqwest 0.12.28", "serde", "serde_json", "tokio", "tokio-stream", "tower 0.5.2", "tracing", - "tracing-futures", "url", "wasmtimer", ] [[package]] name = "alloy-rpc-types" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", - "alloy-rpc-types-eth 0.14.0", - "alloy-serde 0.14.0", + "alloy-rpc-types-eth", + "alloy-serde", "serde", ] [[package]] name = "alloy-rpc-types-any" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-consensus-any 0.14.0", - "alloy-rpc-types-eth 0.14.0", - "alloy-serde 0.14.0", + "alloy-consensus-any", + "alloy-rpc-types-eth", + "alloy-serde", ] [[package]] -name = "alloy-rpc-types-any" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a63fb40ed24e4c92505f488f9dd256e2afaed17faa1b7a221086ebba74f4122" +name = "alloy-rpc-types-debug" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-consensus-any 1.1.3", - "alloy-rpc-types-eth 1.1.3", - "alloy-serde 1.1.3", + "alloy-primitives", + "derive_more 2.1.1", + "serde", + "serde_with", ] [[package]] name = "alloy-rpc-types-engine" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "derive_more 2.1.0", + "derive_more 2.1.1", "strum 0.27.2", ] [[package]] name = "alloy-rpc-types-eth" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" -dependencies = [ - "alloy-consensus 0.14.0", - "alloy-consensus-any 0.14.0", - "alloy-eips 0.14.0", - "alloy-network-primitives 0.14.0", - "alloy-primitives", - "alloy-rlp", - "alloy-serde 0.14.0", - "alloy-sol-types", - "itertools 0.14.0", - "serde", - "serde_json", - "thiserror 2.0.17", -] - -[[package]] -name = "alloy-rpc-types-eth" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eae0c7c40da20684548cbc8577b6b7447f7bf4ddbac363df95e3da220e41e72" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-consensus 1.1.3", - "alloy-consensus-any 1.1.3", - "alloy-eips 1.1.3", - "alloy-network-primitives 1.1.3", + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-network-primitives", "alloy-primitives", "alloy-rlp", - "alloy-serde 1.1.3", + "alloy-serde", "alloy-sol-types", "itertools 0.14.0", "serde", @@ -657,20 +528,22 @@ dependencies = [ ] [[package]] -name = "alloy-serde" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +name = "alloy-rpc-types-trace" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", "serde", "serde_json", + "thiserror 2.0.17", ] [[package]] name = "alloy-serde" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0df1987ed0ff2d0159d76b52e7ddfc4e4fbddacc54d2fbee765e0d14d7c01b5" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "serde", @@ -679,8 +552,8 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "async-trait", @@ -693,9 +566,9 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "1.1.3" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff69deedee7232d7ce5330259025b868c5e6a52fa8dffda2c861fb3a5889b24" +checksum = "acff6b251740ef473932386d3b71657d3825daebf2217fb41a7ef676229225d4" dependencies = [ "alloy-primitives", "async-trait", @@ -706,27 +579,11 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "alloy-signer-local" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72cfe0be3ec5a8c1a46b2e5a7047ed41121d360d97f4405bb7c1c784880c86cb" -dependencies = [ - "alloy-consensus 1.1.3", - "alloy-network 1.1.3", - "alloy-primitives", - "alloy-signer 1.1.3", - "async-trait", - "k256", - "rand 0.8.5", - "thiserror 2.0.17", -] - [[package]] name = "alloy-sol-macro" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312" +checksum = "09eb18ce0df92b4277291bbaa0ed70545d78b02948df756bbd3d6214bf39a218" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -738,9 +595,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028" +checksum = "95d9fa2daf21f59aa546d549943f10b5cce1ae59986774019fbedae834ffe01b" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -756,9 +613,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c" +checksum = "9396007fe69c26ee118a19f4dee1f5d1d6be186ea75b3881adf16d87f8444686" dependencies = [ "const-hex", "dunce", @@ -772,12 +629,12 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9" +checksum = "af67a0b0dcebe14244fc92002cd8d96ecbf65db4639d479f5fcd5805755a4c27" dependencies = [ "serde", - "winnow 0.7.14", + "winnow", ] [[package]] @@ -794,12 +651,14 @@ dependencies = [ [[package]] name = "alloy-transport" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-json-rpc 0.14.0", + "alloy-json-rpc", + "alloy-primitives", + "auto_impl", "base64 0.22.1", - "derive_more 2.1.0", + "derive_more 2.1.1", "futures", "futures-utils-wasm", "parking_lot 0.12.5", @@ -815,12 +674,12 @@ dependencies = [ [[package]] name = "alloy-transport-http" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "alloy-json-rpc 0.14.0", + "alloy-json-rpc", "alloy-transport", - "reqwest 0.12.25", + "reqwest 0.12.28", "serde_json", "tower 0.5.2", "tracing", @@ -829,8 +688,8 @@ dependencies = [ [[package]] name = "alloy-transport-ws" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -853,7 +712,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more 2.1.0", + "derive_more 2.1.1", "nybbles 0.3.4", "serde", "smallvec", @@ -862,14 +721,14 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" +checksum = "2b77b56af09ead281337d06b1d036c88e2dc8a2e45da512a532476dbee94912b" dependencies = [ "alloy-primitives", "alloy-rlp", "arrayvec", - "derive_more 2.1.0", + "derive_more 2.1.1", "nybbles 0.4.6", "serde", "smallvec", @@ -878,10 +737,10 @@ dependencies = [ [[package]] name = "alloy-tx-macros" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "333544408503f42d7d3792bfc0f7218b643d968a03d2c0ed383ae558fb4a76d0" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ + "alloy-primitives", "darling", "proc-macro2", "quote", @@ -1678,7 +1537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ "once_cell", - "proc-macro-crate 3.4.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.111", @@ -1696,9 +1555,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "byte-slice-cast" @@ -1793,9 +1652,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ "serde_core", ] @@ -1823,30 +1682,11 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "cbindgen" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fce8dd7fcfcbf3a0a87d8f515194b49d6135acab73e18bd380d1d93bb1a15eb" -dependencies = [ - "clap", - "heck 0.4.1", - "indexmap 2.12.1", - "log", - "proc-macro2", - "quote", - "serde", - "serde_json", - "syn 2.0.111", - "tempfile", - "toml", -] - [[package]] name = "cc" -version = "1.2.49" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "jobserver", @@ -1882,10 +1722,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-link", ] @@ -2080,15 +1918,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" -[[package]] -name = "convert_case" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "convert_case" version = "0.10.0" @@ -2153,15 +1982,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -2470,11 +2290,11 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ - "derive_more-impl 2.1.0", + "derive_more-impl 2.1.1", ] [[package]] @@ -2490,11 +2310,11 @@ dependencies = [ [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ - "convert_case 0.10.0", + "convert_case", "proc-macro2", "quote", "rustc_version 0.4.1", @@ -2606,12 +2426,6 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - [[package]] name = "dunce" version = "1.0.5" @@ -2782,40 +2596,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "enumn" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - -[[package]] -name = "env_filter" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" -dependencies = [ - "log", - "regex", -] - -[[package]] -name = "env_logger" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" -dependencies = [ - "anstream", - "anstyle", - "env_filter", - "jiff", - "log", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -2872,7 +2652,7 @@ dependencies = [ "host-executor", "primitives", "provider", - "reqwest 0.12.25", + "reqwest 0.12.28", "reqwest-middleware", "reqwest-retry", "serde", @@ -3036,7 +2816,7 @@ dependencies = [ "ethabi", "generic-array 0.14.7", "k256", - "num_enum 0.7.5", + "num_enum", "once_cell", "open-fastrlp", "rand 0.8.5", @@ -3606,19 +3386,21 @@ dependencies = [ name = "guest-executor" version = "0.1.0" dependencies = [ - "alloy-consensus 0.14.0", + "alloy-consensus", "alloy-evm", - "alloy-network 0.14.0", + "alloy-network", "alloy-primitives", "alloy-rpc-types", "bincode", "itertools 0.13.0", + "kzg-rs", "mpt", "op-alloy-network", "op-alloy-rpc-types", "primitives", "reth-chainspec", "reth-consensus", + "reth-consensus-common", "reth-errors", "reth-ethereum-consensus", "reth-ethereum-primitives", @@ -3911,8 +3693,8 @@ name = "host" version = "0.1.0" dependencies = [ "alloy-chains", - "alloy-consensus 0.14.0", - "alloy-network 0.14.0", + "alloy-consensus", + "alloy-network", "alloy-primitives", "alloy-provider", "clap", @@ -3940,10 +3722,10 @@ name = "host-executor" version = "0.1.0" dependencies = [ "alloy-chains", - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", - "alloy-network 0.14.0", + "alloy-network", "alloy-primitives", "alloy-provider", "alloy-rpc-types", @@ -3960,7 +3742,7 @@ dependencies = [ "mpt", "op-alloy-network", "primitives", - "reqwest 0.12.25", + "reqwest 0.12.28", "reth-chainspec", "reth-errors", "reth-ethereum-primitives", @@ -4261,9 +4043,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -4275,9 +4057,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -4494,33 +4276,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jiff" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" -dependencies = [ - "jiff-static", - "log", - "portable-atomic", - "portable-atomic-util", - "serde_core", -] - -[[package]] -name = "jiff-static" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" [[package]] name = "jobserver" @@ -4693,9 +4451,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" +checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50" dependencies = [ "bitflags 2.10.0", "libc", @@ -4855,28 +4613,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d97bbf43eb4f088f8ca469930cde17fa036207c9a5e02ccc5107c4e8b17c964" -[[package]] -name = "metrics" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8" -dependencies = [ - "ahash", - "portable-atomic", -] - -[[package]] -name = "metrics-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3dbdd96ed57d565ec744cba02862d707acf373c5772d152abae6ec5c4e24f6c" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 2.0.111", -] - [[package]] name = "mime" version = "0.3.17" @@ -4937,6 +4673,8 @@ version = "0.1.0" dependencies = [ "alloy-primitives", "alloy-rlp", + "alloy-rpc-types", + "alloy-rpc-types-debug", "hex-literal", "mpt", "reth-trie", @@ -5010,9 +4748,9 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" dependencies = [ "winapi", ] @@ -5143,44 +4881,23 @@ dependencies = [ "libc", ] -[[package]] -name = "num_enum" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" -dependencies = [ - "num_enum_derive 0.5.11", -] - [[package]] name = "num_enum" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ - "num_enum_derive 0.7.5", + "num_enum_derive", "rustversion", ] -[[package]] -name = "num_enum_derive" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "num_enum_derive" version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ - "proc-macro-crate 3.4.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.111", @@ -5282,15 +4999,17 @@ checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "op-alloy-consensus" -version = "0.13.0" -source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.13.0#d0ee5a615eccbb23c3d610a297508bf26d2b6629" +version = "0.22.0" +source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.22.0#20048eaa105b1c06ca4fca6108a047a2fda0c494" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", + "alloy-network", "alloy-primitives", "alloy-rlp", - "alloy-serde 0.14.0", - "derive_more 2.1.0", + "alloy-rpc-types-eth", + "alloy-serde", + "derive_more 2.1.1", "serde", "serde_with", "thiserror 2.0.17", @@ -5298,44 +5017,59 @@ dependencies = [ [[package]] name = "op-alloy-network" -version = "0.13.0" -source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.13.0#d0ee5a615eccbb23c3d610a297508bf26d2b6629" +version = "0.22.0" +source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.22.0#20048eaa105b1c06ca4fca6108a047a2fda0c494" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-network 0.14.0", + "alloy-consensus", + "alloy-network", "alloy-primitives", - "alloy-rpc-types-eth 0.14.0", - "alloy-signer 0.14.0", + "alloy-provider", + "alloy-rpc-types-eth", + "alloy-signer 1.0.41", "op-alloy-consensus", "op-alloy-rpc-types", ] [[package]] name = "op-alloy-rpc-types" -version = "0.13.0" -source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.13.0#d0ee5a615eccbb23c3d610a297508bf26d2b6629" +version = "0.22.0" +source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.22.0#20048eaa105b1c06ca4fca6108a047a2fda0c494" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", - "alloy-network-primitives 0.14.0", + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", "alloy-primitives", - "alloy-rpc-types-eth 0.14.0", - "alloy-serde 0.14.0", - "derive_more 2.1.0", + "alloy-rpc-types-eth", + "alloy-serde", + "derive_more 2.1.1", "op-alloy-consensus", "serde", "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "op-alloy-rpc-types-engine" +version = "0.22.0" +source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.22.0#20048eaa105b1c06ca4fca6108a047a2fda0c494" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-rpc-types-engine", + "derive_more 2.1.1", + "op-alloy-consensus", + "thiserror 2.0.17", ] [[package]] name = "op-revm" -version = "3.0.1" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", - "once_cell", "revm", - "serde", ] [[package]] @@ -5779,7 +5513,7 @@ version = "3.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" dependencies = [ - "proc-macro-crate 3.4.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.111", @@ -5883,16 +5617,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "path-slash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" - -[[package]] -name = "pathdiff" -version = "0.2.3" +name = "path-slash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" [[package]] name = "pbkdf2" @@ -5986,8 +5714,18 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ - "phf_macros", - "phf_shared", + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros 0.13.1", + "phf_shared 0.13.1", "serde", ] @@ -5997,18 +5735,41 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ - "phf_shared", + "phf_shared 0.11.3", "rand 0.8.5", ] +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared 0.13.1", +] + [[package]] name = "phf_macros" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" dependencies = [ - "phf_generator", - "phf_shared", + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", "proc-macro2", "quote", "syn 2.0.111", @@ -6023,6 +5784,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -6073,18 +5843,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "portable-atomic-util" -version = "0.2.4" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" -dependencies = [ - "portable-atomic", -] +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" [[package]] name = "potential_utf" @@ -6162,6 +5923,7 @@ dependencies = [ name = "primitives" version = "0.1.0" dependencies = [ + "alloy-eips", "alloy-genesis", "alloy-rpc-types", "eyre", @@ -6174,23 +5936,13 @@ dependencies = [ "serde_json", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.15", -] - [[package]] name = "proc-macro-crate" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.23.9", + "toml_edit 0.23.10+spec-1.0.0", ] [[package]] @@ -6353,7 +6105,7 @@ dependencies = [ name = "provider" version = "0.1.0" dependencies = [ - "alloy-json-rpc 0.14.0", + "alloy-json-rpc", "alloy-provider", "alloy-rpc-client", "alloy-transport", @@ -6676,9 +6428,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.25" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", @@ -6727,7 +6479,7 @@ dependencies = [ "anyhow", "async-trait", "http 1.4.0", - "reqwest 0.12.25", + "reqwest 0.12.28", "serde", "thiserror 1.0.69", "tower-service", @@ -6746,7 +6498,7 @@ dependencies = [ "http 1.4.0", "hyper 1.8.1", "parking_lot 0.11.2", - "reqwest 0.12.25", + "reqwest 0.12.28", "reqwest-middleware", "retry-policies", "tokio", @@ -6762,18 +6514,18 @@ checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" [[package]] name = "reth-chainspec" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-chains", - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", "alloy-genesis", "alloy-primitives", - "alloy-trie 0.8.1", + "alloy-trie 0.9.2", "auto_impl", - "derive_more 2.1.0", + "derive_more 2.1.1", "reth-ethereum-forks", "reth-network-peers", "reth-primitives-traits", @@ -6782,14 +6534,14 @@ dependencies = [ [[package]] name = "reth-codecs" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-genesis", "alloy-primitives", - "alloy-trie 0.8.1", + "alloy-trie 0.9.2", "bytes", "modular-bitfield", "op-alloy-consensus", @@ -6800,10 +6552,9 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "convert_case 0.7.1", "proc-macro2", "quote", "syn 2.0.111", @@ -6811,10 +6562,10 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", + "alloy-consensus", "alloy-primitives", "auto_impl", "reth-execution-types", @@ -6824,11 +6575,11 @@ dependencies = [ [[package]] name = "reth-consensus-common" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "reth-chainspec", "reth-consensus", "reth-primitives-traits", @@ -6836,33 +6587,32 @@ dependencies = [ [[package]] name = "reth-db-models" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-eips 0.14.0", + "alloy-eips", "alloy-primitives", "reth-primitives-traits", ] [[package]] name = "reth-errors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "reth-consensus", "reth-execution-errors", - "reth-fs-util", "reth-storage-errors", "thiserror 2.0.17", ] [[package]] name = "reth-ethereum-consensus" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "reth-chainspec", "reth-consensus", @@ -6874,8 +6624,8 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-eip2124", "alloy-hardforks", @@ -6886,39 +6636,34 @@ dependencies = [ [[package]] name = "reth-ethereum-primitives" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", - "alloy-evm", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-rpc-types-eth 0.14.0", - "derive_more 2.1.0", - "rand 0.8.5", + "alloy-rpc-types-eth", + "alloy-serde", "reth-codecs", "reth-primitives-traits", - "revm-context", - "secp256k1", "serde", "serde_with", ] [[package]] name = "reth-evm" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", "alloy-primitives", "anyhow", "auto_impl", - "derive_more 2.1.0", + "derive_more 2.1.1", "futures-util", - "op-revm", "reth-execution-errors", "reth-execution-types", "reth-primitives-traits", @@ -6931,74 +6676,57 @@ dependencies = [ [[package]] name = "reth-evm-ethereum" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", "alloy-primitives", + "alloy-rpc-types-engine", "reth-chainspec", "reth-ethereum-forks", "reth-ethereum-primitives", "reth-evm", "reth-execution-types", "reth-primitives-traits", + "reth-storage-errors", "revm", ] [[package]] name = "reth-execution-errors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-evm", "alloy-primitives", "alloy-rlp", - "nybbles 0.3.4", + "nybbles 0.4.6", "reth-storage-errors", "thiserror 2.0.17", ] [[package]] name = "reth-execution-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", "alloy-primitives", - "derive_more 2.1.0", + "derive_more 2.1.1", "reth-ethereum-primitives", "reth-primitives-traits", "reth-trie-common", "revm", ] -[[package]] -name = "reth-fs-util" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" -dependencies = [ - "serde", - "serde_json", - "thiserror 2.0.17", -] - -[[package]] -name = "reth-metrics" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" -dependencies = [ - "metrics", - "metrics-derive", -] - [[package]] name = "reth-network-peers" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -7009,16 +6737,17 @@ dependencies = [ [[package]] name = "reth-optimism-chainspec" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-chains", - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-genesis", "alloy-hardforks", "alloy-primitives", - "derive_more 2.1.0", + "derive_more 2.1.1", + "op-alloy-consensus", "op-alloy-rpc-types", "reth-chainspec", "reth-ethereum-forks", @@ -7031,18 +6760,18 @@ dependencies = [ [[package]] name = "reth-optimism-consensus" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-primitives", - "alloy-trie 0.8.1", - "op-alloy-consensus", + "alloy-trie 0.9.2", "reth-chainspec", "reth-consensus", "reth-consensus-common", "reth-execution-types", + "reth-optimism-chainspec", "reth-optimism-forks", "reth-optimism-primitives", "reth-primitives-traits", @@ -7056,15 +6785,16 @@ dependencies = [ [[package]] name = "reth-optimism-evm" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-evm", "alloy-op-evm", "alloy-primitives", "op-alloy-consensus", + "op-alloy-rpc-types-engine", "op-revm", "reth-chainspec", "reth-evm", @@ -7075,14 +6805,15 @@ dependencies = [ "reth-optimism-forks", "reth-optimism-primitives", "reth-primitives-traits", + "reth-storage-errors", "revm", "thiserror 2.0.17", ] [[package]] name = "reth-optimism-forks" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-op-hardforks", "alloy-primitives", @@ -7092,43 +6823,36 @@ dependencies = [ [[package]] name = "reth-optimism-primitives" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", - "alloy-evm", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-rpc-types-eth 0.14.0", "bytes", - "derive_more 2.1.0", "op-alloy-consensus", - "op-revm", - "rand 0.8.5", "reth-codecs", "reth-primitives-traits", - "revm-context", - "secp256k1", "serde", "serde_with", ] [[package]] name = "reth-primitives-traits" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rlp", - "alloy-trie 0.8.1", + "alloy-rpc-types-eth", + "alloy-trie 0.9.2", "auto_impl", "bytes", - "derive_more 2.1.0", - "k256", + "derive_more 2.1.1", "once_cell", "op-alloy-consensus", "reth-codecs", @@ -7143,18 +6867,19 @@ dependencies = [ [[package]] name = "reth-prune-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", - "derive_more 2.1.0", + "derive_more 2.1.1", + "strum 0.27.2", "thiserror 2.0.17", ] [[package]] name = "reth-stages-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "reth-trie-common", @@ -7162,22 +6887,22 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", - "derive_more 2.1.0", + "derive_more 2.1.1", "serde", "strum 0.27.2", ] [[package]] name = "reth-storage-api" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "auto_impl", @@ -7195,13 +6920,13 @@ dependencies = [ [[package]] name = "reth-storage-errors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-eips 0.14.0", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "derive_more 2.1.0", + "derive_more 2.1.1", "reth-primitives-traits", "reth-prune-types", "reth-static-file-types", @@ -7209,31 +6934,16 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "reth-tracing" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" -dependencies = [ - "clap", - "eyre", - "rolling-file", - "tracing", - "tracing-appender", - "tracing-journald", - "tracing-logfmt", - "tracing-subscriber", -] - [[package]] name = "reth-trie" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", - "alloy-eips 0.14.0", + "alloy-consensus", + "alloy-eips", "alloy-primitives", "alloy-rlp", - "alloy-trie 0.8.1", + "alloy-trie 0.9.2", "auto_impl", "itertools 0.14.0", "reth-execution-errors", @@ -7248,16 +6958,16 @@ dependencies = [ [[package]] name = "reth-trie-common" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "alloy-consensus 0.14.0", + "alloy-consensus", "alloy-primitives", "alloy-rlp", - "alloy-trie 0.8.1", - "derive_more 2.1.0", + "alloy-trie 0.9.2", + "derive_more 2.1.1", "itertools 0.14.0", - "nybbles 0.3.4", + "nybbles 0.4.6", "rayon", "reth-primitives-traits", "revm-database", @@ -7265,25 +6975,24 @@ dependencies = [ [[package]] name = "reth-trie-sparse" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "alloy-rlp", + "alloy-trie 0.9.2", "auto_impl", - "metrics", "reth-execution-errors", - "reth-metrics", "reth-primitives-traits", - "reth-tracing", "reth-trie-common", "smallvec", + "tracing", ] [[package]] name = "reth-zstd-compressors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "zstd 0.13.3", ] @@ -7299,8 +7008,8 @@ dependencies = [ [[package]] name = "revm" -version = "22.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "31.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "revm-bytecode", "revm-context", @@ -7317,21 +7026,22 @@ dependencies = [ [[package]] name = "revm-bytecode" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "7.1.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "bitvec", - "phf", + "phf 0.13.1", "revm-primitives", "serde", ] [[package]] name = "revm-context" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "11.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ - "alloy-consensus 0.14.0", + "alloy-consensus", + "bitvec", "cfg-if", "derive-where", "revm-bytecode", @@ -7344,13 +7054,14 @@ dependencies = [ [[package]] name = "revm-context-interface" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ - "alloy-consensus 0.14.0", + "alloy-consensus", "alloy-eip2930", "alloy-eip7702", "auto_impl", + "either", "revm-database-interface", "revm-primitives", "revm-state", @@ -7359,10 +7070,10 @@ dependencies = [ [[package]] name = "revm-database" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "9.0.5" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ - "alloy-eips 0.14.0", + "alloy-eips", "revm-bytecode", "revm-database-interface", "revm-primitives", @@ -7372,10 +7083,11 @@ dependencies = [ [[package]] name = "revm-database-interface" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "8.0.5" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", + "either", "revm-primitives", "revm-state", "serde", @@ -7383,10 +7095,11 @@ dependencies = [ [[package]] name = "revm-handler" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", + "derive-where", "revm-bytecode", "revm-context", "revm-context-interface", @@ -7400,10 +7113,11 @@ dependencies = [ [[package]] name = "revm-inspector" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", + "either", "revm-context", "revm-database-interface", "revm-handler", @@ -7415,30 +7129,30 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "18.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "29.0.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "revm-bytecode", "revm-context-interface", "revm-primitives", + "revm-state", "serde", ] [[package]] name = "revm-precompile" -version = "19.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "29.0.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "ark-bls12-381", "ark-bn254", "ark-ec", "ark-ff 0.5.0", "ark-serialize 0.5.0", + "arrayref", "aurora-engine-modexp", "cfg-if", "k256", - "kzg-rs", - "once_cell", "p256", "revm-primitives", "ripemd", @@ -7448,18 +7162,19 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "18.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "21.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "alloy-primitives", - "enumn", + "num_enum", + "once_cell", "serde", ] [[package]] name = "revm-state" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "8.1.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "bitflags 2.10.0", "revm-bytecode", @@ -7536,45 +7251,29 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rolling-file" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8395b4f860856b740f20a296ea2cd4d823e81a2658cf05ef61be22916026a906" -dependencies = [ - "chrono", -] - [[package]] name = "rpc-db" version = "0.1.0" dependencies = [ + "alloy-consensus", "alloy-primitives", "alloy-provider", - "alloy-rpc-types", - "indexmap 2.12.1", + "alloy-rlp", + "alloy-transport", + "alloy-trie 0.8.1", + "async-trait", + "mpt", + "primitives", "reth-storage-errors", + "revm-database", "revm-database-interface", "revm-primitives", "revm-state", - "serde", - "serde_json", "thiserror 1.0.69", "tokio", "tracing", ] -[[package]] -name = "rrs-succinct" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3372685893a9f67d18e98e792d690017287fd17379a83d798d958e517d380fa9" -dependencies = [ - "downcast-rs", - "num_enum 0.5.11", - "paste", -] - [[package]] name = "ruint" version = "1.17.0" @@ -7666,9 +7365,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags 2.10.0", "errno", @@ -7738,9 +7437,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -7787,9 +7486,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" [[package]] name = "salsa20" @@ -7827,7 +7526,7 @@ version = "2.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6630024bf739e2179b91fb424b28898baf819414262c5d376677dbff1fe7ebf" dependencies = [ - "proc-macro-crate 3.4.0", + "proc-macro-crate", "proc-macro2", "quote", "syn 2.0.111", @@ -8058,15 +7757,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -8192,8 +7891,8 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" -source = "git+https://github.com/ziren-patches/RustCrypto-hashes?branch=patch-sha2-0.10.8#62d9223ba171ef6d5b637b275c4b982f56d0a949" +version = "0.10.9" +source = "git+https://github.com/ziren-patches/RustCrypto-hashes?branch=patch-sha2-0.10.9#dbfdbd088ac7b55e03c0b9eb192278efe35d67dc" dependencies = [ "cfg-if", "cpufeatures", @@ -8338,7 +8037,7 @@ dependencies = [ "itertools 0.11.0", "lalrpop", "lalrpop-util", - "phf", + "phf 0.11.3", "thiserror 1.0.69", "unicode-xid", ] @@ -8391,7 +8090,7 @@ checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", "parking_lot 0.12.5", - "phf_shared", + "phf_shared 0.11.3", "precomputed-hash", ] @@ -8516,9 +8215,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3" +checksum = "5f92d01b5de07eaf324f7fca61cc6bd3d82bbc1de5b6c963e6fe79e86f36580d" dependencies = [ "paste", "proc-macro2", @@ -8617,14 +8316,14 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom 0.3.4", "once_cell", - "rustix 1.1.2", + "rustix 1.1.3", "windows-sys 0.61.2", ] @@ -8928,24 +8627,13 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.12.1", - "toml_datetime 0.6.11", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.27" @@ -8957,28 +8645,28 @@ dependencies = [ "serde_spanned", "toml_datetime 0.6.11", "toml_write", - "winnow 0.7.14", + "winnow", ] [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap 2.12.1", - "toml_datetime 0.7.3", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", - "winnow 0.7.14", + "winnow", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ - "winnow 0.7.14", + "winnow", ] [[package]] @@ -9103,9 +8791,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -9113,18 +8801,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-appender" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" -dependencies = [ - "crossbeam-channel", - "thiserror 2.0.17", - "time", - "tracing-subscriber", -] - [[package]] name = "tracing-attributes" version = "0.1.31" @@ -9138,9 +8814,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -9165,23 +8841,10 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "futures", - "futures-task", "pin-project", "tracing", ] -[[package]] -name = "tracing-journald" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3a81ed245bfb62592b1e2bc153e77656d94ee6a0497683a65a12ccaf2438d0" -dependencies = [ - "libc", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "tracing-log" version = "0.2.0" @@ -9193,28 +8856,6 @@ dependencies = [ "tracing-core", ] -[[package]] -name = "tracing-logfmt" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1f47d22deb79c3f59fcf2a1f00f60cbdc05462bf17d1cd356c1fefa3f444bd" -dependencies = [ - "time", - "tracing", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-serde" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" -dependencies = [ - "serde", - "tracing-core", -] - [[package]] name = "tracing-subscriber" version = "0.3.22" @@ -9225,15 +8866,12 @@ dependencies = [ "nu-ansi-term", "once_cell", "regex-automata", - "serde", - "serde_json", "sharded-slab", "smallvec", "thread_local", "tracing", "tracing-core", "tracing-log", - "tracing-serde", ] [[package]] @@ -9313,7 +8951,7 @@ dependencies = [ "http-body-util", "hyper 1.8.1", "prost 0.13.5", - "reqwest 0.12.25", + "reqwest 0.12.28", "serde", "serde_json", "thiserror 1.0.69", @@ -10068,15 +9706,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.7.14" @@ -10330,26 +9959,24 @@ dependencies = [ [[package]] name = "zkm-build" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "anyhow", "cargo_metadata", "chrono", "clap", - "dirs", ] [[package]] name = "zkm-core-executor" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "anyhow", "bincode", "bytemuck", "elf", "enum-map", - "env_logger", "eyre", "hashbrown 0.14.5", "hex", @@ -10363,7 +9990,6 @@ dependencies = [ "p3-symmetric", "rand 0.8.5", "rayon-scan", - "rrs-succinct", "serde", "serde_json", "sha2", @@ -10372,7 +9998,6 @@ dependencies = [ "thiserror 1.0.69", "tiny-keccak", "tracing", - "tracing-subscriber", "typenum", "vec_map", "zkm-curves", @@ -10383,15 +10008,12 @@ dependencies = [ [[package]] name = "zkm-core-machine" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", - "cbindgen", - "cc", "cfg-if", "elliptic-curve", "generic-array 1.3.5", - "glob", "hashbrown 0.14.5", "hex", "itertools 0.13.0", @@ -10410,7 +10032,6 @@ dependencies = [ "p3-poseidon2", "p3-uni-stark", "p3-util", - "pathdiff", "rand 0.8.5", "rayon", "rayon-scan", @@ -10439,7 +10060,7 @@ dependencies = [ [[package]] name = "zkm-cuda" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "ctrlc", @@ -10457,7 +10078,7 @@ dependencies = [ [[package]] name = "zkm-curves" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "cfg-if", "curve25519-dalek", @@ -10471,6 +10092,8 @@ dependencies = [ "p3-field", "serde", "snowbridge-amcl", + "thiserror 1.0.69", + "tracing", "typenum", "zkm-primitives", "zkm-stark", @@ -10479,7 +10102,7 @@ dependencies = [ [[package]] name = "zkm-derive" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "quote", "syn 1.0.109", @@ -10488,7 +10111,7 @@ dependencies = [ [[package]] name = "zkm-lib" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "cfg-if", @@ -10501,7 +10124,7 @@ dependencies = [ [[package]] name = "zkm-primitives" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "hex", @@ -10519,7 +10142,7 @@ dependencies = [ [[package]] name = "zkm-prover" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "anyhow", "bincode", @@ -10543,7 +10166,6 @@ dependencies = [ "serial_test", "thiserror 1.0.69", "tracing", - "tracing-appender", "tracing-subscriber", "zkm-core-executor", "zkm-core-machine", @@ -10558,7 +10180,7 @@ dependencies = [ [[package]] name = "zkm-recursion-circuit" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "hashbrown 0.14.5", "itertools 0.13.0", @@ -10591,7 +10213,7 @@ dependencies = [ [[package]] name = "zkm-recursion-compiler" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "backtrace", "itertools 0.13.0", @@ -10612,13 +10234,10 @@ dependencies = [ [[package]] name = "zkm-recursion-core" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "backtrace", - "cbindgen", - "cc", "ff 0.13.1", - "glob", "hashbrown 0.14.5", "itertools 0.13.0", "p3-air", @@ -10636,7 +10255,6 @@ dependencies = [ "p3-poseidon2", "p3-symmetric", "p3-util", - "pathdiff", "rand 0.8.5", "serde", "static_assertions", @@ -10653,7 +10271,7 @@ dependencies = [ [[package]] name = "zkm-recursion-derive" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "quote", "syn 1.0.109", @@ -10662,12 +10280,11 @@ dependencies = [ [[package]] name = "zkm-recursion-gnark-ffi" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "anyhow", "bincode", "bindgen", - "cc", "cfg-if", "hex", "log", @@ -10687,11 +10304,10 @@ dependencies = [ [[package]] name = "zkm-sdk" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ - "alloy-signer 1.1.3", - "alloy-signer-local", - "alloy-sol-types", + "alloy-primitives", + "alloy-signer 1.2.1", "anyhow", "async-trait", "bincode", @@ -10735,7 +10351,7 @@ dependencies = [ [[package]] name = "zkm-stark" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "arrayref", "hashbrown 0.14.5", @@ -10777,12 +10393,13 @@ dependencies = [ [[package]] name = "zkm-zkvm" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "cfg-if", "getrandom 0.2.16", "lazy_static", + "libm", "rand 0.8.5", "serde", "sha2", @@ -10790,6 +10407,12 @@ dependencies = [ "zkm-primitives", ] +[[package]] +name = "zmij" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e404bcd8afdaf006e529269d3e85a743f9480c3cef60034d77860d02964f3ba" + [[package]] name = "zstd" version = "0.11.2+zstd.1.5.2" @@ -10836,8 +10459,3 @@ dependencies = [ "cc", "pkg-config", ] - -[[patch.unused]] -name = "alloy-primitives" -version = "1.1.2" -source = "git+https://github.com/ziren-patches/core.git?branch=patch-alloy-primitives-1.1.2#288a6856fc6e4160e85903f2af1c4af92ed4ccf9" diff --git a/Cargo.toml b/Cargo.toml index 7a730b7..157c07b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,27 +57,29 @@ zkm-sdk = { git = "https://github.com/ProjectZKM/Ziren" } # zkm-prover = { path = "../Ziren/crates/prover" } # zkm-sdk = { path = "../Ziren/crates/sdk" } -# reth goat -reth-primitives-traits = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-consensus = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-evm = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-evm-ethereum = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-optimism-evm = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-optimism-primitives = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-storage-errors = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-trie = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-chainspec = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-optimism-chainspec = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-execution-types = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-errors = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-ethereum-consensus = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-ethereum-primitives = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false, features = ["serde"] } -reth-optimism-consensus = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } -reth-optimism-forks = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.3.10", default-features = false } +# reth +reth-primitives-traits = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-consensus = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-consensus-common = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-evm = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-evm-ethereum = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-optimism-evm = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-optimism-primitives = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-storage-errors = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-trie = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-chainspec = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-optimism-chainspec = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-execution-types = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-errors = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-ethereum-consensus = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-ethereum-primitives = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false, features = ["serde"] } +reth-optimism-consensus = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } +reth-optimism-forks = { git = "https://github.com/ziren-patches/reth", branch = "patch-1.9.3", default-features = false } # reth-primitives-traits = { path = "../patch/reth/crates/primitives-traits", default-features = false } # reth-consensus = { path = "../patch/reth/crates/consensus/consensus", default-features = false } -# reth-evm = { path = "../patch/reth/crates/evm", default-features = false } +# reth-consensus-common = { path = "../patch/reth/crates/consensus/common", default-features = false } +# reth-evm = { path = "../patch/reth/crates/evm/evm", default-features = false } # reth-evm-ethereum = { path = "../patch/reth/crates/ethereum/evm", default-features = false } # reth-optimism-evm = { path = "../patch/reth/crates/optimism/evm", default-features = false } # reth-optimism-primitives = { path = "../patch/reth/crates/optimism/primitives", default-features = false } @@ -92,26 +94,26 @@ reth-optimism-forks = { git = "https://github.com/ziren-patches/reth", branch = # reth-optimism-consensus = { path = "../patch/reth/crates/optimism/consensus", default-features = false } # reth-optimism-forks = { path = "../patch/reth/crates/optimism/hardforks", default-features = false } -# revm goat -revm = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", features = [ +# revm +revm = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", features = [ "serde", - "kzg-rs", "bn", ], default-features = false } -revm-bytecode = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", default-features = false } -revm-state = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", default-features = false } -revm-primitives = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", features = [ +revm-bytecode = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +revm-state = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +revm-primitives = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", features = [ "serde", ], default-features = false } -revm-interpreter = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", default-features = false } -revm-precompile = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", default-features = false } -revm-database-interface = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", default-features = false } -op-revm = { git = "https://github.com/ziren-patches/revm", branch = "patch-22.0.0", default-features = false } -revm-inspectors = { git = "https://github.com/ziren-patches/revm-inspectors", branch = "patch-0.19.0" } +revm-interpreter = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +revm-precompile = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +revm-database = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +revm-database-interface = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +op-revm = { git = "https://github.com/ziren-patches/revm", branch = "patch-31.0.2", default-features = false } +revm-inspectors = { git = "https://github.com/ziren-patches/revm-inspectors", branch = "patch-0.32.0" } # revm = { path = "../patch/revm/crates/revm", features = [ # "serde", -# "kzg-rs", +# "bn", # ], default-features = false } # revm-bytecode = { path = "../patch/revm/crates/bytecode", default-features = false } # revm-state = { path = "../patch/revm/crates/state", default-features = false } @@ -120,6 +122,7 @@ revm-inspectors = { git = "https://github.com/ziren-patches/revm-inspectors", br # ], default-features = false } # revm-interpreter = { path = "../patch/revm/crates/interpreter", default-features = false } # revm-precompile = { path = "../patch/revm/crates/precompile", default-features = false } +# revm-database = { path = "../patch/revm/crates/database", default-features = false } # revm-database-interface = { path = "../patch/revm/crates/database/interface", default-features = false } # op-revm = { path = "../patch/revm/crates/optimism", default-features = false } # revm-inspectors = { path = "../patch/revm-inspectors" } @@ -130,26 +133,27 @@ alloy-primitives = { version = "1.0.0", default-features = false, features = ["s alloy-rlp = "0.3.10" alloy-trie = "0.8.1" -# alloy goat -alloy-evm = { git = "https://github.com/ziren-patches/evm", branch = "patch-0.4.0", default-features = false } -alloy-provider = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false, features = [ +# alloy +alloy-evm = { git = "https://github.com/ziren-patches/evm", branch = "patch-0.23.0", default-features = false } +alloy-provider = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false, features = [ "reqwest", "reqwest-rustls-tls", ] } -alloy-rpc-types = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false, features = [ +alloy-rpc-types = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false, features = [ "eth", ] } -alloy-json-rpc = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false } -alloy-genesis = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false } -alloy-consensus = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false, features = ["serde", "serde-bincode-compat"] } -alloy-network = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false } -alloy-transport = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false } -alloy-transport-http = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", features = [ +alloy-rpc-types-debug = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } +alloy-json-rpc = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } +alloy-genesis = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } +alloy-consensus = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false, features = ["serde", "serde-bincode-compat"] } +alloy-network = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } +alloy-transport = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } +alloy-transport-http = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", features = [ "reqwest-rustls-tls", ], default-features = false } -alloy-transport-ws = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0" } -alloy-rpc-client = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false } -alloy-eips = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0.14.0", default-features = false } +alloy-transport-ws = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41" } +alloy-rpc-client = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } +alloy-eips = { git = "https://github.com/ziren-patches/alloy", branch = "patch-1.0.41", default-features = false } # alloy-evm = { path = "../patch/evm/crates/evm", default-features = false } # alloy-provider = { path = "../patch/alloy/crates/provider", default-features = false, features = [ @@ -159,6 +163,7 @@ alloy-eips = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0 # alloy-rpc-types = { path = "../patch/alloy/crates/rpc-types", default-features = false, features = [ # "eth", # ] } +# alloy-rpc-types-debug = { path = "../patch/alloy/crates/rpc-types-debug", default-features = false} # alloy-json-rpc = { path = "../patch/alloy/crates/json-rpc", default-features = false } # alloy-genesis = { path = "../patch/alloy/crates/genesis", default-features = false } # alloy-consensus = { path = "../patch/alloy/crates/consensus", default-features = false, features = ["serde", "serde-bincode-compat"] } @@ -172,16 +177,18 @@ alloy-eips = { git = "https://github.com/ziren-patches/alloy", branch = "patch-0 # alloy-eips = { path = "../patch/alloy/crates/eips", default-features = false } # op goat -alloy-op-evm = { git = "https://github.com/ziren-patches/evm", branch = "patch-0.4.0", default-features = false } -op-alloy-consensus = { git = "https://github.com/ziren-patches/op-alloy", branch = "patch-0.13.0" } -op-alloy-network = { git = "https://github.com/ziren-patches/op-alloy", branch = "patch-0.13.0" } -op-alloy-rpc-types = { git = "https://github.com/ziren-patches/op-alloy", branch = "patch-0.13.0" } +alloy-op-evm = { git = "https://github.com/ziren-patches/evm", branch = "patch-0.23.0", default-features = false } +op-alloy-consensus = { git = "https://github.com/ziren-patches/op-alloy", branch = "patch-0.22.0" } +op-alloy-network = { git = "https://github.com/ziren-patches/op-alloy", branch = "patch-0.22.0" } +op-alloy-rpc-types = { git = "https://github.com/ziren-patches/op-alloy", branch = "patch-0.22.0" } # alloy-op-evm = { path = "../patch/evm/crates/evm", default-features = false } # op-alloy-consensus = { path = "../patch/op-alloy/crates/consensus" } # op-alloy-network = { path = "../patch/op-alloy/crates/network" } # op-alloy-rpc-types = { path = "../patch/op-alloy/crates/rpc-types" } +kzg-rs = { git = "https://github.com/ziren-patches/kzg-rs", branch = "ziren" } + [workspace.lints] rust.missing_debug_implementations = "warn" rust.unreachable_pub = "warn" @@ -191,8 +198,8 @@ rustdoc.all = "warn" [patch.crates-io] # Precompile patches -sha2 = { git = "https://github.com/ziren-patches/RustCrypto-hashes", branch = "patch-sha2-0.10.8", package = "sha2" } +sha2 = { git = "https://github.com/ziren-patches/RustCrypto-hashes", branch = "patch-sha2-0.10.9", package = "sha2" } bn = { git = "https://github.com/ziren-patches/bn", branch = "patch-0.6.0", package = "substrate-bn" } k256 = { git = "https://github.com/ziren-patches/elliptic-curves", branch = "patch-k256-0.13.4" } p256 = { git = "https://github.com/ziren-patches/elliptic-curves", branch = "patch-p256-0.13.2" } -alloy-primitives-v1-1-2 = { git = "https://github.com/ziren-patches/core.git", package = "alloy-primitives", branch = "patch-alloy-primitives-1.1.2" } +alloy-primitives-v1-4-1 = { git = "https://github.com/ziren-patches/core.git", package = "alloy-primitives", branch = "patch-alloy-primitives-1.4.1" } diff --git a/README.md b/README.md index 356208a..72ee6e1 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ The client input (witness) generated by executing against RPC can be cached to s cargo run -r --bin host -- --block-number --chain-id --cache-dir /path/to/cache # eg. -cargo run -r --bin host -- --block-number 18884864 --chain-id 1 --cache-dir ./bin/host +cargo run -r --bin host -- --block-number 9831027 --chain-id 48816 --cache-dir ./bin/host ``` Note that even when utilizing a cached input, the host still needs access to the chain ID to identify the network type, either through `--rpc-url` or `--chain-id`. To run the host completely offline, use `--chain-id` for this. diff --git a/bin/eth-proofs/src/main.rs b/bin/eth-proofs/src/main.rs index 46d4ae5..6871a11 100644 --- a/bin/eth-proofs/src/main.rs +++ b/bin/eth-proofs/src/main.rs @@ -55,7 +55,7 @@ async fn main() -> eyre::Result<()> { let alerting_client = args.pager_duty_integration_key.map(AlertingClient::new); let ws = WsConnect::new(args.ws_rpc_url); - let ws_provider = ProviderBuilder::new().on_ws(ws).await?; + let ws_provider = ProviderBuilder::new().connect_ws(ws).await?; let http_provider = create_provider(args.http_rpc_url); let debug_http_provider = create_provider(args.debug_http_rpc_url); diff --git a/bin/guest/Cargo.lock b/bin/guest/Cargo.lock index 3ab79c3..0c5b93e 100644 --- a/bin/guest/Cargo.lock +++ b/bin/guest/Cargo.lock @@ -25,15 +25,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - [[package]] name = "allocator-api2" version = "0.2.21" @@ -42,9 +33,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alloy-chains" -version = "0.2.23" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35d744058a9daa51a8cf22a3009607498fcf82d3cf4c5444dd8056cdf651f471" +checksum = "b163ff4acf0eac29af05a911397cc418a76e153467b859398adc26cb9335a611" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -55,22 +46,23 @@ dependencies = [ [[package]] name = "alloy-consensus" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-serde", "alloy-trie", + "alloy-tx-macros", "auto_impl", - "bytes", "c-kzg", "derive_more", "either", "k256", "once_cell", "rand 0.8.5", + "secp256k1", "serde", "serde_json", "serde_with", @@ -79,8 +71,8 @@ dependencies = [ [[package]] name = "alloy-consensus-any" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-consensus", "alloy-eips", @@ -132,8 +124,8 @@ dependencies = [ [[package]] name = "alloy-eips" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -146,13 +138,15 @@ dependencies = [ "derive_more", "either", "serde", + "serde_with", "sha2", + "thiserror 2.0.17", ] [[package]] name = "alloy-evm" -version = "0.4.0" -source = "git+https://github.com/ziren-patches/evm?branch=patch-0.4.0#57b583d7a27668c1b4fb1f2a655675e1be6b497e" +version = "0.23.0" +source = "git+https://github.com/ziren-patches/evm?branch=patch-0.23.0#bf2c1b5816835b4a581b509598555d7dd01df17d" dependencies = [ "alloy-consensus", "alloy-eips", @@ -168,21 +162,22 @@ dependencies = [ [[package]] name = "alloy-genesis" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-serde", "alloy-trie", "serde", + "serde_with", ] [[package]] name = "alloy-hardforks" -version = "0.2.13" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165210652f71dfc094b051602bafd691f506c54050a174b1cba18fb5ef706a3" +checksum = "2d9a33550fc21fd77a3f8b63e99969d17660eec8dcc50a95a80f7c9964f7680b" dependencies = [ "alloy-chains", "alloy-eip2124", @@ -205,11 +200,12 @@ dependencies = [ [[package]] name = "alloy-json-rpc" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "alloy-sol-types", + "http", "serde", "serde_json", "thiserror 2.0.17", @@ -218,8 +214,8 @@ dependencies = [ [[package]] name = "alloy-network" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -243,8 +239,8 @@ dependencies = [ [[package]] name = "alloy-network-primitives" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-consensus", "alloy-eips", @@ -304,8 +300,8 @@ dependencies = [ [[package]] name = "alloy-rpc-types" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -315,18 +311,29 @@ dependencies = [ [[package]] name = "alloy-rpc-types-any" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", "alloy-serde", ] +[[package]] +name = "alloy-rpc-types-debug" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" +dependencies = [ + "alloy-primitives", + "derive_more", + "serde", + "serde_with", +] + [[package]] name = "alloy-rpc-types-engine" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-consensus", "alloy-eips", @@ -338,8 +345,8 @@ dependencies = [ [[package]] name = "alloy-rpc-types-eth" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -352,13 +359,14 @@ dependencies = [ "itertools 0.14.0", "serde", "serde_json", + "serde_with", "thiserror 2.0.17", ] [[package]] name = "alloy-serde" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "serde", @@ -367,8 +375,8 @@ dependencies = [ [[package]] name = "alloy-signer" -version = "0.14.0" -source = "git+https://github.com/ziren-patches/alloy?branch=patch-0.14.0#c5e571d372aaa8c2caea9672dfd4cd195e5c50f2" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ "alloy-primitives", "async-trait", @@ -381,9 +389,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312" +checksum = "09eb18ce0df92b4277291bbaa0ed70545d78b02948df756bbd3d6214bf39a218" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", @@ -395,9 +403,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-expander" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028" +checksum = "95d9fa2daf21f59aa546d549943f10b5cce1ae59986774019fbedae834ffe01b" dependencies = [ "alloy-sol-macro-input", "const-hex", @@ -413,9 +421,9 @@ dependencies = [ [[package]] name = "alloy-sol-macro-input" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c" +checksum = "9396007fe69c26ee118a19f4dee1f5d1d6be186ea75b3881adf16d87f8444686" dependencies = [ "const-hex", "dunce", @@ -429,9 +437,9 @@ dependencies = [ [[package]] name = "alloy-sol-type-parser" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9" +checksum = "af67a0b0dcebe14244fc92002cd8d96ecbf65db4639d479f5fcd5805755a4c27" dependencies = [ "serde", "winnow", @@ -451,9 +459,9 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.8.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983d99aa81f586cef9dae38443245e585840fcf0fc58b09aee0b1f27aed1d500" +checksum = "2b77b56af09ead281337d06b1d036c88e2dc8a2e45da512a532476dbee94912b" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -466,62 +474,24 @@ dependencies = [ ] [[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anstream" -version = "0.6.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +name = "alloy-tx-macros" +version = "1.0.41" +source = "git+https://github.com/ziren-patches/alloy?branch=patch-1.0.41#6e100c7f3487b4e00f41eaf64558e55e3ebec984" dependencies = [ - "windows-sys", + "alloy-primitives", + "darling", + "proc-macro2", + "quote", + "syn 2.0.111", ] [[package]] -name = "anstyle-wincon" -version = "3.0.11" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys", + "libc", ] [[package]] @@ -790,6 +760,12 @@ dependencies = [ "rand 0.8.5", ] +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + [[package]] name = "arrayvec" version = "0.7.6" @@ -977,9 +953,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "byte-slice-cast" @@ -1039,9 +1015,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.49" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "jobserver", @@ -1068,59 +1044,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ "iana-time-zone", - "js-sys", "num-traits", "serde", - "wasm-bindgen", "windows-link", ] -[[package]] -name = "clap" -version = "4.5.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.53" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.49" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.111", -] - -[[package]] -name = "clap_lex" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - [[package]] name = "const-hex" version = "1.17.0" @@ -1159,15 +1087,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "convert_case" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "convert_case" version = "0.10.0" @@ -1213,15 +1132,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -1295,6 +1205,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", + "serde", "strsim", "syn 2.0.111", ] @@ -1354,20 +1265,20 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" dependencies = [ - "convert_case 0.10.0", + "convert_case", "proc-macro2", "quote", "rustc_version 0.4.1", @@ -1495,17 +1406,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "enumn" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.111", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -1730,10 +1630,12 @@ dependencies = [ "alloy-rpc-types", "bincode", "itertools 0.13.0", + "kzg-rs", "mpt", "primitives", "reth-chainspec", "reth-consensus", + "reth-consensus-common", "reth-errors", "reth-ethereum-consensus", "reth-ethereum-primitives", @@ -1821,6 +1723,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + [[package]] name = "iana-time-zone" version = "0.1.64" @@ -1893,9 +1805,9 @@ checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -1907,9 +1819,9 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" @@ -2002,12 +1914,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "is_terminal_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" - [[package]] name = "itertools" version = "0.10.5" @@ -2037,9 +1943,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" [[package]] name = "jobserver" @@ -2167,43 +2073,12 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - [[package]] name = "memchr" version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" -[[package]] -name = "metrics" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8" -dependencies = [ - "ahash", - "portable-atomic", -] - -[[package]] -name = "metrics-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3dbdd96ed57d565ec744cba02862d707acf373c5772d152abae6ec5c4e24f6c" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 2.0.111", -] - [[package]] name = "modular-bitfield" version = "0.11.2" @@ -2231,21 +2106,14 @@ version = "0.1.0" dependencies = [ "alloy-primitives", "alloy-rlp", + "alloy-rpc-types", + "alloy-rpc-types-debug", "reth-trie", "rlp", "serde", "thiserror 1.0.69", ] -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys", -] - [[package]] name = "num" version = "0.4.3" @@ -2383,13 +2251,14 @@ dependencies = [ [[package]] name = "nybbles" -version = "0.3.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8983bb634df7248924ee0c4c3a749609b5abcb082c28fffe3254b3eb3602b307" +checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" dependencies = [ "alloy-rlp", - "const-hex", + "cfg-if", "proptest", + "ruint", "serde", "smallvec", ] @@ -2404,16 +2273,10 @@ dependencies = [ "portable-atomic", ] -[[package]] -name = "once_cell_polyfill" -version = "1.70.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" - [[package]] name = "op-alloy-consensus" -version = "0.13.0" -source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.13.0#d0ee5a615eccbb23c3d610a297508bf26d2b6629" +version = "0.22.0" +source = "git+https://github.com/ziren-patches/op-alloy?branch=patch-0.22.0#20048eaa105b1c06ca4fca6108a047a2fda0c494" dependencies = [ "alloy-consensus", "alloy-eips", @@ -2426,6 +2289,19 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "git+https://github.com/ziren-patches/elliptic-curves?branch=patch-p256-0.13.2#a6f1a1fb07020d00f627725a20dc336983be3946" +dependencies = [ + "ecdsa", + "elliptic-curve", + "hex", + "primeorder", + "sha2", + "zkm-lib", +] + [[package]] name = "p3-dft" version = "0.1.0" @@ -2619,9 +2495,9 @@ dependencies = [ [[package]] name = "phf" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ "phf_macros", "phf_shared", @@ -2630,19 +2506,19 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ + "fastrand", "phf_shared", - "rand 0.8.5", ] [[package]] name = "phf_macros" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ "phf_generator", "phf_shared", @@ -2653,9 +2529,9 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ "siphasher", ] @@ -2690,9 +2566,9 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f59e70c4aef1e55797c2e8fd94a4f2a973fc972cfde0e0b05f683667b0cd39dd" [[package]] name = "potential_utf" @@ -2718,6 +2594,14 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "primeorder" +version = "0.13.1" +source = "git+https://github.com/ziren-patches/elliptic-curves?branch=patch-p256-0.13.2#a6f1a1fb07020d00f627725a20dc336983be3946" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -2733,6 +2617,7 @@ dependencies = [ name = "primitives" version = "0.1.0" dependencies = [ + "alloy-eips", "alloy-genesis", "alloy-rpc-types", "eyre", @@ -2940,29 +2825,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - [[package]] name = "regex-syntax" version = "0.8.8" @@ -2982,8 +2844,8 @@ dependencies = [ [[package]] name = "reth-chainspec" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-chains", "alloy-consensus", @@ -3002,8 +2864,8 @@ dependencies = [ [[package]] name = "reth-codecs" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3020,10 +2882,9 @@ dependencies = [ [[package]] name = "reth-codecs-derive" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ - "convert_case 0.7.1", "proc-macro2", "quote", "syn 2.0.111", @@ -3031,8 +2892,8 @@ dependencies = [ [[package]] name = "reth-consensus" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -3044,8 +2905,8 @@ dependencies = [ [[package]] name = "reth-consensus-common" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3056,8 +2917,8 @@ dependencies = [ [[package]] name = "reth-db-models" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-eips", "alloy-primitives", @@ -3066,20 +2927,19 @@ dependencies = [ [[package]] name = "reth-errors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "reth-consensus", "reth-execution-errors", - "reth-fs-util", "reth-storage-errors", "thiserror 2.0.17", ] [[package]] name = "reth-ethereum-consensus" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3094,8 +2954,8 @@ dependencies = [ [[package]] name = "reth-ethereum-forks" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-eip2124", "alloy-hardforks", @@ -3106,29 +2966,25 @@ dependencies = [ [[package]] name = "reth-ethereum-primitives" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-evm", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-eth", - "derive_more", - "rand 0.8.5", + "alloy-serde", "reth-codecs", "reth-primitives-traits", - "revm-context", - "secp256k1", "serde", "serde_with", ] [[package]] name = "reth-evm" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3150,26 +3006,28 @@ dependencies = [ [[package]] name = "reth-evm-ethereum" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-evm", "alloy-primitives", + "alloy-rpc-types-engine", "reth-chainspec", "reth-ethereum-forks", "reth-ethereum-primitives", "reth-evm", "reth-execution-types", "reth-primitives-traits", + "reth-storage-errors", "revm", ] [[package]] name = "reth-execution-errors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-evm", "alloy-primitives", @@ -3181,8 +3039,8 @@ dependencies = [ [[package]] name = "reth-execution-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3195,29 +3053,10 @@ dependencies = [ "revm", ] -[[package]] -name = "reth-fs-util" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" -dependencies = [ - "serde", - "serde_json", - "thiserror 2.0.17", -] - -[[package]] -name = "reth-metrics" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" -dependencies = [ - "metrics", - "metrics-derive", -] - [[package]] name = "reth-network-peers" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -3228,19 +3067,19 @@ dependencies = [ [[package]] name = "reth-primitives-traits" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", "alloy-genesis", "alloy-primitives", "alloy-rlp", + "alloy-rpc-types-eth", "alloy-trie", "auto_impl", "bytes", "derive_more", - "k256", "once_cell", "op-alloy-consensus", "reth-codecs", @@ -3255,18 +3094,19 @@ dependencies = [ [[package]] name = "reth-prune-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "derive_more", + "strum", "thiserror 2.0.17", ] [[package]] name = "reth-stages-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "reth-trie-common", @@ -3274,8 +3114,8 @@ dependencies = [ [[package]] name = "reth-static-file-types" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "derive_more", @@ -3285,8 +3125,8 @@ dependencies = [ [[package]] name = "reth-storage-api" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3307,8 +3147,8 @@ dependencies = [ [[package]] name = "reth-storage-errors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-eips", "alloy-primitives", @@ -3321,25 +3161,10 @@ dependencies = [ "thiserror 2.0.17", ] -[[package]] -name = "reth-tracing" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" -dependencies = [ - "clap", - "eyre", - "rolling-file", - "tracing", - "tracing-appender", - "tracing-journald", - "tracing-logfmt", - "tracing-subscriber", -] - [[package]] name = "reth-trie" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -3360,8 +3185,8 @@ dependencies = [ [[package]] name = "reth-trie-common" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-consensus", "alloy-primitives", @@ -3377,33 +3202,32 @@ dependencies = [ [[package]] name = "reth-trie-sparse" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "alloy-primitives", "alloy-rlp", + "alloy-trie", "auto_impl", - "metrics", "reth-execution-errors", - "reth-metrics", "reth-primitives-traits", - "reth-tracing", "reth-trie-common", "smallvec", + "tracing", ] [[package]] name = "reth-zstd-compressors" -version = "1.3.10" -source = "git+https://github.com/ziren-patches/reth?branch=patch-1.3.10#961eee5d02d811a181fc3c058ba0218e3b756f22" +version = "1.9.3" +source = "git+https://github.com/ziren-patches/reth?branch=patch-1.9.3#1be69c885f5c0be8aeedfd58e97c395a2d24dc1a" dependencies = [ "zstd", ] [[package]] name = "revm" -version = "22.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "31.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "revm-bytecode", "revm-context", @@ -3420,8 +3244,8 @@ dependencies = [ [[package]] name = "revm-bytecode" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "7.1.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "bitvec", "phf", @@ -3431,10 +3255,11 @@ dependencies = [ [[package]] name = "revm-context" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "11.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "alloy-consensus", + "bitvec", "cfg-if", "derive-where", "revm-bytecode", @@ -3447,13 +3272,14 @@ dependencies = [ [[package]] name = "revm-context-interface" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "alloy-consensus", "alloy-eip2930", "alloy-eip7702", "auto_impl", + "either", "revm-database-interface", "revm-primitives", "revm-state", @@ -3462,8 +3288,8 @@ dependencies = [ [[package]] name = "revm-database" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "9.0.5" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "alloy-eips", "revm-bytecode", @@ -3475,10 +3301,11 @@ dependencies = [ [[package]] name = "revm-database-interface" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "8.0.5" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", + "either", "revm-primitives", "revm-state", "serde", @@ -3486,10 +3313,11 @@ dependencies = [ [[package]] name = "revm-handler" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", + "derive-where", "revm-bytecode", "revm-context", "revm-context-interface", @@ -3503,10 +3331,11 @@ dependencies = [ [[package]] name = "revm-inspector" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "12.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "auto_impl", + "either", "revm-context", "revm-database-interface", "revm-handler", @@ -3518,30 +3347,31 @@ dependencies = [ [[package]] name = "revm-interpreter" -version = "18.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "29.0.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "revm-bytecode", "revm-context-interface", "revm-primitives", + "revm-state", "serde", ] [[package]] name = "revm-precompile" -version = "19.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "29.0.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "ark-bls12-381", "ark-bn254", "ark-ec", "ark-ff 0.5.0", "ark-serialize 0.5.0", + "arrayref", "aurora-engine-modexp", "cfg-if", "k256", - "kzg-rs", - "once_cell", + "p256", "revm-primitives", "ripemd", "sha2", @@ -3550,18 +3380,19 @@ dependencies = [ [[package]] name = "revm-primitives" -version = "18.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "21.0.2" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "alloy-primitives", - "enumn", + "num_enum", + "once_cell", "serde", ] [[package]] name = "revm-state" -version = "3.0.0" -source = "git+https://github.com/ziren-patches/revm?branch=patch-22.0.0#ea223141ce8bd77714cbdf7ac302f82b0ba81437" +version = "8.1.1" +source = "git+https://github.com/ziren-patches/revm?branch=patch-31.0.2#bff54bca9f9b64845c255fe6b94a58c136e846c1" dependencies = [ "bitflags", "revm-bytecode", @@ -3597,15 +3428,6 @@ dependencies = [ "rustc-hex", ] -[[package]] -name = "rolling-file" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8395b4f860856b740f20a296ea2cd4d823e81a2658cf05ef61be22916026a906" -dependencies = [ - "chrono", -] - [[package]] name = "ruint" version = "1.17.0" @@ -3672,9 +3494,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ "bitflags", "errno", @@ -3701,12 +3523,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - [[package]] name = "schemars" version = "0.9.0" @@ -3838,15 +3654,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4" dependencies = [ "itoa", "memchr", - "ryu", "serde", "serde_core", + "zmij", ] [[package]] @@ -3892,8 +3708,8 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" -source = "git+https://github.com/ziren-patches/RustCrypto-hashes?branch=patch-sha2-0.10.8#62d9223ba171ef6d5b637b275c4b982f56d0a949" +version = "0.10.9" +source = "git+https://github.com/ziren-patches/RustCrypto-hashes?branch=patch-sha2-0.10.9#dbfdbd088ac7b55e03c0b9eb192278efe35d67dc" dependencies = [ "cfg-if", "cpufeatures", @@ -3920,15 +3736,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "shlex" version = "1.3.0" @@ -4067,9 +3874,9 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3" +checksum = "5f92d01b5de07eaf324f7fca61cc6bd3d82bbc1de5b6c963e6fe79e86f36580d" dependencies = [ "paste", "proc-macro2", @@ -4096,9 +3903,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.23.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ "fastrand", "getrandom 0.3.4", @@ -4147,15 +3954,6 @@ dependencies = [ "syn 2.0.111", ] -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - [[package]] name = "threadpool" version = "1.8.1" @@ -4217,18 +4015,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap 2.12.1", "toml_datetime", @@ -4238,36 +4036,24 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "pin-project-lite", "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-appender" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" -dependencies = [ - "crossbeam-channel", - "thiserror 2.0.17", - "time", - "tracing-subscriber", -] - [[package]] name = "tracing-attributes" version = "0.1.31" @@ -4281,64 +4067,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", - "valuable", -] - -[[package]] -name = "tracing-journald" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3a81ed245bfb62592b1e2bc153e77656d94ee6a0497683a65a12ccaf2438d0" -dependencies = [ - "libc", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-logfmt" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1f47d22deb79c3f59fcf2a1f00f60cbdc05462bf17d1cd356c1fefa3f444bd" -dependencies = [ - "time", - "tracing", - "tracing-core", - "tracing-subscriber", -] - -[[package]] -name = "tracing-serde" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "serde", - "serde_json", - "sharded-slab", - "thread_local", - "tracing", - "tracing-core", - "tracing-serde", ] [[package]] @@ -4416,12 +4149,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - [[package]] name = "valuable" version = "0.1.1" @@ -4721,7 +4448,7 @@ dependencies = [ [[package]] name = "zkm-lib" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "cfg-if", @@ -4734,7 +4461,7 @@ dependencies = [ [[package]] name = "zkm-primitives" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "hex", @@ -4752,7 +4479,7 @@ dependencies = [ [[package]] name = "zkm-zkvm" version = "1.2.3" -source = "git+https://github.com/ProjectZKM/Ziren#be43a854e4be21c11fb87304f9794dc9137b492d" +source = "git+https://github.com/ProjectZKM/Ziren#03e3cef63e04e5d8b1d7e41a784dd4c3fbc3dfd4" dependencies = [ "bincode", "cfg-if", @@ -4766,6 +4493,12 @@ dependencies = [ "zkm-primitives", ] +[[package]] +name = "zmij" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e404bcd8afdaf006e529269d3e85a743f9480c3cef60034d77860d02964f3ba" + [[package]] name = "zstd" version = "0.13.3" @@ -4793,8 +4526,3 @@ dependencies = [ "cc", "pkg-config", ] - -[[patch.unused]] -name = "p256" -version = "0.13.2" -source = "git+https://github.com/ziren-patches/elliptic-curves?branch=patch-p256-0.13.2#a6f1a1fb07020d00f627725a20dc336983be3946" diff --git a/bin/guest/Cargo.toml b/bin/guest/Cargo.toml index 3a7d058..c4ddad3 100644 --- a/bin/guest/Cargo.toml +++ b/bin/guest/Cargo.toml @@ -27,7 +27,7 @@ tracing = { version = "0.1", features = ["max_level_off", "release_max_level_off [patch.crates-io] # Precompile patches -sha2 = { git = "https://github.com/ziren-patches/RustCrypto-hashes", branch = "patch-sha2-0.10.8", package = "sha2" } +sha2 = { git = "https://github.com/ziren-patches/RustCrypto-hashes", branch = "patch-sha2-0.10.9", package = "sha2" } bn = { git = "https://github.com/ziren-patches/bn", branch = "patch-0.6.0", package = "substrate-bn" } k256 = { git = "https://github.com/ziren-patches/elliptic-curves", branch = "patch-k256-0.13.4" } p256 = { git = "https://github.com/ziren-patches/elliptic-curves", branch = "patch-p256-0.13.2" } diff --git a/bin/host/Cargo.toml b/bin/host/Cargo.toml index 5807582..9abfa53 100644 --- a/bin/host/Cargo.toml +++ b/bin/host/Cargo.toml @@ -38,3 +38,6 @@ reth-primitives-traits.workspace = true [build-dependencies] zkm-build.workspace = true + +[features] +execution-witness = ["host-executor/execution-witness"] diff --git a/bin/host/input/48816/9831027.bin b/bin/host/input/48816/9831027.bin new file mode 100644 index 0000000000000000000000000000000000000000..c1775e23ee0ef0e51395dab736590fe140519854 GIT binary patch literal 152615 zcmd?RbyOWmxBm?UC%C)2JHZ`-JAvR39750l!Gb#kcM0wg+%*aA1PBhn9fAh<%}gfG zotoVBKKK8(*W#Qy-JklN-PPTDSM90;8N|=6JLD6xMO<4VEzQ}xx{NNfISevSpUbWgrr4HuLYlDFt((@8LqJ0O zV?+B#`JctV_W!R3egBF5EW<-U|Go1+HAMeI`TnQ$R{`peSF}HQvOnMd*q|ZMe%6M9 zfQJ5~*W-T*WPcxGspqh2BubuDkK4&Uhib;b3^5@#o&1p-QO5%bV-@}x z@)xLO8||m9UDjRu@%8df@FzSc!!yI<^U`avCL{KIS}|nuzXc)w+uiZYhF`*W)nT5j z47MFolzn2{rX>kpi-(E35h79x>y~{D@U)u0IQKOesG+OD@XBtr7(^7#kV(;K3EZZ7 zu20E_6RXxImj60?$Um=BRr^n?5|Mts7iz-%RX{`d`Tlb+1jN|wFROm;f&BISy{~9z zMb0QM%k)E^o5FdOkM>YAK=!NF|MA`IZ*7W~9xngiRiIV>dHn6i)OmSsMdpS~Xt(@1 zNlYDD$drE`|E>Hy()YK0|J(sN)%nklzmnpXKp>2ZJ6}W6*Oj>k@?k;m?`oZjma3 zd4ylYI<&Gl&k?8Mt^$an1)}#d$c+<|MD~`~?W9Xz3lc>(Kkz4~$no0*uuA>X{LeT2 zDv67$qCk|cg=l2;*?#QGJ1*1$Wg;IfN>)1q^`4Cd&R^XB)j`KX=SD1BL*z^6 z^t^!Z?tt`!m8$%u(epq$eaNk^e4O!E+Ar?EJu&}R z4)XsBf({zu|F_$(_WExP;P@{G{fm$KmxC^m;})@v>rFA{*L~~KpZ?u~%Idos+j!l= z%bY!-k4xhRPLi-Q*OnW33{%+zDLMbJfx+tLv56whV6;wC(PYZlMW(T5H4*Gbq0 zLv2|MS}z8lLye-{`_j*=)5}wTi?$Hqf6HTjU2jeP%j*AjyZ!mdK>qdeXBhe=FE-2H z(58oz%jBJy)3IAP=b6?P9N?E2Ui{tPd~1HN0rH>l=R)745A$uqF2%1?OB1iHl}~w? zgv>VBF@Y|o{079)Q^H6$R44mo zIA1?|UUytIK>)ygn4=#F33<4d9aT4SuZ~6x%JW&vFEpN{NyWNXRR&`KFh`7Ojb47P z#n23##F@A^2fO4Kw81O47f6@3V>{X3E`M)7LV7t!@6CldW_l>7bHW^C$41nSseJtz zQ<_Cn_s%R&K;A4UkK}OP7#H^vYh#7&&0cEog(-Yr)YwOhW*Y%gT5JH;=1SM=Ql6z( zpEN8X>hXE*+TP^mfr_>K3(mxXa5%=Zt^ zn<}d191nD^-am(En#c1f!W!jRp!~f_SaZ-E`d~^4x!ys^`Oi@5O$|%BI?S>ds;}_b z*_fc>1MYb)>j>QrOi2I7Yvh<=*C?zHeVs%{ydh z9{KsC==QgidE#89kyRL-9ss@^QIGBqh>3te3q8mXm}iCJ-h`E7D+$L>F`=~0Hv}I8 z6n2W_M91Pw!4qh%+q9~*R$hF2`7&M(7v4Ypu^IhCJALHyM{Bl-IS8KrVA z452x^ERpG+71dT2X^v%S{$j`eny^sSj-2%0)RiQpZ}xw4UfGV(lxasC`&4=tqEFx( zZ0^(}5teHkigj4bdJ}f*1zG`{%chvOp3|lz+)yZo<($(CY(b&wCBA+&?A-EW;P@_w z;+L`i^lino*qK*VSwZ3`-VZEat{`q}u4u!)*}OrlH1&O{tycYq^ZX|+)BoQ6#4|5J z=zbXv%V33eAlfv*6VcaKNcTG|i$>^s0A`KguZ-GTx?pP#h*ead5~I_RU^I69hT)Bk ze|}sd>jA)D+AuGZtDWv{b)GvIl_KKzDAkwHx;m*Z%Vi^0Jns|-;BPQ#*AtjGUnpol zp0~P3@nD_I<`i+%M-Ux`9mEi4QQt77%q zzqY>xU?i>N)sh0lD@>D18J@6|V-mSWwfb$rQt5&rW1|`M0RS#*^$w*U&6SR(HJMoy zqeZAhP4cAWO6x{Sq^w6PMhORC@idpW0n4M|rg@3!u`@0HIN5la)eI{)TjFLR=a6wb8&~)Qg~!5+&~Gy0wWrTa;$nGRjxSW^nK5xw~}VM zE^1+x^91!-;vC+q0+V>n6?~4>tWS8Md*fs!8^(jde zA$+yYo+bK~@4QyF;Fk7MRB%hMqwyrKZ9H8bfLBZ@opoL`+_4Fr@YTf`Xq*n-h6`BW z>Bsp!v1x2vvjbp3Ni6|o1u{dr4l=Hy%jwW)Us)B;i%H82=U1;AQ>lFbm@h2)Erz{g zsKkU`QJnUs0rMI=VMl+wXA@;y4x*C<835~j%X+Wmeqxf*EB%G!I61oXLS1UJK3ya= zDeR~z7SREK+ePbz#-}mfF5#h3)63vQee2%-WK-|Az^8vjFE`J&0KmDp-H$}(@vYwC zkE?%OI@(NeQMhZe=l9|AOIaM+$te6iG!00)rS%QuQXCiz&d)|2hCb|MvFVy8~o z1^k!*TwK~4L+>>uYjDmv|FITBcFIPyUk--?dNIS-Yp}-tD*&TlxQP)k%bN5RBZa1W z$egIq9FiC!MLybs!SmNB5TE+JNs!8RXdF_-!UN986`$Y}oQ|EmwuS75`Pgt1e-oxV ze-6kuC0f^FE%M7VP-d`uiY~R;btv0W>{xxcoVaQ@LE@JL;I~giRfAkU<%~!rD@aHv zQ!;K3cq=317NQfRtL?`B_zb}4SRWD>99UEd!}&=WUgH=$J0TP8#WGhCi^_j{Vy*?c z$Xs%gBdBy(T(dc0ycgg6sva42TZzN0Q4nkF<2(7s;R4ECJtOyTEoskaiYwTI%cM!A z0x6WATvvwahB0&+J9H-i@JCu6Gbgal2VVNCPZ`M7})B&biZN!CpZNH4EzU?a}gZ4Gp)fC-m!AGM7fAWKJPM`u8yxn@KHy z1TuhERU>2ljJdTj$@)=Mdm{THh8lOa+P;&es+bH`;&9#(qz{}po3=#~9IEXfr!po5N5HT^SI(X-4KH%Iyk*nahUdNj^-;0m{Iq( z_drB<&0W-{T~B;(prlmE{JD4VMj@;n<5MX|0ZUu|tcsDKE@EK-uT9iWr+1w_d1;UlKIMi|y1>#2H+?J$H=V0!H#Vy8>xnN`wv%<+9u9T^M1FgdR}@ z?ZlfKL$CGk`$-@V{Px8VhGL~AJdI6+~w0qd?l@< zizvQfbm2*q1>oBc0~>F7h3h--Qk0q}oHlC$F;kbc* zcJ0AT_q#m1J-qHva8?rb@;E-wjUmdqUrKE;*qr(#xVJr; z1YobQvm#{~qCzI-TUYb$+}Y{6m+7W>lIy(|^oimmkvRZ-&zUZB5d?Yb&i{~XYQDYx z91-iz7uA4liEP`lPzE{(fOCpTTUuW%R`g}#w4g$McX+748rxiQ3z6sMb^M0ZkO9E4 zJfkNZy%i{C&1g-9xC!09*`HuF<~|k@iXT&_W!D=1ei>JzN_A*;`?a-*QB;Ej!&@u| z975)wH$<#KR$~*QqJcwX7P9b2??r=?uSd;jqvX^!EG+SL6zKTORU!1J-zEmW1Gc=G zKq`ZJLl}I>Rsu$zN_K>d!7P_AY^nR?X9QEw4W)dDeU{~N~kEwElBNh96lfI zoM+uD{rxRh3Xma?>ejV~+5E@|s>j4@fu{0RXLFJ< zb$^)*)cCsi8UlwUQjV*ER0INIS z34gxi5OajG?b7WBmEKUHx(dMKU4+CvQ#7qUrHx!P-8{Ipl6IF=`X?+g@#~3t(!G%Y zyoB_!sHGFB(5i$7I#}c?uLJi!NwH!o$sLD&1U|ZD9Dq60aC?`p<!8JE6$X6*zC&fu+P&{zK@pg&OQVm2GBTi1TOUM0NQ@tsCN6p3X!yt(yG2~kdm@s@sH!HBWWX7NDO(o-T9DFOLN`^aQ1+{(4 z!7@N$Bo4Oo^zIf6>}{jowu29kuGeW*+X!9UriRMKb}C%o!htN<-N7;Pb z7N<6p!(s|8Pe)rofI*5@LbY&k0!JUuJ|j%Thuo5qib+7{YGCLnJ~RdrkcAN++gi5_ zd7_yDCuoEikp9AS2CkhfOrlHT3zg^Dm*^z1lA9@$na`{dz1{$9QoNag6E48?iUlLt zbJKeDW|zF06H}nb^o&1*t?z{&02@v5aa=xdsf%xVg_^(pCK*A({`n!{4hFw&@ysa@ z!yJG$Z9nyjBgFeHHZ$r$G^14~-Fb|2?DXwd`Q$Ivkr?;_a9+=P^Can(Ta_BzO3#s< z_u_>^fK#x4QHKq?t<&ZaI6N(ckbwy&FQR{0HFonRZ3(_3u&`5D0~S}=1$#oGrYj6k zKGB_2y7+48c`;om*%~-fC(kb*Jw13c^3-UC5t~I9Y&to4D@>w6sp1w&6`(0x6Qt7YoCQ*INKQPi`7x&NyS^4)^Jb|9kI?4g&VZP0Gt{sv8+3r4AIG^lTMq8xRF}o<@!Ae9v=RpH0*sqDVR90GF|X% zs(Hx%p4yzf!|jdL7rVEY>ijKd1$E*O?ZebNKzW5RI1_I3X7d#lMed{L=L%jw_~(U# z7^$s7C{ou`tLA?X*g}?H4r(A$?`twqC2v1wk7>yu5G@T&Qg(`1Hw~KRhywCF&!ng9 zhdqfRh&#Q9u~;^DRb}unLs2cndq{ctw1}C0mxtXnf_u>{?oVLAr!DxcQ%+EGBVo0v zGfJiM9?c|4vFP_2$Jzba{icDmJhU4=Yi<}ayUt7NvJt^JHS5O=1bf9u<<@1@w^E0rtVJ`)x*CIh&bywv?j^KY za6`#e)Bu>#U>N?5ak`_?N*tEYtTwV*6E`+VmkFbgZsRtDY%fF~a}_e_T|oV|9| zHVVpn;h4~y3ri5xukgua74eF`4@_3BOpME^KXQLcjuT-rO1~{Fm0PkDiNogcwq@+|_A8|8 zus4)qKjJ@(kj7AY!(>3Ulf{jLrl?o-5A;eZA{*^m9f>FV6>Um=h>$&y)wBpklSoDu ze)Dhj^$V1|%qs}wLXX|Na11!tChrhw7AV_mDkyZ4?MWCq!1R1r{!2vkNtt4va!Gqi zwW&s>Of*Z6LkcE78H<3|iBq5{rFfc}0ts^jY__bqW%?MecwYE;GEo-?f3%TR_sgX1 z1f(t1Htq|t`-Mp@>jN+~q&T0x$9r6y@kM1MIIWO4LjDB+J7aaK$yVy?jp?$g07cPl}&bc zi?W)A96b-#dC+*P7y52x#p+rSYG)8#Cko~QfWJ7+H=DaO?SBillwnrJM7hS*qQS2f z##ne*;1D^79RuKl_jzIln^avocrPvym2%GTJm*@yXl+aPXryrcnd7YixQvgG&RqR@ zBm$OmlsBntHov{hK=y%*KcOGg`!FG$Spep0Z#39a!hzUJ(4nd~u-bC=qbRBLzRc3n zOd9X7BL-cLP+Fch6H%JU=n7Qw^(6ZYx1;RWksscV_HEw;6WBb50+hesyrUyJi1A=( zRL<33q9QGHi1_R*;zI6`C#HcGXb+xX?lc}m$e_V~TBRGS7xtEGtOC^`)ZVJ>Ipwr40p|b;LfVh66EBdA z_2@U;0QpbeH3na>t8qLJM;2O+c;uv!2qp7gD25zixm(`Cc`5<0c^j079_~!xtt|a~ z(T)##LVLB_>%mF5&}kAUYxxaU048!NOGsJKuglJKr8|BP?Xihl<%et(-Z$*?g~P>E z7Xg69i6fpg317ZRD$;lS_Zl{9Cb~NLjmCqiO6&O*&X*gH$MRH- zQbip3k~Q6bR`_EB2KXX%Z3oe8ovfV^6b#|95|lwWrC9Z0cVprlEbC4VK#CY5URbQs zJ{l@hlwba&Na!B-{fWR#f2Ej?c*osh*42IXAcbCqy43Kv7)|5T)qNaGl0AdxRCNIY zh}`8-Mkuc!L2Jp54FjJfSq({fENSp*DotJQQQgy)evz(~VcbTa?*^NXA2on5K}a^s zVT(Ka8Kzr#`+N12Q3|6yJ%t?X*nU23pdCCFUHe=Pe&{9c*>JysP~Swpbg-)Cv#CD& zQRIqY+x-ZD#V8G%{6k2n{qJl3m>0QJ&o4SGnNYz)%jVeqd=&c>e8?IeQNZjC5exPi z!pNLl`;IBz_=s{Lv6IxdG0lwzsUHB!!F_>?Vt%@xZ|*{86!=E_si{v5!;%GN#vvDCSG0fU{?d7(sa+*rz|i%@hCpYr~E|EijK1o_o`TG>qlnDr&%Jc($fTrEouFszIvx?l$=4=5-YVillU?{EjVCA99IWwp-dGkk@{G&S(-TX&iN48WAP zHJAxWSi&35rnoqHo6Jb(%R98o9)_A^t)d4vp5R@VDed-=1zU{Ft8ZKTjO;@`#8j{7 z6vbn_;AP94XG3m@fHL!U9+7S1dv*Mln2(;!_iK-yaM2bcqbDO7T-zl@t|kL;+Y33h zqvFTJb^76}CuWBM%2wCqh-C*MRs1lpMo_3yqlPMgN+J1F; z+CFz^0xWC%u6>p^BO6r$UeIMr#!-h%eBs0@TYdiOoN)Z(OP)T$) z!{OJDLd)^~0l;4LqE{?*H z;w$DPD$Niy0}QfuWot&*sUb$Z-KtBS@*4iQ_VuyWh7~Gq)?3sldgWUHrfbI+g4qsS zN7l|3!Im_gNYp56;c^?u;BDbz>~{;(1>nzdte%%#U!iMX7P!3ffmQ6Mf5O&9RTpH= z=geUmexn1x?S`e8td!qV~DwsH9!(xL0k9cW&HV!B%Pdk8 zjY~D%z-L5#Cad#eG~1W73KCPX3E=d>U77!fE8TD5`RX4m4fg`~u}AzH31u244TP2i z=+wjTezxDAi?@HR4ibq9h;t1&&AWvD)N$6Pfo=;iHW1O1@I}*+H0f>^2o(Qybexf)j?P54 zO#5&CexGBh-mNDRf|6~6uzCdXqECqIz2E~C6;h4kESxkxU{3!%L&m3$i=n11OfBE$ zyN>KI>(Nhi+7wx-4lGMIBj7xSqwSuZYT^DgjMHKFX&l8lN3V#g3NPyQ)*9P@b`2ev z*eY_wyeN1DPbYeBM{_SGE4SdIGr-3bC~gbU|2_LA+!!#!k#iVzh{z(`RipDcVUoN< ztn^4=^<#(gsI`YQ0rqQf9z$Me{QJ|wG^bK|6~zlit(A>OWKu<5E$RshHMN0NnPPzQ zd*Sq#UX){$Zow@AD5PdeLDCm=6P0d9lL$*yi$Su@0IcjU;V+*$W1;(n>RQtv^G1Mc zn!~px(kT6#wNUquVFCaagT5fGC>tVeVOPFY*2gzJ`A&9+d+_0GW8lXhYe>I>sSWhJ z%kY5D&F_WRSP5|F1qR+`$oIO{blWjXg<=LYk-r3#50(k>D+jdvIrDscwR`gN>ptx9 z=jMI0pVsRxN$U=(0bm;A+ZqdK^rE4xnf*^?PY@HMN*>J_b$CczEcLo@I)EM2J#|a8 zS%fnSM(am;X%sD=1g!4Z?zAAUapO4dOl8;=0Oh>anV`=Qq2h>6{Jdubw_*{{9i5!u;Ea#W7#3)O}2KpD+NIKh5x?E&tz#74rO zuBZ@-SU8G30buuf6KI515&L(>6wj8$NibVO4+#}_HFj`cv?(V;*nkV5IzE!W8 za$PCW=q9qU;lT!;=G77QkjOEtQst)Vs2s*du>KGk%4v{D+c3& za&*S|`j!BECa`LaH*D~cF(flEgt<2k+8C8tSLFFJi@$<996Lh0x!cL|` z!~=@xu$hpDujbMEBWMyDoYjDG*yShJyA8Ra^EVX9FH=vY0~qHxF^f_UJ8FsHJ-_A( z0h;&PVkgL8pQ3Z4!ry=F0xPz5+1xLPS0jjE~M7=e~r;&B_?U^izn8#6I-z_5g zvCKx9;|MKMQUes^Jq&*2K^t6jI$jN1@y_yK#3;~yu+$^V8X*=v!czG7H6?7cSv6~G z)UOE4<(FTJ9ieew0x)Aw(t|jB9`E!*e++Gq@F3LVZbAzSH%=>>@g7I&P_U~mF7A9} zDgOE_pHkc&3hoh(mwmEf1JuX5qrM1A>cWO+fHHcofeh)REkFH_qtU6huW?q6%ybkc zl3jjejpd1VP*nbY8EZtyH&b69w15IHH~|zd|Uj32x17z*E>gZFhA=_FJ1# z-6z=~l+1NGi z#Yo6>{v%zRfpY`prSIHcjvl}K?q^Elw>}G;s}>pohv~st(KW53sk+NUK$?-tHqWF7 zp5KH>Rm{JJ&$mHn5Mv%jG`M(S(&(jwDf&?lLC;K6gXv|AlJ!r~{`d{nU$@qu9i4x6 zFG1TcfV z1DEPLTA(Jr;}L;WFPlk^mY8b=lN~xnh<;lZMgK?$k0f~KY7Yi9VAO^~o+jGmwO?z! zIq{3x$jlIc$ee@Q>As2d73*sZGDYDP!==7+2HQP%ba>J}16V5OuM^pgJIHOLw6N$IjYJ{xa&i-x9gUP^a#Asa?@dED2aiugkc@~dr zsT~r!0rlZ+do7$>_J|Boi^gC*(~p;`mwA#tme-*2A3p`$N^lr+QEs@63?Z~lc|pJw z`wo%0pvs6z;LyMofYmgcGvTeg)~Gc;6$?*0nnl-^hXuN|1r3JSUs@+=gBOL*#Ud;R zaisTEWnJFqlaH?6iLCG_$0`(lXD45c^3_2z3NL?D5F6)SJc3uZ>8#}?;;y!^Qp;E( zr^3sO%GWsn2kFPH2R$z{YS53~Y@q9FxO48uheMnO)ZNTu zzV7FiG2Sl&_cp1~Y4bD42sni_W^ zvn%W$k5;k+O@emev=U78dQa#Hl_by1!)aG4tF!=)xzlGx5*S_wrk>wJLo6NTw#Ir) zP;=~NE;N3{jTm}D&v*cG&gFfnRq1w)At0YAeZPc}A6JX#{(-p$i8*Lq)?9Q5uLiH& z7K_sFun8G}+Zg!JFnNdF>1t+mC7bSG7ql@Y@zn>-VaO$3 z+ND@4Gzm?|^rgNdfX%#9s@U)ft3HjlI|iZpKlFOU%LUNYNzY@xMkd(5 z<^pqqGAVFE7M8qT{144+dR*lsYQ6P1^Dd)kb|$jW&#v;p2p<%x!a;d(s%;4Exw9T8 zk&1uB9+aUIBd%kVA>gj`2y6{Jb$$QEdZ%zWLj`XCIov9L7)(KCoK&QYEF5{Qgh0^U z^yjq{oSTMgLAU2(ELPgtxE!Hsk1l4Ue-YS+?{w(E1x`@q1h1bSC*;ahywdpkvTY8H z&pVO&C?2CIqqN&G2M+4@yQv|Q(>XJwav6m@7UOX)3SQlF;(mARyuj`>5*hMGW*-3g z2wZ$shc+_Qr@k>9$G+iSQ?B)%ic5O9NV#< z_~N}pH|k--6!-|y`(b0glM3P;_jrgfQ$`WQL1+|fQsd}5}f!hI~I1HjYx zy&-t)!{L@TJ_*EU=DMm~iL(0k~Z;z-DlUW^)Qh*{({ZU>Yri*@^*BP+bR;{&RVMa$V9(8Sm%EUbH9 z#OcpzVbQ_<>@EORVyv#??HrFcU1(=p$xQrN*?qA-{$O;rw1tUFcFKa00E7F`^!h?I zJ@v;D$qFL@RA-)7giWS{#E#;V@aBr=FSo#jqenh-^N3C-m#@xHaX+9yixG1%c7ErL2-2Eyy8-0KR56iyO9VUJZ_^xqQ~|m= z{3|s+C#iyl1^Q6$g7dtpAMu@8KwgnQGRcdXoFoM@R{wQsLp6Un?laLdRDX*bXEg4q zVX0mbsmp~(?ycwZZGvhzwt%5hejD^W?3o(`v9dq<7>A7v=h8E3XM-Az+biK$e>9t!6wT`N?ASJC~v)d<8zeb2W)1Fuv^Re&iykj0thcW9MJ(E8n(; zmVd`4NiG_8Sb=2QCXsr9&c~q!=XBdL zt29|rkPS0uQAiyqCd!f2GL0`{JQAU|muvl*+jdHsr)a$b>)U-8c8#Wwrb5^3g}ZWLnKo}6^QM+5L(x?QVn&-0Od79W%`vr zJTM7ISL9ni`5OJS5-F75*ywv@x(6XvvgaLOi{6RCg7l_fvHLdrvyx5<9to*YwA}30 z3s3W{QFWKsngC4rA>s;qWpOEDP^{4}x@Pb0J&YkV&AU)Jm1hI=-m{1RJiQtEBlr^8 z^Z)~1@yhE{iY zp(F3t?p+7K-$x>%-zRm@V6bkkAAWweKceaSVskmX&Ym8PT9b$R@Mp;Q&uU_zZiAs8 zGfX}qqVgeDv`{rEPo|Hz!j^LIt)FogIYqs&B< zR5nK(y9u>5?R9cNniy4I-7AdG6rEAt8t0QrGrEp!%#ccRC2L($nil7sFi5|}#iz=c z9f(=6o?g#VWbOMreGhlfxR`37(pa;LG?)6*ul+r;06hemna&5q%hJ4v2mKAHJ!$Xv zCE*Kllk2;F^|@NCBFcZ)xl)7-g;ak_6^8uj_I);+;|n}`LB&B@QWIEf=1@ z56fx#R9fRw&3HN<$>Bnx>%1+=%4TFE0ByZVVf050fX}p*XtUcU6K7xB`0_Cg1@5JT ztXQD`mn~c?YfR;5tmgoXoQ8Q%8?0Tz2H!yA4nY+xX*<`xSERW7hXIikNRoRE(xX0Do$a?5Z^(|k#ULvLg%F>hT)PtfGkgA_G6d|(&T^6t2wrQ1x z6uco{Hj&Yjg9G3NBY!@UTgS@+Ne5oFOf-e7WE<%(%ddsHn4z? z2q7(a)l>jpLKesE5I51BL*>4yleF^{z2i11`DA(XD-|8G8*jk~8bDg(vhmAO(9qeW z_uSY+3DaZ!yTnko39$eMEwJY3nLsD9k-o-F_7oJf1EmogW;9zblV!rwcn1MHpl*Xh(2CaE7 zbLm4IBwZ~vi!$B7X5IKnspOif`swdIOg3zEM!04^b5(l5$gc1DnhwofZv!xy6x^gV z18Qh}KLPR#-9}b*LV^;TtabApFr=hw*{jor^+U*H#)v`!+vM2*9F?-R%=p293vM07 zO^TPcfFiE121>jTKsP{Z4C!2wFQg1Z< z-Z+ToUFEu*pD@0nSt2PECMyTvXsifQC}qw2-RLO0mwwGV*}*|jcGhYTAGf)*)=n(d z0eF&>e`@S%hOvlxrQ>`5`M$jT#YK(}#sGrABfhOc$)9<{fBA(gJInNCqxj6Rl8qAnabeOjPHL%oIpdncYu;Uv0Q_J4yJlA?2 zyo*NM$VU$$9I*&nWXa;4^P~rW-=!VlTo=J_bp`DaNRPFma?2c7b-g4`Oi8VJZfrQV z0>CaCk5eHGPdma9$&cW??UUyq*FMRxe&& z?59Q|2zV$zVb_3Rwnaup6tuPUmANk+54`GE;s=xws+ckh`CZS~4vA~j=|b7rh*aU4 z%yw?_s&^RO*cHGCRu;M-ZV7!96itnF_I%5R#b}Zqu~!ToSo?ku_cF6o7|b3%|WLCd`{*ZJ}aPvPJe;R1u5Tq{XY8i9co6Q zR*W*`N+dF=7XUxnATC*?L7vqb)@ znwGPG@NEEwI7E^1Jj9fkOx}+=(B=IUF=NK3h)yk>jjXtnTW1Uo0XlxrS%mocL%%Mi zf?F`4*hSd-VQ+lM(?!}_Q(ZyhX#prx&h}J>+H1a^&r3AY%?+VVE-$!gw9?~*DBCx5 zLb2`#U|-V2?-QW`^SKKjsYxBm5DL8Ok_Yb+j~tY|Ty<-*CI(z<8$O+C$~ek6+5Ah$bU{efPq1)W z{H_37@*R_U?aA*b5mvR(hgKZNoZCOO@+C0}i@?Lrp$dJINGHt{e|7yvdt&^=@W1@Xi8vfF(N8O>=G(cln$>P zgOZ6*59E7Qir4h~gV)qgq&Y8Y7y@q zJ2#%}qa3ilB-vMr(Y#blmPPsGfOTDZQw(ZSnT=!XkG8>w{C(rWJ50Ow6!& z!Zj5QsbG#CkRHE&3?_0djJC%n43s4e4$4Iq33)~@MVL{__ImtlZk}i(4C=W9%8CVF z?yN^7Xu@e+!xn7Yf?tyNu5x_HJYtPBTs<_emjYlPf|#)~=P-@8{hzI17lf9rIrmsw zWe5(fd-@S{(geXUT@a#XBQ)Ujb!~=Wy>qY^am|0~iLReXDtid+;mfpfFaxuhuYO;$ zWT;SNRiKRMUbZl;j4_HCXzWnnuh!)=4A}sfQHwzDFS1VWgu~_Hf;@u3X3Nh`c0F`} zd8!bUSv!dR^T(b*4P&e0&PKjATq%_REWPmufsyB`Ba~UEN`b@ud;4nZe`f&yIT`e1 z1V@^$K*%+fXFw#N<{0Zc&2tF{nb0W{%-e4hEkK6kzpm*~GR5<#)2lZ3YIWwi8`bf6 z=@!~wV?XO1&Bv;+7{$x{*RbdB7r<;(VYz_7QM2&0!y{#zFW!&X*>=7%ugo)6-F=7U zoM-y-ui!uNU5PM_@6m#$i>P3t?@TQW3V!c)(#x9>>L1V9GTwlR3bcR*M2^+9AvczYsAAT6U*ipOB zpx%nx%9)cx6v_LZtHl*hSb&t5&M2q=;ZC@(j(0egPM+2=Ng3A{Z?-5!bj zDsRkLrudSmq`N2x+2*Y0a3|6LWrtYWMFJ*jNNytgP=99bOO^gDA7P~BG=_9!isEQC}u4f3`dWPQ!S*E)8^Q)nrYzN332h@679MnJSLal36S$PMph&nPW zcYJ=a;GRPb@nC8kj^xhK^@69gVU!DMno11C#0^mHw2+~xLF8BeP~udbO17FJo%ynfYCL{`I~p=4W5uR6ZbFcjP6#TwABq0 zY(T%hqlfQNP6FVKQqh;;D-!oqnoBkHvGEi^WktIW6V#`i7~i2N)&xPf&SS7)o$=#o zY&oiyI)0ikQg#M+1i>U%DkdUteqw#i)0A4RiA2d9p-;ifc%(TThjL^a3@kccZFM=nX z_wQIV3jyGcVSikWn=yp>e*XuZt7N8z+>2Mq6Y1MB0-p1zHZm>%oT`+MMwyiD@K)gn zE$>ri1k<>=VoW}v2I`i^GsrpIXaIgYE*~^zigB*P-j01xF?WPtzF!~Oc&&Tm9CsNL zZ};K%CP^%PN;^bt;;Po>zGtbwo44o0!AzFNq)kz0htnv54rbqmotMh0U$tT6n%~JD zKq4MJ96TChy?=b0v>cR_Qy|j`*aFoo8(Lc!mw`gP5>Dc0q-{6CORuuEqxJ$C6N?jR zvkZVq5>>gO+C8wj#) z4QEenw=}K*aPz2BjIYEqm2`3OYGz>=m~*)vXwfm4bZN_5`sfcio&f9;INa6ApK2&h z!}EO)auy4KXJ11`Qrem;IAs+&H?)xOzwO$3d-kAtP^id2 zK0-eaI-_mOcP+w??ixm7n*JYWZynav()NAR-Q6A1-7SrDx0HlPgLF62jWkFp(jXmz zba$t8N{IC1zOH@0&o%D*xSr#9*B`pK$LIH5=ggWl=Q-!hnjv&SORb_&z~V^tql+^u zd&H;t$$bqd2Ow7vcSAkQ(++PwRSqE^-~?q+f7C*i^Z!~(;Q@;dezG8H&^;V~P&SY+ z9vjR!nw8AF@Uc@i(0H%HkTW){AD;}YJI|C=QW^KJl!Q*&rBOCN<+YZXYnQGb;aU5= zl?6~#!R}UBU5~|i^neG6?-!HqYN{#w_3LoEJ>5yKPGjZl;vf>h=#=liMa8S%IRmm; z2i}}q*of#C9TrfH`HF7BAMYw|fvy-o`_lFlr(K&zno1UH2%}1WsfZ%}gVwM$;(FD+ zFM>XxOt(gBu;{Cs$kZJ(JTIem7FL7@JuE|qG3IroR?SSt3&6AN9 zQ)sF(V-@$tZ0wJMAIr_~QN;n+N4CmK&I%R<>2|INV;qpoUMLX_@7H zVq%)lTSGJqOtj9C7rX;kzbK4F>6-@eh~*pmeW*1@g@ENZXKthplyXII)T7iG2dj=~ zPU9nk!)GxLG$9)GFPbyYtN5$k5$?bJq~X!QdM61chh=c=4o0osi=H1z(_V1xcxAY9 zXuYRJw!DiMl5gnXJ_Ky$Xn9@{?rS(1oTMIck%7Rn!vA&V1v{pr_o2yUM*ZeK0JkkJ zJ$rb)I9HYA{MB$z$<{3xKVYK(pUoT2!JoJ6iyZ(P3|!L-GtEe9uDVQJAs}D~SKPn( zyn$VNsmDpxWbA1Iz#gWYbBC|TeZ8nh_PCD23Z%{tSl^}ARZa%{utU_Ta0K8)x2DMH znS|)uVKasVkw}c3h>vmK6wRLTLqm0zPcDNKW-$Wt!iB5K;knw0hI3;6pIE6>*b^B9 zBm1_G@Q{~#5dP_;+)^+p4=Wb*Lbe{~IX6~V2$|L|;bCwnw8+gOU~8UB0=A$exP1>Q z>loCGVhhc})2LU|ftOkcBrS&-PWstNIAsICDO$sEaPE>EHzk#2T{AkgMA4gbOlzg2 zrn4-$391+1guurBrJ+F5l^g{*%6iu@_H+vDu`YrVm5kZCJfB*BDHsKIH;1lImrYl8 zGW$!QKzuscN30xa-2A=c98SPax%3~~iM_P57A{J=q!WIZiqAdy!~R7XV&4127g9bQ zi&v?ieQ9}J>KA`eJq0C5NzB0)CBH)T6@Y8ohSC|{2l`X% z$KKd=tg0cFZ*3Y5lgFX7dx*8&Sb$qe%+)Dt3|=F2V-@2W88x}DEN}iQ%&lBvFurRT z#hQ63Mm!rDD1mQAJ*${`FJz%3(38P{31r>rWBNj zs29kK0Q_P-nX&z|erCp}Lq;rb>ck%${B_n|_N}lduloHn zW;51FQuO!O!}C!N>&Ojov>p4 z9b*92T){%-(vV*g`#r0e$r;o(R#v zljeDAS2|-0i|icyPn%`yrO%v6fmnonmVTGIvoXFt3(~GP9J2D`*B85p#Z;qAB zB!R(r*BvG+sW1xl5KHcsgNj8)b{o=9E@Pas~~6}SglA8$IaZL zZS}=VrxbN;BBa(`&&4AoqdyIm9yW=RdLUDe=Aw4zHrHXwYsdTcdi8ua6+JOd^9^PV zPz%1O?)G|1(<74wzRh!CFp&oVX5aE@T%o+3OQ?hCz2-?DPLBHP+qFdvpN6 zSr`{d)dqY$k)uzk7_IukKE$_?_^^EyL|s`C^c!?05kz@N#cKEUn&r>9og{7nw02sFb zrz|qfR<6vZf_%0m&)J-1T(y1jy@kG38D@EMD41nkw3CIVrRIpH5rZD;awYsJVd50_ z%DHm#ZnW;5Teo>HpuEk2e&>sS#WVY&mDKDRPYMlIb$>h6A_-2?rrnCg7?@tdE>0SG zX`jD*M%^2ixgV75H}CXnUb5 z>j=zEPb$pQTDkg3)A!59H|iL}pHIon^}{l1M{QVZG&v6C1IiQkXpSk~AKQp}7sf*^ z3^5I-0@gzLO&n&c<2@vos$BuNwqmNqx4->lfv|MHb`terjE0wE+Z{%2h1mjW`J`6x zpAMj?^L^3pg%CL;JZuK%Td8RpsZx-hVr7Cq*yhgyk*EYt_@;twkj&O<$Wi|jY^g&^br8hWBFyf z@tki&=(2is8~e|{81SBh7(CnT{XO-bU#bXZ@ce@9LuHKdWLD_vq884WWRE&!r@wbQ z70H-gxqC+h|Jxk`@;0aW!&6@oBFHo^U@2zZijMClxn88q;ctGgc#1XFR0H76%arM+ zR{!XQWwN*eF-Hn+N>=e6BST!6xW{s1@eVKmF2zS}erj8KuX<{*b>A&u5X@w>wiLx9 zv3XANnM5-f>=bOj24T+%V=4;r!|k7bbB)xRsFhr(y%(!`r7GHwIr_&~aYT?EnrGK= zW|L6oKsXCds=Zpu590>%;T?v^py26Z3Se|J#SqP1kFueSzPe^xqe7CnY!eFA4}&NE~cmmmm@(x9_)& zwIwn#(lMvW1y0#)w!zV{{I}hh^Iw!hhsQHQqR3*UH+70H$W@u6Xu{;8wXe1@{*H70 zx({#{=#ZX(8Q&0QV$*P$A9H+pY4_?9*peDy%;*~jkOT^ye`Zp4pFs=kB*7ZqSWojo zbI6=dObXkU`IB0+yuPvY0-_h?``MSYqbRbkt!Zb3$XR`A_X+i+nhmg#&+-?xi+YIi zk`lJa^2@f)gnOEzU?$j~B+V@8TDlJsYNTMy6gA3p|Cc)Hd^3ain-^1*kH=czi-GZtZdHrz7BRj-%^*K9fIHC@j-O}L1McScfhXQ?mBAPz zHfxo;mK$O5k{bQ9=OWJpM7-7lc?y->n{BL2SgI^Ah{>fGQ*lFF-X>7P$KRYXL=_3JepKQGbjcdkRV{yDg4BV|*~jOC;ceUkqvlp} z8WubRN22t0$=Xs{g;lIy3h;RYwL7Qu5NTg|Z|4AI^rPMhX1bq#$KsHdM#%IV3^Mk` z0e&1;1QMDY(@i|!5U*ON%p!E8u`wX(KytRZH&g#tt*;L=rM82li1 z=9A?}D)X+}c#IH+9kh>a7A3+5vQ}?g{ZDFd0JxYoyw;H}vc3<;|I54yqUTvp&Ny+_ zvtqH_MBm(5Qy2i=LD0^lAtQ0Tw^-D{o`Fpckt{uOH6h2CLay`h<6XD};3HE`h~%aW zaShg)@0%9x**A7|=|#G4Z2bGqDInkz!MJF^c}m*R1%kHar{VaR#--?2$4-^H@av~S zOMMZ@32b&id815N0^OlOzf``Wq*`g?ROy{H*EpR^(T+wiohGv=IC#v_SfqsXQmew^ zziLcmG1RGNepTIr8p|uTfq8(4!3-u^pFiQ?AM5PHI`1O~HK$JCYK8H*^QAd3i5mdU&!R!<4~josyv={^ zbRWS;GX0ujMzU^+g=7`#0Ua8Q1g_lhK8PtgAEOhBMXNib=tUF*mI_?g!kRc|R$r1isFLyf7& zp`ajcKTpB{;}26hDY=wSpbIgFt0cawU}tftJ2SCe!zGT24w#XSQ}kiztV)@zhmrr}YNvcQ z?3A2YJ3)?6>$tAOCXkOH<8V03J|+JYZi^MDiq|K>%Jy97FdlMv3BY)r zr15FdE?ZyhlXl6-w-_j2h8>QQIr!T##G_`ar-Bh{YR`VhYWpmeQ8@n_W|COKFw&2# zgOgq^-!SCSa4Y)2)rLVlb*=3pOBT1%w{sL_a@ua5q;vI(4^lfpFN{Ea}4M-1Yq|BT(O3S zqgLGmEhjQ4s~QJyUc9#cY5UAPH^z0k_k#c&&Sy(X`7wlkfWzmN0Mwk}flkJlCo;_~ zjC3?Ihsg%mKptZQ*plgICErqNdzu8bBMA>f39t20d-3s>6n{SQll^C9j~|oO*{^O@ z`ndmI6ybi+QYSVrLYZJ7fkR!N__A+t5wOKDa)i|n=4Zmp%q`8A%=^Q-Us zDy%#Q63VwXsm}YcCzz)3N1sr48j(8z7#WT!P(9d;@I78;SM=Fy977y(Zcz~uwY#d* z)P}1^(0MiXWKa|3^xS0_>@dN@l^>S7{;*!0URNm`{A%WaQiT40qZ{BJzjl>hG-3&= z6vK?6S7HttdtUr#t@#`?*U^yk*&;9M_|IVIRo<=T`LpwWC;tUO_!neSVG*y3s{EX^ zIu$u5%*yi<{|JWo1cP#}?0>!EzUA?*^F`61y<_8C93II!xXBfKeF_9a{aZa~3td9J zhA)Ilph#0=b9dW)&;$S*Y+#nllM;s1i3FI0%wzCgf_u7n)26Y!t$ZHPYf7T*ss%i zV!UB`7R$t6zVj}wmI~~~1D6A`@Ao3-6~1fGre3gmh~a`S6+E0IVlzG8IKI`NZ5N#c z3TP{eSvEkxKA_O^!F|S z-BfUTZWZn1MSmZ=q79Bw4pm0QchO8opOMSz*OjG1Xt=Ho!Vb~(GYJ`BsmHO30%p9# z`0R&7tB*$UX{@+&4y}yJx%VcC?&@E7z*sgb?&X_P4Vu%;j}pHch)Kr(9}E*uH| zlKAT>ct?-4hz0D&wC;+>Z&`~5_4M(sf8`$H$QuX0xYXkvi>j^N?Z|TnXOn)(510tW zv^Dj%emwj3_yEc38>z;9QE-7Ayrr}5dmJ`JD9Q2eLOgk;7@a(&gyn_O&M(D~LL-#T+E+jUYYb^ia}3pz z`5GIy*iBf}N6L*K^#i1;TYjktMQcTV2H&+2|;wl@Y&PK0`Fr8&i!EqJc%{qvcJz+h{J#fe{? z^0tMU+6de!Q%4&2^N!aBznQU057QR|Z1HT~o~oszEZl3$yHl3>n)$|n3To{~y1-ji zxn)(?9Ik)LkER&1@<=9B>(x2X20b0nsETUvLLP{Hw7kY>%6xte4({J;=e-^J;pK^- zAB#1S+MHoPxZ)>;+E?P(^zpurQ3Y(?aYq^J_WeJM>%5dD;(v17)<#9U&8d8O;Ka|v z=QDP41`ID|E^xT4km}~E=-}`FfX=&*!BQa32s3OM!?#1LdUOrIJj*@L)2^(@_f8UWNS#)8~y!_Mmwy{WIVvU`9SGN#>%ts#h1^fV6U1 zQ@o%h{2G;*P_?aE?Dx9+L>>UX_vL{5D%2_}&+h&z2~!$};h4Dx_JT!*FVS{L>o#~EU=w^3l=&l{%E?WWf64g<;@ zpDded%Q_*8If`91ykTg5(c~}@${6|MkA1Y)jrrrCoD9rl`vs?5h&w*1N`mKRV=~Nz zRYbh(Q*>McTJiDS|M&Yd;1-?x2hV@Smd4nbmEFr18N*vfnDFqPUEd*JZ2TB9(8l5mS3S{= z&x=8|hHTlIneawYi+T=AgUIabc_P0_mf){sWFyq$MgZDs6I|)@sjpR5wT2^YaHDQ= z#^Cqod{95A-!V!klkP!100nEyj~GEI-BDmmCX#lI>Hpp>l`GUc^FSvq`$a4F7Z()( zkGp(ZnkF-hPX>OeQ8B~2D-6ikHr3V%Geiv6f z92N>x#v^ksTPOtd*zawB>AIyQLxvGsFJ|;d`2Z*jtGy@lKSMI^>_3u14(QhS7H($c zEyOdgULKihx`G4-O>9Ie2=$j}-5glPSRA;jxG$b5D8kd`Cz!lA@>*^Zcn2ttn)a#{ zz|dyO#DC~g$e14;lORRpY>$(Kk9gse;|T>ibLTNtoSJpbVih^X`^qu+_h%MN2Cv$N;@gd~5d0A8R;DYlki+qPqnj`~n z_O8(92M7=Ul@72>I&S zx2udX{~TPoG|;(EXGEZ(jwJkA{P&8o4W*_dbXaUG9~WLhWveG@aPSum`BrDF;_6EE z*e$hnGgWO?842Csl@y%+QAbGek6X}>AA7wU9m^bS#Tbn|M(nod!oqc)`pLnl$|;(w0C3)pPB}6gia}tcnE$twyFQGVdh|<+s1)MNQ_fy=HX8mOj8mR(_f)ID$}T*GUK`{-=i{JQ<$MBE&-cW@L-% zM1%Nz9cvtk@I%J!3m9_feql8wz!oG6T5Z|rcAZ1P9Nnbm_idW$6E)0ht1C znQ;MF9p$B}Bg8XvLlaN_`!@e^U1tZ+Is4c6LyT7*?v83S0KDWC32VlgU@(43;@aEy zu(*&OLndWJaL_u4uqc^~>jS`+hQE@S0!At^uv zV0O}-Wz@8%byns1f>HEDA|XVIYFl68M5)l^R3$nMTLAW*lXU9HE@Av>AYz!jyL5tO zcX&RfWQiyi$igUNS(XLB8NwXvw_bwhJ+E0wH`3CE3PYIUj9lrj>tzRh&gZefb)qfR z&GHZ%$h@VM7LML1`bd<<&Y?oTj{^4h*3!b#W7_)XlPO7RX)23MwJmk6UvPpKq>Ds7 z;<4CDvy>J30%y!Kf!MB%~%`LAIQ+{Z_z3WaE(fe#Y1Hg3# zH&pZ#eWxbmq7XF}s}+52SfnT=1%r(`<9?E={h9y_hdW>^O!LD8z67!x@7@jTQ@A6A zxTBtPs7G|WD1si@KMnsp+J0cLiCTQSK=ozD$^#bFGR!lT-|Uf#MDlFUogSQUN02sQ z+1Rd#z)2Y!eaf~Ye2U$eHPR(&Alz=aD|WD+1#GFJQV-@BW-?xAiJUI48P{6HXDJ%C z+-oM6>DNe+;9mh?JEU?x*f{!-C4R0KBqcVt-Bk zZq2wi$yDk~Z+47ZCpyJXUWOg2?k`3LMqp_3HhGC}m{usJa^uA;zjx6c6@8D+I)8T0sIAW}D)?DLne zxa3$axt#xcGXKjoh!vb&9(E!kgk(1{fw$nuyymiT*L2j)0c_3h6VB6VMSu`Nz^M#t zbwzc+imwH(yy8j3JA|qCB+fdyN%6dc(Mj>&@({lipu(W=85W2~@-UG)I34Bg>7xS! zzhwTLYU8f1ei`G~6AW+Vxq6qQS(F!a=@cgv8R!3<6c5&c6LFJazw8_P6;%cF?kgkP zYP8=cHUOm@m*Sv;@<$Ay+sB)_9GWotq_?d1J)PCXGN1g14fkmkNF#-xqCxa?z{o>| z5G&x`C8^7Y^xMA23urlGGv!6(YyLA4GRQ@n%ttOU={IrmPV5}g3GeNjc`WxIn=S<# z(L=&r;LOWivF)&C{#b7tatM0!NI`+k`zv+Y5!0&Cf?0cPGNs_5t{uiSw4r^IktXgYlc8 zms5&)T3tFz2Qn`+4Z$9!7#7%N*p%!22I zU>I(GGLludw9{E8#8;wXvG@KJ<>C}BtG1eMABSSYNY-y>{JXL#{%#;VBa$~!bh}Xj zS<%CGfpOL};Y66Kva0u$Em1u41FVJkC zUKu0QKL=pH8ObAg<>ONQ{>#eF`0`#Fx@vyKnubEJnv%{3!G~r5R)v-HRS?J`)9+=2 zs(^eQULND1AJl){RMFN!n@VMw(&F5rm4yH+2)W?Ao5V> znKq+VjI{H*SVnb@R)SQfq#2+*SWWs7t+h|16{Y;JK4PP`f$RajQpYH=7+popqaz?1 zfM376_A$1;c3fN|>~Epnj^Bww!Zhi*;LM)hLHK0hZwkO)5UomCR=bhl(WYZz(-&l^ zkJgCBO2rOx^SE4DUbKSqAF>a07T+Prf1R>c3KK0uu*dPVwohBVMMu>fe3BbrG6$6} zt~1Irt<(AwUp@*z+VXB-l(S=axDxA#e5+e+Ld5{!2$}DZ&F3gOG68bvNH5@`(4swO zwu{D7n`C|;j;q+-zgU9GRYg8@j*um~)IIlnv;3O!}C@+|xsGi2xs(Ot|Rg1wQhVOKi>j@+0fVyHT9kH*)|Lg6XFKiH9N;5yVC&JRv7L*S zShCcV+c1#Y4by}y)$kW(WN$g5F1mLBr*{+}Odew&nm47;WlPW1DwS?+`G+=gh-7!0Bp^1hvi zF$(?Q2zuO_GSM$r~wm1E=(DcH&DbzK3Xk@9AHF8`c#2XBwKa zPT2n8>s+Wb=O{#|AI1G9M47gG$loUa5d-K}VGOqrRZ9<`OG0ixTNw^YCJZzg^OBsk z)jMha9{&W?ys<}03Sl%_pYhxRpNtONtCiUc>G#bo!t@$Ct)yFwF9EohN<`ZOd&7Z? zTnoEO$bC<%tx8HJKVT>2$fjx@7Y1zMg`eK>+Tid{XpVaDSQopB!W$b1m8Vos=so`2 zfQD|M1eDV(p0Vq@1&vV;Ss4?RX(6)MW3xNg#)KZt)H0f$JAuO=tx*n9Uo3MO-GS;X zikql;v!o8#F-Y%EdR~U}uq8yWfO2|sq9=8h;E#|Gk_!Ba$AV|q`D}R-2vWRHyMnWG z^a23<$$PTNECsJ5*n2*?C$UW-+c`nxqZ-!T47^JRl}-N<09U$2<-)C8Cl=Jze(vEG ze5-a$z(MWmPR61kkqyIK4|Wc{RFid_Po4U#L*J^^%sLoJ4EQLo%N0K{Yw0dJsC9yw z-Kyu!i68BlFXHMjAIFe-j}>l7B0OrXp-f}KIS6COK<`1#@LvB44xE6eS}jeOqR+n&4{@z?gJz8Q(SC?789K-X(Zi@e$?j#QM9jQvCh*A#2xv&8PkKJsMz*9_<(AW=%NyX(6H&{C1{y?^boT z(jv8Fmn*gUV@Z-D|Jg@SxTZ!0dAm@Sbcl(X=c^=&e0a=F?Fb}jaP%EKhq6xmyN~$K z$g59DK$JMcdTe&>z?WJN|UHq(aN*9`!K74u2=|dS|)*;yDG|BAL78I&}Xn3{qo(JdGUtrS_tv@ zhfCfyW0j6hLiy;3(+a@q)NJ#;ta%gP(XZ2nvMc>1_B$`VrUM~RUxZlY^dZWy*`geu@^WEcC(K_o;dv>qBeT zr|S6#rK*gMr7*;j+C(@*jc-5H;Q+X09yh!h=5gqgR=xVGFU47JU)M zSym*I$|F$uPv3Em zEaF-CO6(7BQHsw@kh_NgxKv@h9lC?r!|X6_{Fznp4JMZm>L=2oUO#RK#4{?(HvqhV zOX0*N6lK7=p7*v2)ooJjoeugOsVYO6UPco{sUes~*+YKG{CHsGQSSyZBa)xNppfgJ zL=#zc!*GL&j>J#1oS7lH_e?SI0`&8_kn-)6^xL)5m05+faomRoW{Q3=Y&AmQgGy~=#2c0f& zM+*MdSbEFxwt^-V#1g_==P8hZu6pNU0fkR0&! zlCZIL>;syOhza}G;pk-$i@rv@F*ThW1K>oQmu|oJ$fUyH8-j#Kg@4Vm+(h6yZWp4| zE|gmd%~B4)aq87J*s+hK$IrU$LpEbQ6il$Kb7q<24hlU>tWaUy0ocZ!Y?fV+U^sc^ zE2{zxVs;1~eL@<|Izu#X4g0c!MJ@o7Ug@&pmkRl))62cxHPc*e)Mry$D(xgqLBv#NxM=9q zhy`G}czp>JTr4b7r)V+iWr@Z2`>PKDw=|frb$3SqjQ+l(f_RQ%gtA61{f$HY zCXCq-@9bUfB}X!GB4TaV&_7$#!|`plt%>H=B7}D{w&z@m+sD_g{P1hl?=d@{pG5R{ zf-c55UJUk(I>yTHw%es+#1ZkR6Ei2WLz`X!;Y4S=z)rx!lOKbMY9$tvWvaaYe~ zghbC$^qLM4lM&8ek^1+k%zru4KfQVFSj^d-dU3m5EdfPkw*I%o4yU&qWwBhZf){iN zDF51;;IAvoM#eAb-~aiaean!e8D z%OZ4$sO{#+Kkcc|{$`oNptIY2eWS8;Z9EF7^UY_3)jn07nZy&%U=2g;r!ueV>|L~pH%=s3i)OUY_a})e!NvY*e#zk?yOWeeG0$RNDG|ds)s(5 zxUJyrY|Ml8=a(IuNMwbT_GA3R!Kip-!3tSUT#aBVzl)hge)FMl0$>O9O53Yqfl7nq zOhFR#{tfp9OKC4*(8m2%~~MzFN{#gJZb#%ITuKaMsQzej~ox#bTw&$E_V)HLy#D7NGYIQ zFThdk({%~jFyYp2_{&+fw(VJ$GYxzg?0ert@jfCPOD59Tf4=SSUO)~uMVKCzzzPf6 zT}zm4Ja-VrQ5i<899^&?j-dd*k1x(!{&;ZwG6(i#2diTMeiUKK%Efujj$++hLoyFy zss}LKAT!aNF(mkv@Sf%6yf}8yfv@p*CG_U(2cxl~lmU zk9Xmo_GEI3)|e&>39#Dx<7A|J3Og!G9|}!fx5F!o_VdXg#LS6roUn^z#~h*S4gKVR za&`lLZopVGM9NUu5R-ONT{KDO)kn8P^r2Kds1`_z5&&jCx3bF;NeabOYPfEs(4-u; zW7iw+z0B-;TkuMq*BP9U9cIBi4#gsAW+{WyrC%C6qvuyDj;(^-3u)-_#(CobhKC~t zX5Vo|pq6Z1;M$Yqat5Pv0xCovbcjTMADqGXYFP>}1KX`|G*`ppfFxA+f=${UVdPNn z9y%@IanRJIH$AfP697Bs(aDPGWe5wBP`5o8ET-+A;lL(yH;P*KVaIAF-u*8}KmDM> zKY71aEtS&sIQ<+)^iucXCw>$jBBJ2xFGiGH0x)n#sG;KD-Vap}YdCwKDgc2OP;{U> z?RGmTo;Uj4oOmx2u!Y4NTS^3}6xR`Aggxoa`(C0dY@Q^B*S*vy99S=PyHmk;H%DVT z_Y)?1b#a9(k#DGtP)i@=W*qEFhj{DNgp8iNF))-8;gNXF)en6SbN2@RynIAb>BYBR zlLHBCUHBWTa*n(I+2aL_(i+GrnPk#^^D?T5YLr>0fVr1} z&X8BxPBokrmb(P}C+)hAdDH=D+1m(R;`wGIdUgsxN!9Ug*MG!z+`?wFJeQUdAqtDO zX|WvE;3D@gI+>TpuLEG!H0U@QO|C1*+2-Mh>LLhX-083lEGs>E8O9cf`7AB~ZfQal ztr#WHqGw3mM&u*%!L{3mJejIfKSmsQqjDAox-t@JV$?=~A;V-GVwE)QbrQ3W65XYr ziaFdAb>F1aF&%&v9wF%XS?qT>Ht~8xu5^HoaEBoSQ7`E5<2_M7uOclE2VlqdRW$X+ zefg@=$?V3ticfvQ4apZOau8*sb{{Pszp9o2u>BHGv%9iA3R0~vaS-Xp?%j{J^`~*{ z>ejCM$mer$U>X7To0bAp+9q#!&5sgFCvjsT8Yc^aG92W zXwZHY=;Z@o8NI!uzz*N6jOUkhSekFIaBialTdV|K*&*w{IcErfi~5DKpaSy|IAhT=3gciinXDziA2 zg0vN10XWFbjrsaZ?h1Ok!eM4?34BIg?UOBko_n97To*Jyof7~rGgxhXc%1RVx8p#Z zvmW3;wcHR4qAvHTg&nr-WIlEPU}KE|jCawN3B-&CsedB;yrWU~h&87}?w3V< zV}AuBe_hhFr~ma_=l>k{{J+jVp!k;}1ccYCmjAk2(!X+G|44+{>&CCj$Be&=?frc8 z3AZ%fzC0|OvDBiGC$*eAcc>1WwfZ2n%hg9zh^#ezak5IOKj`KP?o{k_%^!;}e_XT5jU&rN>* z5gMW`<{qRZuN2j+y@oGr5V$TN<;=#G{&q5z?S9zjPxj*9+hzgg>?yt#%zf@^qx*aL zU6@z!zU#eMD#wsjfobg|9%I9h3;@rux^wp8hsjq^{)`h=sZwRVh)Qz9Az5BQ5@AE5 z_55q!hyS^Nex4g~w^?T*eGlW4EsD#CHP>4jl~(#byME!Up;hET5%|A<6gCT`m%s4k z_x}NR{V8Q+iZ1;2y^f!pm_}Lo`_vr9Y@asnn1%|PuJg9*+J6Q>C_#I)t3qst%UicW z9SY1J2wY_I!@U(7i3MbF4a_+*L4Dml^1w2*W#htUMKUNbv2rO8KNYRqVzKr@dk`S7 zSpS&hc=4WVy~-DA!TN)&bcqv@hk$p5HKYQlw;kI2Ru1nrvl5s1(+sn1|jsQnNYr<@%{$u#=1*7#s~Tc_MgxGW5i zRy`=pv57d`@w+oA5X+ou_i%+t6gvqIYFPfYIwIx^##`>^=Pmo!Roc-hqy(o5_>ILY8x}`YX25(S1v<&J^}LM#dtZK3A3~-Wb#GpWE;2MG*iP)iuyq0+z>MEt z#hn`)9PI2kw{J5_Vt!RMfI!EA_ou>!Un_4^Iu`+8tC=diF4F7`<%4U-sEa~FA~a%8 zOJ=%v{Uy1Hj2D^A0Q`Gn?SwEh{=$%N{RT^Bc1Ws->k_pQDa#S9U(q%m?T7)G1{Z4f znyqe2*oNP+De{G^X84CS*~ZQ!&S=-Jwc*WH0G_`7%uA!rSdYMbyZXZdqHsY~{d@Zk zDsl{_0?)%8`~UJOWz$xHPlD=yyre4Gd`OA*67{w!_P7eBzO>^8%Q3CQ zhxosabdfIIHqZav_5A+Pf2Puf2W;jWo`2SBOp%56cR9K&c%_TUl@L+5FPxmSU66?I zciRnTiI3VqW@`c4nc>%k_pSABW#lKeA7y=q_;P%W2=0vgA18lG|N5oYne+FL|NaXo zn*sgGnTU+XNSFqtgw-Cugm8qyWOg9VPKk2=a#pQIF91_L*NC1B8<3;u{^;{6_8Qrv z!Z%6Y;EsPfmwcp$lU^8rM}O!v$k^nMn?s>~Da~Q_?P{)dc6m~KedR692j!YM0Km{$ zanDW4=40?I#6B`_Pa zAwH%Fbb2xz3n@%^G9L1DxHSLTED1_NQnCSH3#x!rv74VcCouu^jrd>vKNu>fm8=Se zu5d${qU3B9QvChg&6jWg>mgA8f8wCEuy28Vzc=?fYDs*^(X~o8?kZnKD{A?)NIBuV za%SQ3*RB8O{_xg))G7tA#FhwhB<6=UG`qRv`PQF`RyvM0MMbLi75~YEmVH*Zg~q|75Mxp=OVXo>j^3Pd{pKe~V{ZXocu`M%m96 zbi$I4y#KFP=YMQ)-9Y@W+dTiL?v1?Xe_a&#kMIt6w72o|p-$bxYyran=}k$3Ys}K^ z_3rEwnZ>p-V0B)R?I$CWDa&76*b}$aFSB;(R1=E!5lk&X~@j>)3>T35Hd3Cps$d zvdN1!@b*`o2>AH81MG#owJF8|OAHH_;B6Gsl^_45FQxXdP z&WcrE4BSSSXhQ+EtUBir?agLQ%B`D(|5RsEsIIyVC9qw!wxJz8Q9nrmvvi9MZf_u( ztsTE-KHd#OxH7!@LDa){C3smr8noX$l>{y{7TMMG)K1u*X5*&~%3$o043DIgG@zXP zsr79>CyD2ej~RcF8f+n6Z)auN!f6V4a4Cw(okGL}ui2*BSz0z53xN~<3}Z_ujH%J^ zylceyEdhwUtvq99RG4L`A$3_D*qQF&G8|LN$!_AqRxVWZGbSOL6CE_iJnV;GPWpN~ zPcL`(#K76B`ZeaKAl_97>=WD?Ob_$qYp#m69z6{bs$UOQ=RWW8fT|0bQp<8o>xkBL zle%*?u(J7)A{e|LN2puMBi!e8E(W^G@Brh`(t6fMvM4h>efU7Ts^T7-H?m0Ht3+>B zhU5jo=s21BYQ%d`jN~WrnfORN?TwF)Qwal+p}4RJhN%<1ULIfu*<~rUmT#zvlIpLE zwACSas}!fA4H)=17o0wln2qOi06ek+7bI4!fiycM9FX1=8;`$Jg)&H2!{UkYQVWx^ zvl4*oB3ZLhvk5dxQmZ(O8Z9j2auo2sS&tx0G)Gu_5GhmxFt(k<+LOxMknM-I?_1*y zETydhjo&`zmzMfpY+$zB{`zM-wT`2e&k-}@z9cd=$yltTIbEcIQnk{NE(_*ALvBq1 z4QDANwvJp5WlrpgxX0pI3hI`4=}uj_3NS+d9!kqihN46-xV<1$;qab< zv*h(n8_+bz;HoL7b1FVhMwE5%#(R8gG-GMcJo&(IJgw*g&!hUeqjS} zhcBu&8x!Yov+DN}3Mc!KG(hwjIL=-E{g-wvOLM-PlKvLM)U{ynJnK*Cme*TsyIK9Lpbq>a~tM?(>sLg zP~lXhQZU7_Gt^_Pm(eHheq}DXuBhcHe`GYOiT-0QgWpisO}Hd9_#4jLuQhq7q&%S` z^PDe+=bKZy;ah|c6`&zIlS5`7dKbUz!8KN$pg!P5%aPl>)HH@e_odl4O^A&LY6R+# z>kLm=mZG*E``Sz{aQ^*5b#I=FcY<9OvrF;28E{}LLKld%^alI+d4T)X84(^5vx&-F z`tU1k4!+3c8dsGLKsn$kOZ9Um?Gz_2i%NDO7sTT6F1FyK5UNN0PPcY>%hO{xa zwmFUAa6fL7d{B_FT>3!{hOb2zjv$==RqGI#43#&gYs!m%3L5JjxS^f!!id@XjDVjn zD7zpv_kFWu_kUUNKjx=YRmhCdTntHI>A)?$KQ$oD(C&Z~ZPb>m-v3cy7%&_cHb@0y zYOlLUfCmC&xmMF_S#c`Xr66cfv1BPmVPye;i;0(J=-NaOU9n$#vxw6W$7n1+LkUNn zH0b@9a8mya3`b{Gj#xzXkKG4XUf+#$yejwIpO4HGWg+qp&6Dl6-~>O`bnPGAe<9{p z=jENM(Qx31DmjGW>wG#RD4SmmsX2z-^shG(eDd6jjqVWjU!i_r_M4NY49m%= zrNKNK>_l?h7h(7#+)X&(HH{_wFni9|FvcHJZ(e?PJ`WYOu+>Dmylk;%IaR%ebl8f52LG z&Dv-;VT80L&~qA({D8AgjxY9V>#Xu#I}Wge=ytjXGuGitz7e{>0IvufT6bsjaSheZ z^fqPFD)4iKbaMStY7b6dMh>%nGH!u>1I_w7i$S7b zLEEvyj1kDI2}MVk6uqMarjSXS*4+7UaGHtrt8Z<`|6%M);Gz7!|7VPSCq}YlElaj+ z*>}oPOc=Z8u|z~!N@bfFYm~;CN~KK{C0bNSr9{b^5|XuqWJxLUzt5mgPkp|h|L^J5 z%$euD@44rmd+#~tp8L%3FHdr0Q`3_jn|rUo7haLHAyL;+EY+amu=r;b=Y#G;;y(vh z1*z{nB+`{mobyS_h~Z1cynj(NWtwWTk&FWGSGj7|-u2dLU%W}>bB%#J()-35t*sm_ zi`p%t`ZvR=D6rEh#~nkjJ&ack^ITT&V|c~2N16O`fweRFsYEbiES(7o?5Xm+Z<84l zMy{JN$4**5;x3owMdr^J8CW&E^Sximy+wf^?R)slM8jU`mhd(s-}O#cl0R^5YqD?{ z^q=Fee=s8W2?gFwR2PnM>>O=K?#8i|j1*SPCD6%>MstsC3%&8htUn3`Zsyu{7My=VK30;;;uhHP&L&qDX-xOK)q&q?j|B@M)M1n1nM`__1! zy?e9kLhU*f=lOy|A=DnT#xFeDw$xMC?v?rV^ZmHizu|6;$Lb5GHsqne4zE7d{-vcBL*3Ifc&;K11`1Rn;{Yn>@Y-CViMa+2TyFl{p{ZDppyq8R{9Dm{9T>pkx zmv$5Xx^$AWT-CM^Uan57R^3{Jjd?;qeL`*41Ra){E6nmZf-2>{u zY672ed+tn{Z}iUnAoJ|5kie>=Pdpi-uRXz`z*h{Di}f}OZm-~PKkRh%T|yQ!Q@qZm z9h+{I>P3rLz4|3Yam_Sw%*<3AM z=w{@r4+ni<=+R1t4m-jR>o;l~6T&?bwcTLcQxTZo&_%0)O00<0%iJ8VkejR8k|Ar) z?{d2|Yh70Lg%_qfL{21WJW2j#h|gcGR^m8SQhb`s)7g#>xyZd()_`zBHE;Ux?CYfO z0pzfuo~VgYbJCo*$gQ9FOA?TzehcQa4f;4az{z>M;PHw6k3R%jnLB0OzfX^F-RWvh zIV<^%!+M`@0gCe>qM<6(K-e;Irh;#}G;uvaX8a!idh@zl$xingw0EP=(3A%|R{O8{ zbi{&D;KC}Kln2*^N1PaPpMLfdw!EcsGHVxF=+z%vG>`9uQgUrap58n<`z@e0@w+zV z`u%{(OD(rGr?OCTSTaXH(mm9&Hf`a{(W~ZW{9m#+w!hTbpw!X7{$rso)&m8GxfGyH zTV74ZC*1O%S=g37UEkWbEjF$D^QD2{UPJvv6u2;>{87x63De+Bsk7&zTUNV;h)UHg zp3JWLb~qrLz7PGxPz7hY=iDW8op~8inGdG!c*_BNZ!P==zP%XQhDt? z9IP$fs-v&WZc4T6k?4^n*4^H*sy-lO>UCcLN{r$AnqT*YWLGhMaY&tZ^ry%19N2LA zX34cgNMwid`!ncBf8#N&)73vJi_UC{xMAOkA$MJS+0$clVpyU<;PmFfKb}swjXBgI zBrKDDILS-WQ{;;pFJrUH`<~F~8>&$U*4SNXL5Y#SwjDAm`)s3P=A#xT z_wgkT1LyGl$L5X+XP+kJd)}VX6RnvHta*C-Xhk;jAPO9MD7L0)GUn&kzNua2xhF!x2aU!=2VcjF4rJUgg@0&Aoytr_rF`2W!Ols0`v5-ahhUb3I3qs&_S+DBsNt=w;2n^BzUvW9Q%ahFTLTAQQ5 z8e>HZ2j^we9akxKRALl1SQbb>e)Bn`O~?8H|xrZ@J(5*qhB_wQ<3T!8dIB-9BRaRf&&v=3w{ispdyV zz?G_De9Si$*k5bg5k^0B)`uwDPUd5(b!53WTVhJw>`-!S?6g){MeWK@V&I+KGkkoS zUhs{}l=-kw(5$!F2Fn*VzkAUo$N2klv;J_u(Brvk^0?DoajUPYrt9eMNjuznwW0cl zC6C%9rwrozem|iQqk5-fv|G5nil?Zr7j=S1NmdcJ-tRMP4Zc1qB|nIxwSd7;a9-&C z*EU?Rz8A30mSdp#@YO^8;y<7hic#jz*H~pGg!zQHo<^e$hmzKan}~d@h$~9{cCMx{ z}NQ zdWbv7Ol{rH!AFsW$HwI+ladxV^USaDjGGjH*t@~+%rg{g-q*&r3wliMY}{pVcc(_@ z{_hVkF=w0-)fYR4QU?80tNyli`B$p)ULX5bTatRP*s^l*(r4=zM@xjh#TYc5I!YPd zrify{i^}hyxUPO9Q8Ra3szGR>B(2SlVU`o)=UcXE?3*$t3Y;0o5w;)u)g3oK|EaxT z|2hS>r(ZFj&$l}7FlZ=jOh=z!O#5uuFuDEx$L2TYA7Yx-@*iz%S#O$$YY?!(o@xqs zz756sThDj4sek}O=99S|n}@qjp0=+VZ7`PFR4SrY)@N@qg90ZprfD-|mGLNkEYi8! z_riGL+T1m}mh)*j-0z{6kD}4G?wt75#`yBvVz=n^Pw0KMt$UjBrlj4GdG|uPQi?`v z2s-;F-_>b@WwLzMYOr2+!+6R%jRhCSd))ryiqQp=km>4|FY!zK(C>7am zxyijX;%%Xx=_OMIw~Ch8Al_CKm}AuqKj-zN!Guo}DH z2}gki1E0OW+jSX_D;O>G7c{(beo`Vw$E;a%E!TQ?wG%OiP+;#J!cg9}Pe~8Ar94%A z^0Zi4QlSn*I#qt*MfPTCx~(=Suyk3MIGx)oCO*-mut*iX+ZA-i#l#RUxr)c@6jQbf zd85FGCv&flxXZfBX%X&@?3%gYqZv>#cW>;f%QJB!;8X&aVq;Vlvs-&z&FC$P<@J2{ zGI}3AwRSk@U+KFpa(mz=-Xrn@d?+xa9ZP)LUq{#>#>yTPETKQJ?fsEkIvEG#i0#*! zPxYa{p(~kq*hRtZ!V7k1_q~ZK{@PU2>bPiW8Od$QvB9pp)yB|EEP>U$R^_bVsp=Y*UEie2FHc%O=NzumjNY*MfH3Q-aB!ff++FEF+3sgNr1u@rR|5``o1xI zpmm-FoeP=?fAm>m_3?LGIL4k;GF5gl6@SmaysyO69wWX@r8y)KEeErX$79P`rOMNp zA8Wvat&Lla!gj;4Uk*AG!`k1oa@<47aacjjJ!9~!caY|O=hx@OOU`^ht2?m4Lg^+s zdd?^4qz9Vyspna_r4Q#APBqBKQ4HQz-Kx0|{8T>KpKeZZUxUUUDc83(X6pnOGw}*L zoIJfW9=J>LR6R7(5Ug)&G|kRAKeG!Z#}D;x-=6)Y=@W9-pHvpy6%7gS7v;Z6r|a1k zajK%w)aSQ75n7~yFWbdl9lv{IY}<9cuGLJQvM-(vPLu5|S$?pIvUHwAFQ1D)rzo7W zb4;6qYzfyhr9;ZM_}Y}4FOqTm;tjc5&Tjl;$0K{=un^O!TysqEvtDA_H^zw7n1@0M z(snf)9o|r_TfQJxAJq$@ZHjwuf~J6C+Tv@qjdjipSM^xvA{$Kv_NQnXm)kIiE&B=o zJ@r1$<*Z+?TsXYwK4>;-9&`S3YPV(Ez(?|}bB;;|zq=~sP~X+Ex;D?0f_-u_-D1YU zUsu>(FHiS{>f82mv0J(cW8+9@L21lb;imDBUV=(e5_oGtGYfuhTu38>tT;Cfh2Rp19QY zguL2nSgq=%CC4SRJAPb|^-*cQC@t*r?!w7@=#ArYJ}YTD{brP@0aCL%>%nOOFjPLXH4HG74boN3%BX?^EF9_tHMy=wU+lA>LoWRd8L$F zwGN!AUjNivEd?Z`BYI1P#AeoJFFB^aq(5+rCsMLh`oYg01kNYNkThAF*UNV2SWBng+>mUZ}XYzWFgXoKKwY}n0!XM%AP*xK&?qvDTPpVdIo~!qEO{z55 z&CX0vUQE057;4$W=p}!hT6<{WM|n?&;Qf?Jb^Ws$Q$cCvm1d8JKOBtgBw?pfQeVj9 zyni=U;La;3c(eZ3=i|3J{0)o*{T26(x0W$74Wct#TwWhHuRD5l)73nG+YVKi%~`Vs zo&J|E(Xl<7^?4C@UmC?3p5Jk-rTOmF*_XQpd{a*GYQ;$H8sQEaJvlqSYImCfI^WlJ z=yD-!mR7nmmaFgPO!7PB?;V#PMe@-_dwLw=-<6LR<4VP@*2b>3Ep=*VKh)`Fn~mI* z8VeApm~x4$4Sx0bAbR5#UJ&nOgXdW&ie=pBC)K=W{N#6y56rcV`B&d-@~irx_ur`< zxvnQKJiU%z@7(A_4cUBzu#VTt|MOe9gs&gWr)IyRIv6B${oHVyYrRtND~>lG4k#;r zR0z`SFg_Ku_`Wh$Wd@y461C`WGdiXq;H_Ac5qwcD_d)AyIrqKH#Q>X5xw(3!UKD4J z_RRfmJoaQz0UN%;XUPC2%Bho0|EE926kGm?m|#n0NTI#|PZqlsCQo`PHZiTj(LsXRZCcShTj9Dc~W6b z6>Iz)JLfr}`14q0(MMa$C(w`M*>epJe0Xj#kv6%Hk#O*i(cC;EuJh7P1!bKVROW4~ z(BHfn5wFLUJhvI*UR{l0`g-71QjR}7oHLV?z)?-<%WX77iP4>Rw0-2&Wd^EOM@B0T zfk~kL!>00puMoj z|1V*tEYr^m$Ll5yzBfKnX*>R-X3ed!9Wr6}Wwhfmj(o6Mh5q$0(G;GrvzH|-K9odn z%M%^zD{T(1PJJ?bxN5fW*?mjBVwB{=jsY(TUOAb{y7X28AIr_+8y!|ldA-I9_1H!5 zyqMqqhn?K&dDqb6=(O^+%?irbA-Ep3Dc<;hJm!1vzxX1>xZ8vjVoA74x8MwZ_`3;hL?7MPt3LjDcie)d2mZ=D z^zvrz6Lu_VqF74QzMTA&|6{!=TkGb<_Tze4@`COcq(a0{{g>VAnNQjowMv=o#Kwit zkfG@Z-}iPDun1T%9?^e40-dezNZ^>p2Idrb+`gpm8wykubmU<3Orp}$lJE6~I7J9FzB!n2=k&L{Yb zd_#fvpXzxuq1G+g8#JnZhy#%2M?72}b@lIoH zZEKB;TZ8hpGesrEc{w@H6_rq&Cxoq-SbOh{9L9QYUnm~=8Y=VIVRiUf{iy>D;h9Q= z=O}Pe$9=c(1FD5#mvov&U7hbh=h@evJ{Ksez%|!@@-00&FZ9Mu_T9Ng*LSwEe%n|Q z>qQ^*{Mg(?vFOT+uj$m}yibSXymo$lmugyB`g!t(bixI}#_>Ieifu-6_o)P#X|J;c zPZIwX9Zt>f(o*X5GurUJ{YYWNRm0sOCx2Y65`Ey&w3EDH2c>AK#_!o6eFefkUM8J& zpBjIL!~|?)pRuz1{;)Jm;mouC+uzw|e?>}PMEH(a9{gbU;H8g%H#4_n=3#GRl(2NB zES_>W>OX@3cc(@a-cDw+GAj;x}6K)c?@)FU4N= zTx?D~e7Da~F=X`lTN4y#e3M-AhZEuvng_ULby+21>wSFmK0SMJq_%#FYcbtv%W z)Sek_BbT3c(IYZzvl^cSEX4L7b5cAr#e0`3=VI^z1#aJFw#Yne%+Q@Y|0$tbxL_Up za{88=Um0ZBqVUqq?hga=e8!^)wi1lIQadVn_|g!)rbjpPmJH_;VPDUhy|yq4M4O|> z?%V7{gCN2iR{HM!nc(1|X!NG*2Xjlx^SJeJm9uJ|+4bzptOhQux9m$I{H$I@7`H)AC^6i8 zwtg)ZV4+)pMkh`k59O7kzrS%NQ7U(vT8X+!{TO;-tKHRmHt(KZT!Uiro6l;K$t>?|S{t2s+HL zJ+l4BdtFtQ&r;B#?;$_eyFcZz>^qvV-cwmZVMEc^0hAd2MfwZp!$as?t$79oHs#(- z96DLm>+M z?NRoQyV8zsJPc0=UoW-_1{roY73^h+Hf`)yF);Q*pAps#s;}CKtE&bFDyNcz1G+j| zMz|V9Sh0gdRj)vYwU<$xa|gI1_R_`i4NmTkKWF#x$Q$zg(?hF{y60;7alfDG5&qkN zelOIu>z7}jL$DqU$=e+y_nYHiyyM(@Y8J^^h^ z8=WeXp5DJCz5i{%xo3H8Ql~x&s1qJ`-e?xrOKo<$uZrTl`-99keL9by5TlN5#D$MB zJUoFJ{CLqbx4$2s@N^lBL4kP=jBy>~DOy{Xw_h(?qJ=s4P1A9CW#K*%Lbg!Mz;&m; zRr2|MSDpX-m2$(URbzM8Se_7Q?d09mvLS75+tq|J?w&prd$Y5bF*|u&H3jReSKsvH z8Tqnv&xw=G?<_K}eJdk{aIy9ZB*6w zp)J`krO`05)+!3i%VAJ|+xJUXHX-7$bGI2KPh%ptCbSI|&*|#2-peYQnqM?%KhSh^ zdvf(ee18bT4LIroe~aKjY4PPve!lki;R6zUS*GioHV~2+2m!a;0@W2e65QhlF?Zgx zIH2cVNfvu0$3{NoDD{rGM8dB5Jlm+NwMVtBGCm84h1M6KA1J=A+z=JIU2$PmQ%0-% z;po=Lg71qP6`t(cbeCdk z(F4-{wtNUH{GxrW$gAs&xm96~ZcbxmhmT%=rnMktu~Q4}J+JS&QV114)OQllbJ=o# zqvmbj5XN~KTsQmP#?Fhw=h;zm$g(J1Qh#js^PQbhvBt;2eCOh%q;$DKlRkdyGD>PU zddhw3?6qyVDf)un`{lrEtnpMw)cdENdpOeWgybF-ws1T`o6%^=?e}bIyYOOoruSG9 z-N9?cRASku@4H`0-yP2V(luXrkM@TIma2hyf|AU}o3Z)v&7cSlHxql^x1%vu_}3dI ztOSRim7X;?e53r%A4hF@-#&he!^of6+@EY-*v?#kGpzvDDIN%4=V4M`Y4R)6wKN-1 z4b9DlS(TRbUB{&QnD9#RB$(ylWUbZF1JKawa z@n#%c^%`dnWF2z!Y?FF5IVO(+M;k{o)bT&KJWto@dV;Fp+mCa7XcV-5Tar)ZsbraW1il?A z^+D#ukRNZRMYL+L1G$<94VN_z$3kBw3VgTlC!5R`rF-og^cZl*Hl%o*WJ@%wHMp?gbXSi} zE4}7#50UU~;l!)X%13)X{+x-Dxp&GbCPRk&miZkUZ^f65BjOz>_H($5%Q*oSee70? zFZ#-64NhJ^0ym!#$&imefje@q5p6`vth^4|o)&xLt8I1G=%mohpxPduC?$;sg3-6= zx~+cb2R?hU1)6W*xz)^yU#>6HRx-&`p-$Zj!yKZVsDfG4{zDtUMIoa z3c&*>PfZOCDp~h(Z=AQck~P=x&qB#8G^oDo=KDJi*|+q)?OnGHNpemQJGYK~Fwr8Rb3RsJ{X8Wc~(|R^< zab!F$uCmEkQJC|?G0~fkSzB0Mu?nL&dt3TtVkV9ESnWD(yF2@|qz(9!(|fz_l)XAu z<1sClqlE%%%}0K_2VH)Yc*WA>M;t3T8!$O+9kI^fNpuk%PIwRaF)1ZBE zA|XEeRZ?cJDBZepkzs2%`lteP34dU1EJ zW={K2(1JdQuun>x{@HKSt*1QwSm;6EJ7uYov&n(lxQoe}#{z4r`BB0U9u9mLdDWq; z&uvyrIZ8Ym{O;jdq7u8q7ZnxU&56Z7zMYuLBw!oiJ)@`a>g}%f-TtG&L50Hbg*cWR z^@vBDcF%%PtnIT8oV;^6<1xTfFwJ;od8HVwa@pOLZ%4gXjh$i>E#u(rzt^ zs=J`P+V|lvueKZjp;}U%lK%3=sf9OeZr^B}jiVh#^vAel(ojc-MnHqC7ac9z@O$py z|MMgX!*Uz(JIya0MKu(2f6L;v^gUM(8-6JKASow^H$BNfcH4V4OS{IH-|$2Q3fw%^ zwB`PuGUFWQ)Yx1F4g7{UBSVgmZxgtLZM#4AG-{y03r8OpN=sCEOBAQE?3(q}d}*+bgqFSXDIFO#v4 zbfw8=)mOql<*TH-6AFk5`Wu8hhn^RunK4hDLkIib zi&bo8eB=6*Ox+^%{%6#}+~}UdV)yr}gG2MXZXYbG(Yjo5rH!u#rjY4R9F0YF(C+Ow z$a8)So7}!XQ{&QP3JYs$ii);l{>AeFvFx)Pv42}l$*XlCt-M#c$?BWWZa7}x zT)Ig`{1X?OK*9K*p6KwPVvXemk-%Af9R6U*JtM7~9$&3Fe$4*R7`UZS&qTOyfJV=q zC-a32H4Nax)#EZpbQ&A0yyG%`48(X)U{fWx zmme|J_Peu3*p41kyQ}^NcVf=_`*fDU`_jfISVk0>V_U6_WszLP`Hucm8nN?NiY&4| z>g+M*Gvn^ra<`})JviZ)Q)Ye+1qt0rZ+U&ZP|LzNw{iH6Zi-;X#|4*S#$*8$=VAe8 zi8-VERXW{aQl~8zUguZ`OTN1IhOKo2lp6Fb6fMU6!s{bX-e`q5Y<`i_P`D@1b=2yO zS)2w}b}|dJvp^^b#d$Wuevea*yVB7KWyhyhnd=C(b0@k8Hr| zGq!84K6PZwn`wUE8r}mVSHKryN7K3sM9yi16HuE+y--OzCwyz&9EV?%lg5v2KMI&2 z@`hYr*GufJ-bC;-6wC2Cs)ec|ej%NNZ%*;qr_1$3#T8_dRu?;_=gvKtP}(}<&b1K* z?l-WRX1xB*he<#5N+XuyKELKu#|ai3qbx4-`m2ki92EFu^hasmxhIah>)CG&rQx7L z&CMYD9(A--HWz=HV|)h+T*DS7VZCq|_iW?cv&CU#x2HSm-gD?$J?qq!5cXYEdyN9e zhMw#!UJN}u`=HyfuGYIU&FU~kz@AXR>6!KVqeplK3T$Q5N-|zxewd`QA#hWgTGNv) zJM3RFWnc3t?4s+xkVrs*ckkAnA*eZ?gOc$CU1mN(-@(I1|HaC1-&b=tMsG z6W?1#X~Hb4=RLA=zLPWe&L1pRtsTz{s(Rw=-;~v$I6HNiIgiwT`|^D&`K`g6;d--^ z1LL6=Nk#Ywue8Cv6C1>qM`v+T@IQZT9)Yc3FRSnASpQzKrhy2xR-v=68VQZDcC~(v~!<8`2cwJm<^#0&cGNGaA;)!*0 z8}aZBXY#HgyNf6=BtCC-h~>S&?&DS4L(P&Ov2qOROl@N4zZl?0IybXM5Cz7o=bz5m zc{ZYG9zIg3y0sTOZawJv`QzX@ z^^*2lt0S$m?@^oy4+7m5ReeD9T|svC4OU zy((QeB)q@as}==rc)9oNvwnG512!Sw5?)Fi5AUjj%(Xh)Mg?^H_t`Ai{_O{@xkkSV z>~|LK7d(DcLo_S9sH8EuS8kyp;M(D}-zx+=QS3k6|1m~R*`LMLLScaDnD(5>Q+cY@ zs~a!Rq(QeQQv>ajJhy-Ii0)y(EtN8%6PTOttfe*=7f}@^F#FT*E_Yf0IvsrEi`tsL z&e?B=7Vl{_r>wi=SUz#?t7w&Qcvn-0w35IiN{p85XxHibqM^3oVKJL&yFQOnx>xo` znaekHf7|6ipYk0A4t4m1Yh>PN_fW#+)R*{-lv~ z#8qC`yy8zjsY`(-P2y|O;&sKB^j>Zj zX!J{8!+E-Q*(GJV(X+bvW4G_oNli_YRO8Gyk+B&_i4qv}L zcP`i1luv>$|G`W(;AcC{4zsHD||@b267b9~;E*-{ytO}<4fo|Zq_yXNxzA=;5fR&Fly+{rzgyYtoeqUww{K}uc5$|oO4Imi?KgP z3;m0&Sv~xw%gj#pSj|AzwWME(3z_&>C}E#f&zDZcjweRc&_3N zv5LE?eWMo9$qw3^FuO*ud#}$BM+n+(!*63AnT13-WWT!WVrnMe*tXB~puv{3{i2+L z6Wm?5B>O#xmkwd{ON&(#uu(f$J||a zXN2FDk<4p*eE-O|1xBPv)nT6kONMzx z7-eG8e?G)1fJg(boZvp;E$0%I#d|$!>nIh@f+CZ8;G|-ykoL;4Oe6Q`d6qsvB*>5e z(Q9zSnD<0ab?BWi$$L*eMTG~(BoRs8MGSfO07+aX`Cz(TfNUP%CRHvuve zkUd`G`hYAWdV2nJUE;zAW8Z?3m>1O;P{Iqy_)@`OK&k*T`}Ij9KsqhsB`ZREKvNGv z2||LZA%Ij|6Kw-XDj-#Khx`C}4Uih9L;QejSgy+W^DT}K#(W1QEFPE2L5UO~SK~Pl zF577!4Hz>^gfTNP-K?W4#uX7!jl>UQ8EB=pFqRX>X*#+>hITMkD4hy(rqe!<(s9)3 zC8W{{(geopYe4ic=VM1#7*|KbQTh4F1V{`EDmyO0J(l1Qojt;o`bTNhZ_H9@%*GLB z@0Kf{TrLLkVlN}bT7M?;#r=}BVeS~osRW+D#6-{(CGC`FZ+qXDho1sU4 z(|M-#MC$ymH}s>f9J=OAb`K3VxVhDH=TX7%f{{dK#5qt6f^Z~z7-vp}xlP-9#o5!-#Szj$)pStg=t{w+ zQ$4|S@)V=GlI_U^Dul%%&6DDIU|c?tLd8LA@c`s%i(FJ&Fle5tFs_}PkN`7UA$mx+ zwROz^FG~gE2^3HO#tz1POF%F{i?$FpD-)@XXq7{i0yC*2lmJ5Qq^Si+4%8Ccw0#5r z=YlS_j^=lpsxOHszhbH6{b&xSvDZ8XTmJbNZTYkPZ9+vfP$rF5Fjq-o6yP36SnEOw&urd zm2+&fY%@TwX@fxj+aUa-1JJ)XV;+8(0ZRl!1}w)RGSnvoMglyBmH=kD6c$;O$WZ=t z^^6S;8NbSV{Z6dST1b;?f}7j(-1n>4bv%~%JfC=XcwK#Rax%~3INO9mLp8{TL$k;?6%sXUSfogF$ z95U2k+SnmV6{FgE!VCozm?aU>CZKOpl9G~OmNMkyp%wmk@-K=HW|*h-SGtBta;d+| zi<}gPhv-4Osdz{VY1tGD(|-dBXJkrANuf;{WF{K%bZ^3jz<`JV)TwEN4h1uwl8^{1HbBbG@0KYHDM0_033RsSwf@D6J zv6V+(BMJ%|S#ptVfKQh?4($=EpX=CdM4YdpAco+~Z?-ZUO&TABq` z-Z4jMJkgz4krDKkN$$UUi*%3H+u!SW(CYjT<}jlL#dE0+$pUnbDU*h7vPdV>^l5?a z)lzpnDJ%T(6fiYBk*OMoBPS%eOlAPJ>XAHw!kD@dPU*JLT0sc>EE_NfVCLvi2zs87 zSUgrAX6i%MN4hN-2&yd!3=OT}j;eEeX$?d4$gEpl0m>`w#V$t(v^T78Qi`+nIS190 z-V5#VTV^wiM~~w9fNf@WCEB8pzt>u#t4q!KTmdoxAY(%x4p%yjGuKMa>H=L%&Aq6&z%Dc2N(@x(Z{BSJ$iDoVnNSN@wxR^=jR6`&qNBGFJ-B z?Q5pk5B9<`lwKCwFGY6VF*v5iXV!j7vZ<+0AP8_Xhe+U6nYJQ5sZh=TT#P_W#8f%O z5-p7FP5$ok${hxX0cPu10n>ijai!?*cPzw61A79C2(x6+EN2`T7+4SseMSrx9T}T} z*gy$n@*7jdfE2)HdcrIZfmKR|*<&4DGk`VBu!UJ#DHNE)0<1i0PWGQmISvoAG6SDO z=SiX1!z@36ljeQ|>`1zUEzG)~W=mI=>K_3CZB??m&}NSopV|P_kBGGlPWZ1?xdMtu zbEE?IMRoXP8o;t+%_2f{BzxL@m=&0}m72?LTx>Zw0T3*xNnR<&16u?BAwf)R&lI6V zsQ>B7oexX>=QWR9&X&J4>0NskFZ0F4=8GiwTla`kS-++O*~PHPP%cgW^C&YFkB8Y5 zXgwXK>-{%_x6&R^Cz~S;XvxQT{XdKfDPgJezZ<@!Wy43II)KFl4BtP?J$|JDeC%P@ zzM;{vXxEl)A;!_7@zXsxzM8LPvZAhHtWWD6-I0z*I>h$$-#TQAOg?Bajt^%0OoZ7+ z;$V(N#AndFE*UsXw)y{i)WR5Zy|RB2c4frA7m-#{6*Z*X0^Z&QNN}Z9uq{N^e1> zx673nEohb0`={fUmM#c^5D&Ui3G#$F+2UYM-6fTRAeKTP$02c7I?_!LiBPa)l17{+ zSSjfgf-TS>O~tgJ6I!I;p|wcAac^kNY-qQ9wA{>Z{)KD@Mu>#?B}gn0>j69zB@qkk znHb`{*2ZD+30NdzT?$x10|X$`c}Oe{8xM1OJGy2fUJu0B>i>)iaDbdOv@Jk7V!S{U zX&9G)4rJ7{-d&R)=`%Z{#D5D5JuOEaAy2uq{^7ngus%%Bkf1QwJF4~ZpU zmp)}@WPuuxA#fyEbt)39ic#W`dR&@II}i1xhJW4Oy4>!03XK7@2!hsRJTN!!5DkJJ zaRJ90hdo5=5rvF{3_&mmb0v|N?jW&YG8mTSd6$HTNC`kg`SD1I7zf}r;A6ZUEh;7@ zVKZ%kTvSh2nsw&tCdS#t0d;1^V>784*mSU6fVrv>PjK=C=*7yl#-kl3Lm9b|*aQ z0OfI$aWHok(R=IW$Ph5^!Ny1eq6ZTgS+lf3AW^U+%F-PC4aBno`t6?h^1X$#K4H6e zd7EIEg)pob+;T2t)v|x~+8Msj*IQeAcc_nVsJ6Csn3pp1FOWErG)G+|+NY&gkXQkq zNElmsF+&V9Hwk0Nj9~`<>9{e>SY}K-C`L-?kh~1N7>1jUTMVRTmw?QM7%}7?!p?9x zaRV42A8A~?IK~s!8<*MnfAlbpdDIOT5g|KPUE)(HN=Q55f}^* zZ3$0erqy4$51OY3&0v6t-~!@+3y~LGG(19ZBOiZ#S|-Jil0UDdwrRBuX?+0Q$Iu%B z80f(-Fg>8aCj^X;$OU?dyon(%hRDl57uFC6hh5@~@Sw3{CM^U0;Yw?j8_^OyGvG&K zhTNm4FQNE21FL)d|Rp01|^SnUJYEB&811T}7-tl9ifvMTDW%^8BX~%~$?ch|lEE^o@knUTV+q zpQbLf^S6ch41w%U&fA-w7m&f`P{Q2{hS_@ju2^&2-CZLt*4p>n!Bn^l3=XWXp z;8D3WDG=rVy8gdBkf;D9$*-y_1edYlub%$ix)>E&{O_7zmH-bh?F!MWQ&$9`;3+ty zA0Qxu){+F%v3QU@Aanbzgg_J?0hmq$I8%b7>u;9JXvLb@QFpFD7lHTv#f%JzrQ>KL zZb!4xv_^pAN~cnA=@cHAE(tXG8^d4bkxZt`NGJ2B$J6r(fV>+511j-0xH5E}=E+fA z{Lf(mdnkyW9Pjd-N(QMHIihE}XQpR5%s?c9*+)ym4EfOlmkeP00TRXeKL^j{dqy0M zB}AX)nFTYbBOHPL4ehcMNg1>?1Q=5YF5ffbmzvIk>E{s8A_>*X%9#H4&Wz8(XOa?d zF#P}s^b%I_!}PU8&;k03L=Z7QAREJUAjA1zTxg4d8>R=FU1$+cO2>i$peY=Df@}au z9|lSg0%#Ye*Q7$MtpCLig8@?xraS5AiiqJ!qzA(T(}Td0erx*DZ7eCB#te)v*xsYY zm3L*Lcni}1fT01zUoLw~nEvQ;Z>ZkSEAQ7YIa8z%BvgPm{cU1Vy$vF6MuPG8B!Dg6 zlCwn>-^g;6r`7*e9Pd5;6_);!C(Iz64#EO4JxGiPW{@Ph!VG-mIGBzPbPh{}>0l6f zfz59O=!hQ7z)G8YdY%-0J&>6LGdjx_X0WAF^x|oi|EZfvg>hhkfT)gY3#OeOln(%x zh^}OqVK0=QxzfPWf`AzkDKMQSvf@BYX$NNHX>jZTC1UNev9$ZP>4*#%M^`-%nK1Y} zE}Zk(xo1b1lLW6A^!5=c>Q15S{wMyq-Yt*SlML#^6P#yWGWZ&ImwbKgwh~7OV^n|5 zsi9@7|DW;13aIK=HJaC0`ULzGa4N~mMYK=gg?5Q8zhjnfEc;=@CI1QD02`zN3GvI| zMsni{i$bk;e8|VffEbjtHUY6^#eDG?2K=R}7)$+k|J%AKvI|I&v zWN#s4Waa=Ma{;;Ti#0exl068>_1qy-fV2aojK!=KAY}k4pMjYHB;sHdCcP*4V5ww4 zDr)jw2c#Y#H+Fdr19B}OHH_YYef8RWKx!(xf8m2g-ve@!gYjoTRsmA~RR|v-5r83S z%oLFO5OPtV8jxE6X-?g22uLwNS`wVt`Ct(%Kw4+&HUM%xAh#KwuH=J-(*bGEBcTXL zFF-mJu=(-9LP%>wkt;wPp#ng{jWSvfZP{n0CXm(49H0CaVbC|Cw7rXb^xWW9tULn z`|U%3OaNrky@T(T2O!x5tHTEil!Lp6)b0iWG7XR^H^t=v=?loizE9Wk!T2i(Ir!2E zkchlTEcUf8g+2$1!FygqI?EuJ*g{lv<+zHA1)!PqXG}#)#-Ogv_K-Fwf z2P4mlbhBse-W))30`jd;9f;FdkcRue%ELk&SL2srX1L=8xif(3hL zK$1Wb{r6HP5l|{ciN|7jU_iqR+^}vbNNzI-(+;C_zyaJ+yX^K5Nf@6Imq36xXh&iR zVi_=lCCC{tBx3EMd|^C4tTm6+^j>K^!5%Uc#v^B1I+>2H@reXTc;#?2SxglGsgm{BMLX5`ISQZqJPHI9%BG9*Aj5YUn`E#(b?_#I}r1-vJ$bWZ%N%!O)qOqbR6R>efSWTb^0&H3g{BA~i25dSE@(;9W(6c-Zz{wf-2eNEbGCm!T zgBi<+WRS-A)v*N7F>nZ(PR%4B$83v&cnB*%b%5wW_L^}wH9ihDVsdoF+9PowNKM5? zM`}0m&@i1h#D!1Gj1nQp%?6o6Vyc$^LCla?`5p=HAYiZfl1pwx`?i*loA7gDAh%i~BVne_v-X zlNHRQ4{rh~d6>zZw!&atcCgH*mlq{!@-D4h$o8+P`}@j8qT^qi4w&gAjX9E!S`!D( z+<^GBRsZ*rhnb$x+6PM?!v4>7yNb4ML&L)1(D0qXe)c=P1AW77Lw9=nLjM0O+<)QD zEVa~2<_$}&EYAQu%xp;J2eTdog0xuy3E{xZ0A}Ss%?CS8j6lKT&i2Qh-ngxCc0C21 z`?GzN?jY7b`i?FI7U7-n|5nb*goT+$m-Goz$Sl=FRge*5Ng=9&BWoerdZqvk|LPeF zk*G=n^LnW$j&@?aH17rRabP~j3J-&`8+`t$&w=t=!#8lpZ=uF3FcNNmXZvEnksS46 zdmQQfe@{~0?b#U)Jod-hTO6RvzfHD(o22ZtNg611NnYx*M3GX_xdKV(?EkF}SPNV1 z%?O?@W`u3X;QX?6SZfE^VZf{>Y10i4 zujhtY@4>94pfmv=4{N8;fQfi2jpTvZ zH==8tJ!mYS0>&HQ(-Sh6yA9#&@gP^h4?x3UXUZuB*x0H9-@3F^6MtL9S&5m6G$1bk za^xZ}lpJsjcO!glE3@AhGNhJprx zjb{f>CV;_8&$fj*^{M|%-sKU?j0Z-Qy^08P+NEdF1j$Gw>(J~0DKP`02Pz|FlQX?J zIF-AgL7_N;%Vat@b7@4z4(7ax97FvjB_~bFAbuX(?Zoz$6%jLj6A{88CqK0bzedtC z9tZ(c33I+mr$sd|XFo9!984W>bWKE@_&QAx$gjss!H3QJ2Pp7 zl0Y&c1mRMo3WPvtQYH|ZQf7vPQ6lCZLnsOX1E}b(xzmzR)H{<Xl^Z#(ZvOa{%F*agC77ebwO zp$AdZ&_Z35vI{1ld%cv~b4m2oL@%s>W?exX23U`6vdKMm`oqvXLAMu1lUa`g#yB~s zJ#O_^v##f*9#n~f@}l0ICajLNtq8-S&GQ#6shl%s{;c`47gba*Tr#&B)Kleb&0~dh z=i}q?&7U>9ddY(M9#7fa*@P(DZ827wNprKDbNNORwNljqpO%{vwGm>&+^~{8ZI<05 z=l5dw$az%k9y!nOtwUQ;8pTM5Tu>UbUPJs^xRj=B5O^bmh=G2V^AAC<0sR~~((KA* zJ>T*p6m|(7sps<;)qK`-yPpu$kt2F?GoX_mRga39z8{cF---(C8cwe5qpy>sug2%!jBt2)MBJG@c-x=mN2lXTd`*2 zrusE!ZQitIeI4ys%}3v{Qn zles-pFPDPUB`%!5$Wk5zWAP3(VKGKhG6I@Ib89M41Z~mX!afyyWAdD}()i9&)@u`= zeXF`1zW1){R@iLVBYWKs?!Hr+1U8sp0auPIzT?4(4-C+rJo?Z|FwZHQRk0Z0t*%(S zxOzdE4~x?Z<`guEcEV8_&hkbGE+DU@9T$){ClwdqBrd?&X_q7y(5L8)!ah}dU)i&~ z>V%G5KoaWcDAxGMV0jPm#^kbm)gsS0jAe5e>x)Q+!=RLoCe4ssQSW7E?CpE`oB4;T zF5i2`{^#F#3tY+BM~8DJpF*n$ybH?~ovt0UOyU&KrS%LU0we-QnH`u&lGe*RI?G2> zPNppAm@Lv@L%mYO`YBIC|m$6TX?aKtqUlby{Nf~A#$Gw;y%_7ViJ8Kw{+O582! z2}P!)0Z;TWt78w7Q!+)9z#u{u+!}^H03idx+#bYwbbzSSoMDnX5bYY%GE8zZy;-Sn z?E=Y{AoaX^0|D1|5O)|VbsK0o_f~wtpaN7L(R*z~?+GG2;L;A#(~$s|0Of0k>FN5u zE>L!$0+|Bk1-?ltX7-abDJPJ*m=ZqyOtloQg&K=#1i0}7ak4_2oDLs*GLMf%BGbKsFF;*gM4~g&aLL zY#>p_{JNU@+I6*cn>@Akp3U_&tJ%g{b9XRhlPMY@7iV#M@FtA`&V?LhaTJ~sZ)*Qe zn<_E+N>;OJeSMksL;}O4XcQRhqcuPu3LA%mO(g#j1rL<3j`_#`e&fkU_b`R?B9&spI=9OMFvj;+Wz+7#82xz#=kt=uYP zg2&ITCaq_1wDAqKA2!sE%q{ElfZ$yX*5{8L66|jpY|(XAw8;}QM*4eAb@=bo}>#$`DQ@gs*nH1?i{CA!Xh?N7)h@ z@Hj=`IV?_!J?yUWU%R>vuh_$ zeDJ=Kfm0qResKJK_i1~N-cc!29H3q^=9&>Vs5cJ2?z$wI;#pZ!bU{L&0O>@>jzj9& z`PP**Zg$HsACo*zZ2H|hZu%Ak2)P$*sfXsIp4C*NBnUD)7L(LEPPKDUk2^qR8ZgS~ zWS8t85W8gmiO07~_ODLtlIALPrPwa}duhA0q)6U3`wuYTuUVL1qQLt9p5t4C^?!^_ zdYx<~RzLwD&;islWVO#AP5}R#h;1>#hy_{9Ry%p)VX< z;0KkLN1<-Otn}-|d}V{a@ke+Tu4gN3SDLFJIiivcdX&n+AMHj4Q!ffa1atCWA|YjD zG?>o@ZTCa0HOT9S>Cm77ex_c<%Aqe}>UHw>_HkUv!qod^#6kYso(>Hd*!(IRE9t$XsBcYOObr6R-JTk%MB#2^zbNFXd6-bqdV4t{RWc_OA9wQ31B> zvy_()V$V9O>JlCMR;_c#(8(T~*1vLP=DWYU{BySrT%x82jJ~`ybjW}jV^BB0P~F0a zIHc)CQ3YQvBZzO{4IRR6Qe9$85K`Qr%4^0@>oZ+Y&*2Z@!XPkvppp&rm@#bNaM5O= za-GS=rJ;(r)f;jZLI;Q+Ym}=X2thuMM+BA1hKCo7Tz2=OKi=pm+qHhj_AmCV9NoHN z;g&BSx#{%65pSOZU8k-o6?$W($$y0Ux>|^K7fr%yjDZpd9my$iQiT%gj&OzOHEiI6 zep0bu7b)s6{o2jGhR452yYs7aZym7t@AG?oJ^#x7L&jZqPfN{!zrXOzt@q}7121xP z0-k~Eu1$+ORGiBVslu>pN^y8NgKOC1XzMeY3rlvzNpbGgij@C^_dX zUcluZOUo)3RERp0a?(JihDV3xs6xe3^Uu*A-2eu;3D#y!KjN?n^zUl%(yHQ<^I=n^ z4qIB)M8Ew^^plK!v)fUpZ14g>l0_k|)AC7p4vcC9DiVsJ!RzCSA@ovnU^PNJWUhY; zDz}oAWQREz|K+5BStPVf(CCLqqmN*qokoAyk6fd#r4`|XLN3E28~g$1TSJy55Mw8% zks?Ft?%9-^FlnQ~sz4ZOtRWxxwZUPO0BtxJ4?5!rgsHP3V0#+DIEi%>QMGh%m1gtD zIoOa4KfUfveaEzfF2co5e1XU1ad<>-|cY~d{6Owj-0E{!u0=M2|F?3)<&V~7{ zi%t1hBm&>oF%cygQtpqjA#VXj&6t}79CS?p9UF27?HZJy0Ehgj0)XTCuyIl$2AOet zNE#j#2_;esG(sNiGQ%GAYZ;1O5ds-GtkoZ)!);oZpgkCHYF!*`m`);IHne}#sSCAA z6qK6IhOLDPX_yPU-#By;hb~ZiL}f$ggyI?qHq;k1#q~qqfwc)x81c;pAu&3s;)7kL zriGMNMY7&Qe@8@u-te1GUikC9)9x8{<$>Qk_2%hw&bYsB$$$x;*DucAa8CZZM~aq2 z$F(|)l$H=iv^9eDVGq(Y9q1>J0V z+c#@L+5CmXu*DgwRC8Y1cPv_5F^?q16^pAyKHZYf6Bp|yVYv9_*Vdl6wx4Mr`2*I~;`p z|IrLaf#@O|F%vTAhMA>5RCL|C@2~xC`AfH&+Gx+S=U!NR{hKG=TE6wGU2l)@I-+C& z)jf!#VZd*d=sV`yHJz9`m{ZI&u6dy{zgMnTOPXRSFpgAZ4Ig;@Z8u(b;&nrBx=y>n zGF+*KSm6~V9oIXuS1PU-I_Cn-(J8Yj#Rw-9 zo>o=KCE2LmWHM2C$=>)02n5;4jeIwPFqqG<01; zl#TqMl}!WL9o1BfIc+qgt_r)j;l%Y|JFf@nNTP@9iFgcG28fbtA$)k!=wK6c=A@xF zs!@r~O0EDx9Q%+Tg=x`-m$uxt-BtVkPp7`+`EK#z?9eIq-TH9$%@anI_SpDJsq3M8 zTQG1jI`U=`a@U|AUD0GJo2ta|*uJiitbxbghu9!H>84;aSxz;IS35}xDw9RF3Ozk6 z<=S&^QIbD~RU^zLmSe9VG#g+ieHC>G<2l`H1Y6OK>O3}fliw4`&xcBS>{Rq<)NsO3 zhxkG*$%5C|Lh7Wx%I26k0};B6k1Xni2sm*H|P;0_e~cy%F45 zI>gtm-4!hy3$*Y)5?xF%)i`mi%dmsVYIDUqRqrU|N* zmtcw&|I_c$(zjY@$rzh9dui34<{jpA*`aRp3d~N+KbIAQLZzOIpnhqzA{49)(c~=t zEzL?zy+n!nE`hx++|dx3Q+y@Of6w-+9oxM`C=^ffZv&w~7DePk2&7hg<6yQ!6b+OAXa>4@;caeh1Rz33a^;sdNW%5YqZP2+K5)Q z?7{(5PoNb)Y!sFNB4aQcDK=Q~uGlsXZsa2p*g(NxRDxbU&_sdYm~$n_8+l-M%v<11 zV1F8-l^%t69fdE@;@AA15E}!rYAjTF8K$Vhil0i1+oe9OjPrGu{s`npkoI_XYi&FC zpdrb<*mF4>JEV!$v1kt~UPpbdW~0Vpu^wq;qXsUm+FqfhZv!=HwvkL;@rTxezmcMZ ztyrjn1qiE6An-@QP*iK%4RacR&l8S$(EF&TrCsg2ge^^yZ0J%P@l8^zoCFxaC@MzB zi|57%(WS%uhBh8O3W5{nH?1(gdFll93h;X&-!{^P!3c+yoQ6?}9TRoOG%eP&b1p5H zk|{L5&}guRC(Xd%m6W6Pgc@1N;=ndxRJFAdOQi$^Vq7*k(2*iO)#z-ekL61|=4f&in+?3KvKs(Js5Twd1nWN!DZ@g~cnCrmo zTz3;#ov0-j-^k+{58BDcP2=)6h~lsZ3vLANpQPNqbNf6|kSYyXP>=@NP)-@wI0u`U z4)!DwgZ+ELOJw0F6v(=y7C>}h>0-}k6WaVlKE#OtHeoH9Bk}X77;Y?c6-;sf?h}Xr zEX~CsKQ>_mh7pFfhQ|5$Sj~icei)0hW0w;bmk5=?DUjNg>w-jktSL+A3Q~^EVhuKQA=(ySV@1U*}YR-V-=t;{2;$klw z4?`?EO*S6%&rDpa03A7hS<1oWC=j`0Br}w zn$$*=E%41QD?hz@UfI&wK%hrw?IfFE=7C5p$>=s!H8M+nYjpQZU=@zX_F76>Nc?fb z!0T_k<_1_`lWrx>b#_Dx6DurefehPd#v1L>0xey%5$qG4k_ME_bIJ(9dceBgX&IQz z0R(CwdtlrU<(3UFu!d;^ozD?E3=|sWh7K*@?W6(_1Y;{750nRP?KhI-2^xtgKnda~Z30d>g0YFCNl~N$1 z4(mWKHBeJaSS*D2A~1__#aF|moBXya98I*WgT&MZLII5NhmAK#XROgwOt$irv8F&V zIjtMeq$Bvq$xA~jke?MqFHJ7?1IB7K91&F`(j);9S7M&Er7Xm+BpO=lkD$ zowsxF?7`n?cPC{$dF0VETIBLpy8!69R&p&p4;q130 ze`_Ig19TDw`ZKxaj%{Ls-5ArO-{RksE2L`jONdPnvx8H;@fs3@&o~F0dIdmGle^>4 zbv(;BGYg!ed4Y!FC&DW7*wokIkt{hD%wx^;4{p7O=hd933O)L)6QIhuzGyL-m6k7F zxM=p0CE6a#_=`!LZbAsq1UXC#E)7QyXl9Zh)o2*U+VTOp8U3(F&#)2Jh!bW}HmyD+ zr87_x#v!M(>HCO$B444?WB#h@XjLeb!=~GaXJgZ@4X|mTrP;JQfG8lO;F~@OivERc z+QATir%WKR%0#`Tnsa;8zyRSxV;Qf7P5TrcMFm^Oru{PrY0B=URX&AHds?J}7*mB8 zz95bw6gb*@g#x!zCQjqgT0pOGAKJ)^LjcIVi z%cgG^%p;p#8{RJKjS5jcn|?uXhuM_r;fM(Pz#vnLs@e2YNG^h2UkV1G5bnX?P9T>7 zBbX3l(;o;m%K}jC<6v{xv@p7n0+C9jkT0|zgcY8zEWn~kKJ5T#fwFOX*$l90qQ}+n zX*D4*5d-UiHhS7pYy}w1ezc!Mxr22CaX3yln=1@4Y{u!NQzBc#HWIGgg!yM7+u4kB zA%74Dn6UcXpwdYTK}5NGD9B!Dt1H-y>xmFF*A$y^faH;+CzrDK8J`0gHmoa3JM`q2 z?DnzO)(#KWeEFAO{mb*olGuH@GsZ5v_`kj?c_td7rb5twR-rIcv4jqixHdJQq_j5g zl^47fK=$S-0;{wZQ`7`Oa>2)J5Ld7QqMg(&F&fElUy!)aiqZH?Mn4j3uD^om59tN1 zJHW3D3oQ!$9sc65TlU2?EO)1W8gqXb;748!=KdNWh)KE`7)YHKQ>N1hd$3Y~0*Nx$ zg?Cdv-Qc@WOA7{4a`%nU^j8KeV87TV)bU_>+(Mm+c9L#B7{pIv;vyEOf!VBywAT5= zhTr4N`ftv&}3EUB%hoKFC~=DB=I;Bb{COe68MLeJs)6YU*mvOQ>y|EKApS^ z#Ia}#ys&abYcyB{c?zlQxp4zlRsc8zMUukEtwTDg<%E2JFwGZEL^VO4#v>}Vo^Z`+ zh(nNxYG=*_tl?D6AEVU;R87AL$~!HIissIBCu380xF8C)O9@)U^DNq?5_03!JYE876flF!O9g$u#U!7UmU6*t*tv#tw4BP3+s znpzQm0W02km}gd$^&L)KqL+ zvwQe!q)SK4Kq3>M^GEauzo$kzZlriYtY~noF&pkB0TAh*G4akq`VKJDN8yf}_5jPL zqpwUh`vrd#e6*&=Fa$e+qgo?AS0iy^amjvAhX?^4Fu91tYfjSuhG+KUelR6Ox`BQJ z9^)b2Ys~zmKN+s)uc&{y$D#Lr-0`=^?j5w?{PY2fU)taIg%7jZd^-wTY%?zD)^q)W zhNkXMzHPks^^Jw2&#W(c>5*;cS2R3uU1j%AOD;eE@`9P8y8UzDAZ2^W-7oxW&f#!n{Z{9lF$)7x0ZR_`1&Xzz!@8t{6{;=OygP+I`ugHGn9}j+f_&42t{NtV9{qex( zk6!Ewcl+G^g{S$=F@c{Z_nkcG506hDbi>NgKkOg4|7=^ranIUwy^mdc%9gPgse#{~ zvM^kI@TM}DNUJSTVLBjeoi7p@7(b)EUq%>WYPqw;SX zmFRZQqX(Wele_}C#XB209Lm9Syh6%K57dlA$#~H5A0JV)n}_LvLOipZ>eF@J9ym+1 ze#DcTq7c;SmlE3)Ma6#v=*f+rGBk#JKpcPv+f3A^dt%M;ld@9(kKkSL%-{qTTYXEG^!1MU^jX z<-7lI)Ey_UiARZ7x(Hihc)UsxI(_k`^5UqqcqxnKt%$dQr;LB86mruS zB~WDmIcOSDThJ85>hywtRQfjC$Ybb9M+hn9hlh||<m1%}H^n2R zjvu>S=0uok;vIAI0KQZn(CM3(?6y=adP2F(Cdkgwvr1WX`ohO9YSKkmbkj`_;)6nY z2~;4}qU(qdF*3!me$ahhY9gKJ3O%c0sLXHC57|Jx#5~n`DjGiuSt?fXsPeKAh<}Dz zN1A8BD?6>>cpV(dn8OrBrOqVCI1zNyGkwh35Om{7$1gsJH7AnFBV_fwO?HZ*Lh$6a zsq|#|&MKSu~<; zI{wqgY`+sAq%tUGpa}-l!9Pf(@__i}LGdLckYGSOR=^04ZnQ$d0+IdUjir)+A-Oj< zWOCyXE?GreIUc8C6ke7U)&zK7jLu&re^Ejw%5aNl)PorO&gY}Uh6L6tsV!V@`ILF`WZa);_=`e zY@6U1t>(y0V-Z}B;9VoXgbzB~*$6)M+{&8}B=2p{9cY8YHJj$I`Rsz1;eyUq#Y1bmkp2OnGG%!q}~<5hJLSJf6?tjss{F4^jx+1Ku{PNa6ebQ3{&8=#%Zlea02qOk#106EBXb|4eeM&eC&*;IRLWH`INN^E#`+Au2 zUm)olGTwdRrP6mo|JpN0OwC{vV}CmMN-OL3-o}%*>z8riT!U@r>ScevzUrD;n=UFEGgF(d^f+f@ z+jA#OYVp2u&_=%|M-jg!TH_Zy72d#SKaW3#~v@& z|DK(2DyHlur($*pxzJMTAG1M;$S=|&pvBeR6dqg}XKulfBgXWvh9LK^*5S2uu*Nep zdwNWPu7o*9(5+tWVMS0rx^v%^-@ZGJlx7xgE1~1iI`z+cfzXUF`%K7ra1k1+fgp%_ z%=?U}{V>cGAQ&0+oxQXivfIVgiz*jXlU~ssYM8lT3HcPOp1G)`bo|`0)u$~ipK|K# zS+mMc9aT~~p?V1)KLy&C_I<+mGi5KcU()f_vAc`)f;)!30ynE^ErA#`(87>70Mkvl zoCzxvQ_Miv^ngufj=DgY_Xu|Z$X?>Y0bTZzZU``A_dtFu`mV}Y*vG+Vo8$J7oE9p) zx$6TQBS9i?S2{F9y*sGJc`eUz74XIdWFX|R# zoM{XaF9HK(UewFw5I1^T!Yy#O8e0Xy4B1pf6y|_w65Wx-k8`9=fKcG5Nx8tM`&m-G z6Y%EX)E7&G0Rt+$3C@)P(BvdAMg|xo@WbnE4FvS8tjwsMmB)n-P#~~)QCunmaZB3O zki;06bV{t+fCwg-!_u9i51OjuaCpQU@F^{@-Ga4O+P5?$>4W$%LmqDgbT3OEk6UtR zp-wO+2FX)4Ts8jFA7bg}Ye!hRZ&&Ls=6D3MF4s<$zNV=OvJ+TgM3mjlEE_T>2j(Mg zp7MzzNR5FqR5F@Kj|Gq+(zLCKWnad4K{X|QE2y`#U2QoDsG4QdB3j$#{ zrqa?`#&dzsl*z)_wjczZ?N2OF$$j~@O{P7KE)6K*#JNp_pprH0G$89 zLO$X`9;3;N*tc=r-1A$TX$9_X+|he0%f7_~bJ!=aNOfVe0=?Kag%%uO-m36R2GgMc z40>yN)&J@(egTh;S{upZ7T;}H7BpqC)|OV5`94$hT`Y47%N(jq}Hq-td>6yWfx8ck5R@{|NJRr0Q*Z`?H??`<*xQ zY}?8+&nVxrYSzG)zdiHNTXWw2{TZ*v{_!dI-PJI3`6Jgfzi``KPv3EKR`1P&AAe)Q zFch2x%8`h3!b^_w$QLMMtz(6+2n)y z=LQ>K@Q73xhJ*Mqhv6_N1I%E>hF_X=2m)$A;XLT3AOKCnt7zE#S=I^6u@!?Jj%t~5 z(4t;gCL@VuyNm19lV_pBNPdPOIqMuhP(>C{g2A%3@KqH}PDB#XY*lD^6KmHQ2w`O> zr_||lfwF4rZBs(N(RVF*^0LS7T6gZW<(Kq*^qnI|{uR(!*1Li2nv%JXWx-wv0haZ7 zaC<0=b-ND6tXrcyva+&T1G>(-IJfd7qWqx5J(;`PKcfkHRzuE!^%u3(9`5#0pNIdV z>-A5*HF8konTuwH*Jz{foHzW2-)B)xUHn0o{XUkFrm!wG5ta=*-Rf)y>+%?8d)UXi zoF8Ca-vAisHXC0)>vFdrw`g4ogrv~KChe)gx?Bm=z@L%vHzebQ*TDdm9=c;5Wr-K-0CELhNH7eqaJ#K((ZU1Z{# zSEjeZoruL1Jm^kR4XR4;Oa+=Ww3=lzmc6BgWdl_~{j+EHPL>U!zrnweB%u9R)QD+S zO{PNd`oZJ1??@fOkk{d`AURj-ueGHbCYf)YmRs>Vz8T-+-pb ziKjW*%^)1-qz!`uyjnZRx^`twQ0U32f)Q*LjbS*gB{g&-r(~NrrJ6iHK(L}yJ}pfy z6wLl8yt-ZIZzx`|sQ%rtZNu;P%)U1eIBogvz}eB&=RS4GRCR~zwO{=>CzuD%f^ZOl zBMe=4LQPMTp*kC_f*K^4hcdQvtwAATY92fE?M>z|w5xxxFS+4bIh+}TXTliq&i(Z` zJJ-xR*U+`F*Z%t#tnN~mm%FY_TUtNf z(8(M2JfHXGuz_#558gcb>4W#oyL-|HbFR#plf8EO#Rn2>3vSN& zCu9v~3h`@K<5_Grw=4%D5qdkoHY_fqKz^O#@ZlNUbi0w03t8gg9pcQPQJ_4iRJGZ{ zcjd>|Bxca{o)D8*(ggILd&Ya^Ko$*4#nprClPFcX=DWLTv#xYUJr zfS%%?Ow|+taUpp;9sxx@=%O{|E2kM~_e;skBrM`G4`w^pytn&`d)|0Im)XdpJ_T`S z&|n0w+`aA&1ZN>gc9RI!ASgV^D?xrSmtLbBdGfkEX1g12#N7b4j}R0t`fWe)L=%|p zcCfv=7Yy@wjg)tRkB2E zHJQF@L=d-uUKU=!Km@)62ANWs_jcQmm*3l+{x;S3H~L!26fZR)qc5K9*}MtJ2^KN~ zjpEtsELH!Sr+tmm;)}n&#PWJSz0S1bwPP|iBHpCK4r!(aRKXwNE$v2g~ zcAgLVHBVmG%#?SS<2-8HM{r;d3l|E0DWdG@JR^D;cELu$iSyi?eZ#e+b{td2fc59s)z-J0be2bHr);@9nc1HUhjpFgRUI$C zCMuoGLR2Lb(u3iN)i`JaBM3CvY-BU+M?7KX+_1E2CtbJ4c~Sde+1szoWFZ$A@}4v} zponGv!ra*#zXiBq%~STb7QJ=R=hxo!z^5l)_|+G4FL+})i}n5WzlSV|v+&8V9I9$xz`Vsg>)HBO1OS-5ZRH z0x<|H=)OSsT?5~sdoQxKrG40CnpYPXKFHVL;)SKbhrgx;=mKLW+zkL!DK0Rk`%gdbiVNGS8K&t`^yTfJ1&M&A`oFM4rGGpgIr~!1Dag@#qrKLAw{-?v4 z1lVbM5cQ^RQyO0@owq4%o7pB<`$6i1gEjz6>I;@( z99A6$Z{4U=H^Ty*r9DlF`Js>i&LnxNy*Lsd9>LP z9_QG|+Moq#ABPNU+@QlY&&>F>u%VTV}b4Rw6tn&+?6RV zEX88;RbvfOYjM;Fm6BKm*PptBa3=!Bou+&Lkm5pN@#{|$SD9w~l@}gF%fA*aZ-rS8 zydavFnVR6u#EpVvMO6xjiiD!ph!Q@NkZ#b&@5xNQ^wK1%j!Imbi4yuQiLQt~vw{5K zpIjY;AgH2D4@E(biEJ}*?In~~s<U3xF)Vy^RsnR1ofogK<_~qmrJx~yd@rw&O>Ddi(jDk5fPCTka zl5si|Z|MWFmTr7RkNAVl_9q90Y)SWB^#%iIb1~b)M59P0)bzReJ3w0f+Fx^qcBsgK z+j#urnQco#ceKUdFd?(`>XWZNFd%)^6T{|@df<|$rmN@uX=3RO>Vc;`%O{QeT?z^Z zq>;S2F}WzwDDnOF6JH!&{ZY?_y#ogqegA}gc6M|1IhsTpxL}qzaq^csuHm>dIhZnt zYx__Ptz%cs(95>WBKn0Xh5nlHw=DlHzch|pzA(fEPt;QwIUscg1%@)B`Tu(zg2XqPCh&QNM^hKdyP61PX1Kb9A3scs@X3*U1 zAoisfR?A-yZy=txAhoH~Ll_4OCA?sQ8!#|>h{RExctMbhA>KJa&Q3mXe-<4yKk9hlA$DR%e!Xj}#IE?nu5sHT2 z{p!_a>feX{xbN);?^4UYtsJoMcjp|rq3gkcRg({mK4a9$)%rDr!R?Rwnf;HrPw*#D zkwi$2XZB|y;H$Z7&+e-*wq%J2fO~2d?BDTcdZyVTVF6s{;x>s;4Z!HsQ4GN{R76S` zBL+froPQeBMFRkUFb4p{(bKR4MwIEyF%cpqzHdUZ7toHpw8aHMLAq#6Fpb$C zBKZB07axY?t1E&(-L?w|u4@VA6G$RaIPSyw4PHH|Z=Q_ciwHh{#eXB%9t5xM{pEZF-$3w=0q@R5 z;R=HH+;rNT2o6Q?-f?H)2DGel1b-i#n~oqeOC$i`_O!8hwdaF7Mj*%#+*=pigCJdM zw{QIu-yn#ay=wM{FE2*$TQl!Dd56Bkm76xa3Y7I8kA^)UgLy2SDhnLhFb~1~2nN$0 zIvc@P5NsZF2*68!3&CxFykr?lbRa1B>Wtym!a)vA!mAC3#;igHs%OJz@8DLvbh@vv zKKwom8PZQeaLa?9-3X3HP@nYv)d)^Ciy1rhgH>pw53eYQ+uxu=uUUM@rVR-G2|>?` zRk&Zy@h=1`eq89mopE*qPg`~!z~ZC}=vHp)VMjxX%@Vt8UK7e=_RH|9`)zktA-EU8 z-u;(hr0g#sIPjL=U4RnlZo1(u^{WwF2SaU|e$2j`b;aR&9I~`Oq&aoiiKwI>u-_)9 zXB@M-Sl1_j62RPnQo)%L11S}3OU(W{>-Md91NJiL3whzO0pC%0lQu$1Gy((nP)M`U zF(s_}UU0#octgawsi1|w=iD)9a|8N0tv{VWbGZGu$BvlDkfvfQvvuJzYa}Puf`~Tk zB|_}L97|dE0$F(hoG)Z2x6QGcbw63W=7##an!u2@HoCY^*Zun|o0yJaVGdr7qU}AT}8LLo9cm{C$Of zW$rf0?Swab8W4g4xIa#Wt3~81*f~YK2@*JhM9(^bi772k(GpO?P-WP|N-preS`^B~ z^}x<`B0&`Q%tM!s@(dbBSsvjU{l{XS8ib|h5lg3bkhZn$AVi|~k@U89zR zs!r7NW&3*4obBpS+O<3FM3KN_;QW_|o->%SeTJbw z={c;=0y(qfgy}fHUT1wsw1h?4=g;D|C`Ne~u)YIi-jquYhx+W6MVH>3wCK_|n2QeQ z?5wLP{aV&HWLYja5d)30(Sr4YCC!1Ya|IHf7-;BwuA0~iRfPxlB8tYkQNTQb(LexT>#={*oP zwqLj?TfLadzRQC1G7coQ1o>P{h1CdQn?~MwiXv)UiSTbaM+C7M{|+W6*hvh&6|^Q~ zII76(CTi-q*fWQUH;KiWIa$QSr)&Ggp1DjUNV(WE&+ky))?<}-qevhZ;Q%^^YPOz_ zYbL}Zw4^+iaUBGGbGuX!7IjDkpAgBZvI;t;8hk3HvhGG%)67)tL^!5s_fq!XQ_4=f z$5K8=t68%D;_zKSVB~;O8l*dSfF}q;19S0b9kK!7>LJrDh4A6Z`kkzvk1^0qpwvZ} zx0DTCXGyCQ9?ycXk-FV+XuH_Oo5av|$rCa0p>2-Y>405Pl`#s#bSlu zgbwR8yOd3O)UuWd`xv`ijdJm~ij7>OjI@<&1=)Nn=i}tYVkH|SNvw$d91DN)X3LoI z@y(X|pGQy3Xgu;yh&lqGQE~`KVYN3ncgFVH^=xY=+Z?V|E~5x^?mYL?`Yjn2(_0 zqodfi0M?XOMxTUeNLaf~1yCS$W8JVNaFpH_P=Y?(%fZJ6#ls~VQ8qzm0F!~{0MRA% z)Dlu4hNEY#DBui%$O|a}NWT?0$u^=+Oc_q@1-+nUjByy>GMMLkZCG?NNMDFvY@L7X71{6G0-bbUhjl3RKjaLe{}I_kcTpHU-WgFE zd51OrNS04=0JI7K7_Fp%Xf;}5$7lpKFOwRPJPUhZC;J7nFyZBk4o^e3f+6oQ5_USd zFyo_wYc{k6$3m_V@D+2djS*KZMO;z-63)&r-C{5!BU>4V5@>{Q0bE3nbLDcv0ZMv| z_@`k}Ove|A^7+;bH%PQRdt5G4vL3$y)j4fD^)djca#f{^*HVn(3kr0=TcbH~;x(Rx z4<}|RH|-_8iP;8RSi#YqXhTj`r)|KEnIa`@`q1kRu5%hOyJ0j3Z5LM=MZM(wEesG) z%BV(~Bmx2KcR36+Ta$o7j=BFW`+}g5v%T{cTy3_1<$RrbQ2TSWRl}xwR=06wZM}+X zci5UbTr8}vq>DDxm2A!0+7;pkHAx-{WMg&7A6I#zOVMC~5hJt%CmJrJVgAbh>e}*M z<@l4HTYE;g((RE4dX?UJ^QVs=$}0Is^egYVeF*nJnTFw`5n{R9$7!|+KbuAefi499 zEcc1j{gjS)7OhuVO%3kWHeC)|`^0jeXJvV0%!P%cIk7StBXAE0^brD9>p47i$73PF+qPITEYuYd5Z5zjlSXZu7=X>RGkwhV>iQ zY+7?(t-vN73JpL`&=b^*RlAIt46TO}3^;&S2lJ_{Gw&d6aCEZfCXEMSE-3lIZ)y&E z2shXDO4TUBESQ|WhLvpd+D%(Vt*>V_Yird_@g`EISFc&Mx)kqY8zp+f(Njcu_fCsy);4|Lh~-9a#SN= zhlqqT#{#v5d>#OZ6wYomM6KX^H0@%1YtFkJx$;;(=+;yyzCa9jeeH%?wh6b;i@B__ z6)P|)H^#TKj>C<@fUc-kc+LVGILA&DgxTEu;hi^Ec+eB=4SM19g6^9?0st52!OCa| zUID-evLm=%6P*c(j^uAad3JcG0F41nafaau?AXBplixx$$-#tnFlgtRyAX&LNjRVnhm}YG_^His7Wiu9JrlEOpF@_Pu}<9(MD|BCQ3TbEGeMi zb{N~vMijNP(NHn4)@5fFw##U-w}LDx#TPu9L@PZC%hMn*(MBTqk*&0UU0-B}*B`jc zrg?|OI!dpYCBzZfrimKEO5?gGS_Oq+%uV14MG3ihBA%-yY*c~@#UAKly-zF-UM4?m z)`>tbBSB7LhXcVGs0i?uf%CBgH-z9iT+U>XC`Tq*!F6Uli3qxQvW631Eqra;?4EC( z_jvipXqV80%-NpPT0bsd^yOanmA!jh_CPRRGoktIg2W-@q-^8$5*NiEX^)`)O~4O4 zLWo3?-iHH@uy4nXps*(*0{}aj6lpdt?iFf0fIULV$QLm%5;mCa#`eyVg?x>?F2mE< zXekMXWc_Jf!XFUu87Q8sJjNA7)FnPwCxQrZdZF;QzmQ%i{4VukJ6?LBd?;^6pRO>A zDTmNqXMOr7tUN-ll01+T(!#7$h9G{0EXo>V*_`mGu|8M+!Y=lC;}>@EY_!9&XM#~J zIyrTb@-FHj4?gf<&e#%T(&UNvPki9cJ98%f_P&w_G;b=3NUs>jCuJMN09aB%vc$q7 z7TYT(g+%1o%|Qttk8RcgJ~I+fq~^YJwB{a@{NQ}Gm95qk!VuuBZ+)m_r)|%U70qoK ziMQ5c{*ONPL(_#HpK$sU!%iBn6LotvjUwOsv2?K5kPl0Qc*eMuUJ!&qKI;nw zw+a(~2;Oa2N7$hZiw7vat73tW5JLyW*0)M}P7>7Ws0wYQBY@wk@?X_Rb919Ji$=lu5t9&&B~L34twggf9eRG@T-K~DHA?r4q@ z5dJ~}l54m@PJn_F0+ImTW?*<5rmgg&4GB1pcc@XK&6*_+S-PXP8yHFx~ofLhVZGYH{7#E$RlgrM6bBVRh>HYc{Q3 zQP0lroVr3+B#CN)o)jKPs%vx{tN|D79niiu5{O9dmOQP)2oL`JFxTTL(NvxFuLHIM z&LIx9+gX=a^OI!UnvwuE7!*?&))VDnDP`a^rm@r2T0?5t)>w;XYl)JoXa!DDcZ$t- zVb|E{FOVFm)p}0sjoeE zbL~c=j|k8;Z0%YAIVF9h=>R0)HWGgPj3Pd~*qsX{EOiK<#14${R`o_f!V%37c7jk1 zxEjd=uYyY^jaC73#A%w|%oEa4MjTuX8-0P)q7a*bOpdt%5ycmSLUmlMVfxi)$7Xze z$2+w{KB{=~&o}IRWL)Ic?i)+5%sFf7rqAzDC&r?3?p;IDCZI$`j4Sv914D|tYve+3 z(W6c0|Cstezi_<|NXZkzdpC#k>Z7yL1Nt_y*~4)LZeMJ#$Jp)R!!H?{M0>GV23(YS zG>?xp48oXkz;mfei1V%%GI`_ZjcYEfRR>HH%TGLZoDWj1J!k~xTqMFN&H*2R;xvf( zv9MZrwuQrC;>HGM;=MTx5ert}_y#;@g(PP~#FT<{g!gV;X9Fwzo}ih{l?dfkv4MM2 z^@=?45zD+m@Fcyf`tCjL^nRW4BywJaEe!(tEll{BN0ki z6*pXPTghi{-ZE=Y{;YnNJ6^na?dzA_x8Gg;=CW@eK6l~%9-HsN{zhacqzl(VsskA; z^r#*-;6(#?lM`?>N0X+&piU$r$2SEm6ce%NU_bL9YV>Pk5}3|ntCbK?>0a>iSn?|D z8L%RCZ^O|0_kH@&J(_>}jn|y{!LyTmkN*9s7v9Z#pzOD=UD@yM2R|Gi-vR{jnbe2D zGgA-O@%4dY_&Ey!8FNcBM@-!MgguQmmcft#q}nc}5N|!-SnAh9U!l2BKIW3~bwUTB( zas4kuOefx)8VtvUnEDJ1vN>e+Vq+(M_X`^`1iHLb<8k~Afe9et@5FkDLW{{a<{?M0 zG5?%hxzXH|X-ob$H{>BNCT++=KJ0Wu9%Aahuptliqyj@60b4fYv(~I#3)ynnigjyf zKNfp(2L#N9p2j8iY-nvGeb`)x=Q!#h(klTg4yR$G0VgNcdNQn90t%_}fh$4Yfq*gf zM1p{6HDP5)0_NYNUxq13;2M_SDY%A>OwcdG8vb{|g_%5TE1Ne2uz~J{z|cX#0?h*K zSxn@D#hcKxBr6#tVK(ega>xGOX~%{;&5nVrBRS>pid4O$dvj>t+PJ1}pZbD}7gd~FtV}&UU zxuPKjPF#U9{C=}{T!AwDPo4MfJ+pUg1gL>jYrQA$*SSgk;;Iu(Ug~NU64E55DZC6q z#}Tud`G?K_0zNVF*oa-JD=6d@2n`LSed;<$V%aK4;URlpyS{FfZ{RR;rAQDZ)2((KwDq7H-U$XI ze%KB86LdL1uIXXoe?nd_jL@{x(D))@@=i29gbq;nB+ z>62UQ!rg8ez3%4GJJxAcDJCwU;|)PkuXqK^z{|(ocrfHhHGkxtDShAST~#=*@7^2{9)~(;XYBiVNvrU^Jyf<%7vd%`W|5oU= zMqve~DyNu3EDZ^!cVW z>+4c6X8qyAUh#UVk#`-n=(^48)b(d=tgSzfm$lKX;H>qe#7t3i2*OwaQ9H!GE?Ey7 z-RG#)5G+>Kp0A$A)`G9Z3RE}Mlag*-?TR%lRS%jm@v#EvjsXaGMi)zL0)zwy(J&f_ zpMnT-fe?~ZK?VeG+~m|rf#A@iY2XuKXbXQiu5AFs=)3)m0koLZ+-&s4;5z!i-vchw zR=hz(2fP%$lb8`z!2+b}xqk=)=&z5l1oXJVMz6qj8sebk3F7U0{@CsNzJ2>(pWtI- zve@EB2(eW~c(K$%;Dj;XqQD5Xi#Hcn^`W_jCm7%c8DpmMX4(}mQnsW9ycC&;u>~K$ zrfx;;1(-KNKP6FLit&Y=F|U>kKgL{(dZPKbu`w2c1L-KdQNSpKPHo`bL242}gp*}h zwk8C}yvm!F5`r9rW4Z!_pdOE9CKDs+h_sZ6nx-1)XfNt9bfxU9N-SXjg(vHJd>4~uG*`qzJ9ya!b77ylw)X0xLku8Ry zE9S;l+9$^4V@}{M$R?VyVLo5S&ZZuzQ3aj+uCG?4TzY9EG1X(26L196eaR(FJZeKC zinjurze;O|_IPQ*NrOnS(uk9Xh50VG<-k;Q7&^pIxJixdC&oUVwEYt<w2**R6rTEU{~( zB+MY_lhcu};&FCV!B-bFc9M zE(O^fErrCZGm>BRf~r<$<6yU*YP(9p6ml0Jm~C8N4^6f?zdQ24yust(g#fb}hZr#U zHgHe&fRoU}xOXf~K<#K?r%D`D!L7QGrWeht@w5G&P7|9NA0!U&3{`A=C-k432V##= z*TnZWuu!AcF(5-$w+gl)9ae6@t7&A0;N^re@A_4roM2_Y758?3I`5UeH#|S+W$)e{dt-ZAcem^^b{ddI z<6ugRJa@&m66G4TLzo-JpE#yc`e2g9d?{Q!&?GfHz!b2Pf$;!*v0)xYaWu}rul0xv zZcMZuaVdS<%nJz1BQ6sL9qowAZmNntgs31JyM~4b0Ks6)3_$+?_Dl+O8l5~ zUVWAQ`x{@qt>G`fy?NWT0gYOhAAUVO=c&i+=i*d^;h^>%5c>j(5m{*_HKd*1y!fSS zwKs}4-uJ`SwU2LU{Gx7RFz4-;$2JyJ{bSA#)ibF9f;&ps0UclyUJLS7jlzN`hMht# zE-+ENTtyBeOf;38)M?}ekB_!acDrP738i{pXz2?CxeIoJi`(=f@r)URmt>?;AoS}r zf#8Yrh~+_o?!&pXky{}tQ9#P^c61wL@nxNzckl1}nsbF#5X>74mCq7EsL=lVj@&k*(1 z2I5aHq@QI^J82oA9=?A}qW*WZr=9dGM8mjp(hf8SRSSDsIP4Q6DGgUAT|?z`ZuW|d z!kX2l<1?-#k4<)^#;|gu;Nl$8rLePL3wG8Pb@t-2R2u~#CN+|P!tKJCm(xopnYuDC zl19-kyoHjo#i?ZmpdpF5c6#K*i9%Ga6$FfI+Bbo73@3g#rg9Nmi(!}W<&Q~XAvXDi z)O|QUajZm*TO24`*ek^z(ZH<~qbQ6~R36A2H>2-WY*& zWt*WR0P5w5$PN^SFkHhn8iFjDqR1*4Yx0vGV!Lr9{k~*kKevk*>~y4o^O3KV|nF~+n@T=!+$vRRDM~E>`09Rw0IJe zGic7vBo*e#o#=X{j*Uy2Yc|){lN2YR%G|tR11>;+UYu6?3x(&?>Qgu9xP<4^E@TV;8xCGQ z<{zvaT3XRO41m^lyvGSZ$CGeN6Ua#uCk=EGb%}EXz%fBDa~uvp3l35xX)^)JrNagN zjbJ2F6$~bwC7`1OoRk0|Nd_B1P`l0;S+pyTpdIu@7&ipk{j{g(qI_5+_;x}~Zi6=_ zEem+BKb@8ghG76A3j!}nW*^hfKsJ16=Q$pulIhshj^C(c`t5O}6435Mh2v5?+U+zY zjO(jF5l{buwiDtgpvR~9#xReckrj`p-qX9_R-$kO9t_Eo6_9Db6a#V$H@FcS^i8&= zCQj_nm@o2UhnMsPR&0FfN@#LWz%B+W&^)?fE^gE)ge{bf3ygyh>iiNZ@r<|SE-%dN zXMEWyJ>briDZR|?Nj<55mXuginj1M#-Dd(Q04I@II0!)e6|RSq?}YuYU4h=tW9fS! z4iO1i_kmQ9ZFv5ULr<2zR`tq)&kvm3t?Z?%c6>8sSGe|vi?5ludC2`YpL-GnIUVW5 zYspZbb4=4;0};l`(zP^%H@t-rtsWEG} z4IPb0N-0e#3sL_#p;UG$f|5{TWmksy@piCnVhfhr05HASB(UL`%FYVD(i2BCuo2MF z46ecoDa{5fHDWtmEj&SsRt|A;Ym_8AA=*%bhCG-tGbd@r%pBb5jF~wlK4WGE|5s)V zje`v6TiRI*?bmZTnesxJmQ9Yquq6@V>H z)%t68oHM|v0$aH9vCY6J3)V+1WU1v0z>E-#Y0O8Ap2j@}gp^{zW2sY4_M6*hvj1Pg}s;ep4S&Tk=LuP(6&L(=fRDDUtzgePDol$y1-JWa}Iv? z{Yf1B>^8wf!g?~!!O#BSXdFC^JGGM^o1t;#y)Y?GFf|;RU?W$9ULXh@Q>*~@63C`M z_=QGq4-(_Rd+kQAF)9i?_qFb9HL?-*1f!m?WlEU%P)rG7)OdV0jodobG;3@ccJ>Qj z?S0~-k)J>E+2Us&-SD^3{bB`mXN0$}=v7hGy!`HjO$%n1xUN2k?Rn1Ier(j7qZIv= z6EwlQB@lQb*WA2gIo4!5D>o%~%m6ivn4+HB9DpK*d|(Z%@;=QrymM zAkg-30g`6dh23kRtEnJipiiWOTGV7OIERerP1b?)QSPFMU2;~M;H+?#(u|2qFF3EY zl_XWM2tRZhf-VsXQ6K0yU)0<1{Oj}1K55nT5vTfp2)_Tse=WW1z57SK@X*GVYLqET4_C!-(#iy5(0AGEWbh1P|$)^L@?yDdC-$#p>yhC-hSExIH^Y1 zo{kAcv6$Js2&O*AB1a{Z^$6GU0*-Ee5;fciL`cLkKbESQ$5KHqw>U{RfI06YiWCfwZz0tP|WQ#aeyOUds8rU@jDw@CM=a8oJPbJbc35cybF-KcLEN4MN&_9}r zT%Hg8NgPBtTLcizhmDH~qWKTSL9`QstyTih{Obi~;8ct)5TYy}gSTgW2I7T~m8hYB zy%9UVUD4iGc1gz&Vu&%5ljR1S(Ffq#EGl$Tv$Ip&=Al>{uEph(pW73Ipwq1Aqyo<0 z!SBP1<=}v_3sBVxVxesK#nH;S@N`>~OIy(d;D_}lWxL^vc=cxKd-Pgk7ilV>fr1$L z51(G{#X(mzg?o_0n8D9zw1u7WbPGvq*`j_pm`+BIn5bvXDSAfxfJ`e?enuB}>kh`; zU!P>=u!^NViN-KlF41a)`psVf*cab)~hJYGOBU@@R# zSjj}$0yP?muS{q!{~g}$)VIy0$rddGP#26AOI^^(aO02tRBHMbkp3f&El8>VjGItx z&gGLlVw&*!J>8j;S0388)6w2{> zvv?PYMA#zu_25%Q$6iIR&+0ML-H1&(&d~+ff}hZMr{Rfcx*08&dO*wCY9&V(4n;zx zLIJJWoD@HU;w$+Qr7u*Oux3uO<|GR*Ni80yHRqP8_Z6@B>WOFm@@~_u-pbq$KUmlA zqsu?v9{iW~{f6&e-r6&<^HH@O*p>FH@Mmr6F`T{61_8`BblWo4s~N2GBA=fE;G4mj z2Ax3%_F2S1q9PpBYPRNWUx2wHk66-=DO+@wsaS^#E?}ZXk0X6J$XVt^B>%-OhpF^k zUl zQ>kK$KEV}KWOw2`KC2&?OfoG za$ps!O-dl*z&$brEefAVks!=7XxK3c0l~#}XuSp9+Hlw^NPAnDz7%|!)?vEV#;HlR z_yF_#0S}K|$SzQJkn{)=v_Hvg>|}%C0h7mJf<8*j zZiD3p6~%MeVG0#8g89s&)78%)yCFBhW#@?S_(O1s)*0Is!??vX>>p|Xn~o_QvNKN( z&X6JZ#r|MG)9iwwA+$D^)R>AY8@YY5S<-u{O%ZBMp3Im`HdWCjA(Gxd0d}izN z?DZcl{@Y^(-PO1L_U+7m_r2cZ{G|<3W_@R$+PGJ{L;97>NVkmx;kVx_sJ~v42uyjk zw3%pp++Cz1lZzkSd~%xsn@y(3NyOOfW;l`CDWbx<-KOIYcY-1UJ}8BATgC0R*;Ex# z_)r+7AqU-vN#*m)4s0skB|?@5MX@0ZJ_==$Me;KECAhfylzXkDl5o9(Xed?29q-!F z6lx1^Q9PC+sF^DNruQfr&pd=kGb`c{t5S2RWAt&Gtw(i<=5`EG+uW3zDit5Mo99I< z5#V7C2ZDn5=c$%sVx z2qntnnMD81f+$L-FE@Shk6S{79uO9vM2UD-W#n=Em<=-aPdczzyGuj;D3$+1!2BfA2@GY%yW@rO98Qip`GA_`QA!#xodV`ZH3Kwi$M`q} zT0lbl!za-c{%C$#8Y`kyE9!F#z`1psnJ$iLQ9kuoe%xjNzg9rn&3J1988^Uu$A7Ku zi{}z4%(_$7M*}K8s{F-1VJ!@?)K>Y4r{-htrhcI|vqJONOwECZ-0>DDZoJ~f#j8+l zh~&kpW;Sddl+N;Lw-n+f#!IpE&63R$)Xi>KI)i?q#dt%Xc5O$Kd8;v=;yrz^p)a6DX%UPFEog=eI0#*D+@tB3!mVZowG2S%WVG*|INRf_4I8B z{z?Yn$~lJM!>4a_BDfF1j~@90Tw*(Zi=c1>?x1YnU31e*i2W;q!V$Q$2W0v?HjB}eo0q`fc0OKF z5H}5wXKmrC+CBq8;T_vP7eV12+x`fG!V5Qi+ME8i?f+wzIC$AbKcE;NUI|Cp%6SM1 z@7PK!g2FqtLhiFqD?T{~Y40`NS}V99*z^lcJRuZEP>d#f;#DqYPIwdLJWWT}lgfVP zyj{F)=kOYD((Z?(M)?Cv&lV}bc6BWNd(9ble5rg)ynEbdD)%j$o==(o7kta2K^YgL zLH5Ng6PFn94yniV#BJZ2q~x%l3x*IMtCGWh?{O+Q$OZ79Sk|N5kvN*uWfQ??8Oz2E zPE7fpWkZaN6c&Kk%`<_e7#*S5V_o6p5~(ez90NOot=r1>WjW?0rNUUl<2Jg(l>OGS z>daKE$J`Dtx5r=RcSbG&XQOmr?6o`jP@;5gDT zRnG}j=J%{8O+9NG1J zi;2r)`#i=T&n}PAiZd2mT-R|nXP*2Y0B~maBmid)>=eM6lM(>VydX7Pj>|F*vpK&D z=CO7hIEA+F6!X}Yj8igSO76s8Qgy->oUZksW(2qcub@IFa=0VbENK%1CA*IC#8vn3 z7872y4S_F$Xw_Qp$1u2L`r>N&g6x*5l(& z2R6s_2?DY-rz|z3j%#3ZP6@Hz>p|XhO48(Z{|`VS=iQ_!p7TwokjTwWO!3@Pe<36a z>Ffc}xyhgqc6XAsB)2PuORMBpiAl@%f#kK3`$6i){QR}?fBDQt&rAQe8k)4kOduX7 zChfKPKQPUDnf$+4aJ|mxbei?TITF69V!`#gGc~}DYr$cEE2JAKj)xm3iB$^9xf5=j zc45rZ_Iw}9t4ZD5g*F%K33&i54v3-P&)CV$D$IeV9g`=cixuebV_W=I0qO83 z@4lo}otJzjp6u?t({Qc^1|NCm`X}xThH07`{!ZwI798${i)C+YUv#f$w&`>I3LW-;kXPWDr{j%+@Ptj9)!I?*jqDhc18fVn&L_~oQd7Z@~>=diE)u*3{so0 z(!%dTkgd*Nm(=R~K&O)=f44bFSf6(>#u8GlpTYE#RP&b)xohb!8*i*uIRLr1+bar2&A)4?(rDAaL^1k+OV=J_z>1{k;o2KgcH)2d(1!LG4YAE zz;SsiK>}vUL?vOlVdj%*l8)O=U~J?f^C7v5!R8cGA51KOffRIjK2kty0|{;?_oEbs zX)?Lqv%wLoh6`SNQMlhT3n;{aejEwqNJ~y>Vyb&L17q7*Aw;6+8SC8|W*r9r;K!~R zrB!MchcgGg$-s;pwR(7VJ^qU82|}1i9j;7?51Kf}fhE;mDp^QAKS)w8ka^+oRAa#z z!onFcrI)usUbI8-;Fyg%S6G|Wxx#agzjK8&@l$q=G#|gPbBWQGcrNH`C+a19iIEO^ zYi8W^!2#UXjEney|}0l^S12u zM9DoXCV~MQvOZ54jqyJ|$M<>uPit2KA60Sx_w8;@63DfigoNY;LO5C#jev;Ya!A38 z>>5}h>b@aFY!xpAsaM_}NjQ}5=HL*OTLl#muU4^Aiv>}uSQU$kf~d7sM8RsQ!2kQ3 znfLZ>5)S+MKgip8bN=QxGr#%GZ+`O|;~(`32ua1FFW%~~rwoHyzm99!L$4Se&x7OK zG2Q_=RbWL$jrVfmi(^2nsP8=S(Xy=hp{nQuD1%GzL=h8@!MJQE>j(JNkt(ds7FPy) zx%ru2`e$4{Y)ei}>*L7}{Bqs--H-ppd)HURSNwJArtQDmkf;oX^@n)c%G3*wJO$cs5)+|-;jjhxG#cm~c!ICuZE;T1U7$oO=lG>Uoy zA>wjr=UzA;Y+4e<&CUeYy4F44A$~EO8_wJ1hx06%lwe1ss}ORvW5n}t-U;U|RRs^j z2^n>*{$)xLoNvhZy+&Pg7PjMOAY|O~mlnV|N;0}*df_lQ39TguRvd!!Q#i}EJT($Ydy1q}e6Q}s2L4BWead5Ny2Eu0QSANl9zpCL zaHf5Fgq%0}YY6qEEus8_r>tViPfYn?kmh8)-vi^AypA@ZDS|yM9>HEf5i01^N(we& zd2nADZ1*zzU>=N}WsS^1@O$e!$O$~A0SFw2q0=r3-@eBgze6I!-Ei`jVK#qYC%dd)Ts8JoS^Xhznuk@c}E+3k?zyyr+ zJ81eb$8ny7+A+i0jxwsVC?3_>-;A2xS=2Eys&hQcgvBp344MQdpZb)EVx7}u1VHMX zMS1nX=?T^qn~a1xXQPpREpxV+MP*uxBI9$S$z86*Mt5$FXPyl;5uW4w7C#tG<9=TW zzktc*yO|yO3lx@=8jqip&jEZ60A{}=u$#o|-xpWXusp0mc#88y3N59YIoFb5IElBU zD=b+}F|%?Fmg#P_1P3X&FX?@_K9RvOOYm|Y{1Ac*!ZLWHCHN%@t{@GM?oh4aKpFi% zIfo^Q{!h)DW%}lZ3_-vf*#5N)!TKBfPTn#?cA8RPOGt-At zhB&@JhdlK7&`2ID;Yz-Ojx&jtiYJvMz#ON^x5ulI+{kMQ%i*m1GEt3WqyMA3B(E`R zS^Ndyl4BGWX*l6A4ANAGV{W|?)@PDoRl@^I&8sW#=F$!$0S#v-L0xWABCMN?(6F1O z;8J-c{P(6^Q1urc58|)33A?a-_@XRzjK3-n%7#Iv)PNs+Vt3Uh5;<4e6 z|9MW^Ie%O7_blyfTkX`t7k$&qyZWlk2R2{6txr4LVCb>bO{~ZL6Kevv@G+IP-JnJD zPUH)1KOL!bD)<&H#?n#@FcL^;N6gw3cjW-U`4{N-X-R=lsG6k}fOhp8f@6HR(Tppk z1by`*=9cKgBY&Dxkg={?$_4v-)#&!!+nXL<_QsCAZ@0CTE~m5nMER)v6@WAlz@~bb z^*9co)2@rKQmEL)AQQm9)9A)&&-1#StQ(8w3Tp~W+a3zBQW8qYhG}rKG~Cj2!tRVi zfAwp_55Kwf#jLj7+n&5=y}irw1@71HIih-Bzy9|9O3_1KE{&NjhAt8fu=HPsSwCzR z05!tmg&EH6UYK9P`bAR{N@wYFNh`q&g4{`5LCkfbV3D6+LJUm_8kaDnNIga3kFQsO zx%3shxj|)lH%@-kVq5*z~RB|=zQp~f>d;77!ap{4zCk0rSiU!_{(W=0hP$fVlmZM7@ zRgGqKEfy-`hvE6Ha(K~=mV#6kxwUhtZewNLAf4-I%z|~98;mqHG4;ZD1G-t4rA@rc z7)^@(!7gI_cb(be&-^waE0jhwY$bM}i@3QumDew;zOho&Pxg}zgWt?X5U+~xa`yHV6s=@7& z8DU=Z@Ckc=aUyywIjp;LzvY8FhqY^73Owc@Qmv@SBb%gqB9 zl?|?_%&E9&+QlDCf8o|C{d-pQDPM5#ibp<*v5f!HN#uDL;$T9I9>+5CLM*cz=U`vO0%+h+YRVIc!yb6T~dUxYw{d|)Utb$?J01YMqQ3>e27 zL8xH81>M~d4YJJ1ezHc5u2lmB&^|!d6n{WV4snyjnX6FDD%KBNYJlIx3b`&somK%T zS`31IY(&879a+Oji}+ep&8}4Apdp&Ut1YLVkyMel&w|qs`K^Y$mi$ z#UXsw6?c4r#2S4eBJfU3gwYoO<>kCt`+s`)YSF9~+8a*@Wyh|6@mGOH2{7HK)V36Y z%&trQ!vcZf!?1cGLI4yGGfc&VaIqp3iJ16;Xzog;*u1q(4adiK zpbmksNrv2HGrU`>zlvBD(>LPIs$t!F^Bk0U<38(<179MD^PITPI?fnzGlMYd0Fy8c zO=N6U)5MRg^nHS7NNe=Xi>iygbE{ju*BPV&w4%)&b-7Fr+{Ky?`q~;@1Un`zb_lZb zn%C3KUO4aDsYBJVrnsHm--Wx04 z`pvP>>IGBsW5%?&f>%L;)o7WAwe_}~QIAb;ivDWx-$%TbHgIjk`|d}N=e#_raM*`A zAEbX7&jFar?&c4oVY7z$tMpKoi_Y=KSk^R-xa4_z>LhKF_nVdz{Tr=_FlL-o6Pz>JQ)Cz&`ZoRXaop#EF`Z(q+|x%(oMeD^hXsms2~y=DCHpF-=te)Z1J zmR&gbuFMNN-71E?L6{_r;Vwa)5JduF*deGt=f-}I6;Ii=tN!Ds?6Dg|d)JH~x`cf& z^T0g?8}`px{^c1lg{9Psp^v#Iy9XZ!EW0AWdO=ql9gR;zjBmPoYX?4kfujTXm7M(2 zf{G6oon@2Kp|@7qJExm4{9qX=m7JRtk%Q_4mc2Q8N^Zp*OHnWvV6KQM%HEbRVkMv0(OjbnRT1yiFSWbYETWNxU z0l@tY%8h{$r*sAh&%GAL39hw}@I=${4weV4E=+y73usDU{r2HZeICmLyAJSK?&`QN z*{IKb8o52)Ava!AfGlPLd4>1Ki25;)8Vz6s1XLv;IX9znoN+Tg1mA|b;Lc2zSM0|h z>-RmX&21Xf_1l3?Z{MzBd6)7nN*rC!1q;LHOo=_1giGW`B65|MN0+dje3d3BMkLJg z9+uo~gs(R8p2ap*YD2aQYjG&ho`{Sv*O^UCP5Mc0HVH&Qx-j9oU`Yj+7K{ro9@ zmOrJ#XqCutJ6HkkXvEmhpBEqHd8{BsjQxBpDGiE1V?Tc*a@*J;x6a0X{s)Nq!T&h+ z3kv+KpujTr^^l68AHkeV1Qq{4X0Sm%0VsjhUn@^B2kpyM$07GPHF@WAEm^$CA9@n0 zN5SuT-};}V9)-{u1cCT}l6oXnhiRJ}che;^VeVT-t?_+z4*f~%Eo-MHzgyl?|XeN>9+X2zE3RKiYuiQmbw%Gb>dk zT?x8acQQ`ntv&Pb%||;hKn4nskf<0Enk;~2eI6yYtiEu`jceBLxh!u({>GWpmMp#W zL2pIvo4Z$U%*}mk>xMgS_yYV`+PFA=py`n~oixblr29WOJg1hHG=y3A?-Qnzq9k)V zDZ&A|6HO;Zt(x4dNboJVIOa$*OwnCv zKAL8*^rMxcH=7l$4X{cD%KQ))h zc`?i#o(5P7f>2i@c{GsYgJq&9`idbzBEnL1iJZ4-6^XuG{7t*Q&3Y7YoR^G$@dwV# z1`HuFXFtG@2RZAHTn*gAayVVzj71G!Q?MRwkS2uOQEtPQu7@NLtb!h>0l_#NraIkw zr@8Ly#1RgL-T7fUBU8nC!G;(I*|J%I69Cy29NO%AcR#|R<@ZUGNSi}z0TP004kQ6P znt+`ufX(g}YvjQ8`u(jRMWI~CdRz_`4_s21?%&0OPekeJLP1GO?V1r%NaFwq^=MqufQjkVH3Tu-e8vGW!6v67iF)*k{EQ<+KL7gQ3p zF8WbuXKVhFr)bzxZN-``) zx>3;yHF^L^Ujs`*O;$Y$AK$?mt)eSjoL%|_%@k6c%}RfYBHAbomWb^^q=okAso+*g zJynqWM=mW6bbu^?hpFS~)>><76WXml&2-_22< z%3Rd0T4+umdM+#z&ivq5m z-zTtB$dSz90w4@!S@?ZH%%y0o<_O=x!x2fJxBja^TLxX$lHK&k4ga2g&w*u>+D1*rU~H_}MM^v-2w)PYWf`aqnqCWbwIeo@a=yElCLbiqy6PxXI77gV6g zKmf~qVf!#JXY#i?>ve$8JS-3zJ}gKg)qr@-_l-vv-7_x<)F_qm+pada!=eJxSI*BrbtD0bx2WXq-f+Re)@c|U^Xokwi%RVdIhO83$nYH>!E?3fF+ecd>K@mg9M0OB->9v{yPXMktM18@SJQfrLIg zMFY2LDs~B!fuxg7@o;-YM9E=&zTwfTf|iCxpYNN@y@~F}uvw#qwB(`&MWGOthsgdx z(0U?`)P#M9hyweLjL4R!?$j>Zt7V*DH-?%}_m6R}%pz#~xA03Nt>E`ptQWB2_)#@uh>v+sA7p2}N3-rrH#ewiXgzrv=_906|| z?!bc%H^*Y_1tT58)NIWO0!V6&;Oa?t9$gcEtY2@yVCETeo6ewv^}ETBKOO}= zL3Cnc=z?7j`J_CIXdcEbu16RQ6Wr}f9$}Phf#w{;&m2JgcJZ3P1an2b=*tk?2Z_8{ z0JY?Bc030@svzg?-<@ZH4yQxQPKnn9CIiS|K>v&VmJCd=us6s0PZX_4JUNWI50p%p z*j)_3-Y;=Dk!u1N6EHU*NR>ev`b+&MOnEfyJfYBF&4Z0hd{~Mrlkgr}A+^v`i)`t( zzesh~T*-QOYLL{3G%2YggAQ$3JmO7yw0OiD4xy|o)p$Mdu-SUr6uru3x0T@+pLUz- z!HZm3P(9ae9vClEDK}Vp%Yrd3B-Ww+?V%`$V28OZN~olw$W)JRCZVi&Akt8jEL#LI z5RHCDB9IEC{3#;|FXAD4YoQdR+qlv%f6+JjsQec>$tPYV-Slx%sE7eik=%~V6<$4x z26*sBAb+e%n}D5SsqqkCLp&<|kSa1BvwV>|d2ts4%jiQs(0}LlRjCA?gaReV+@-53 ze(`wtn_d*Gd!&PMRpCCxqf)p|FKb=s8wGffhb)v_^h9<3gO@5DCTj4_^N44p+ESNO zERTFi`>Hy9B3}{Pw0LT>dw5J65FOYxI%k)a8FOERG z6#T=(3(zIr$pepJ`_sr7%|(yO-*`pH;X%JN+rUU+7G={Z4u2Gtr{v`V0*?fUfAdd@ zCBNdZk|)QDu5*{@bsp}+%{UjiM_Ar?T=`F~Ub4)amrqT!<3oCef7 zK6HM}z-dMk4vI_+dIZ7{e&t|%W*kv)F@9n2IS<%teX$7uB5Wtm9&$) z`ti!dx{9U!kzUY>Vrh`@v9uBN!rGFh{*zuC=>>s4OZ_EYDNE@^X;TK^mHcmyd3nhze_LZPzGX-9A?i&GU^5Ak~1(!a}EtMOV>t&(Vsd{iwtBA zC$mq3%#%4Xnf-38U$y-M7n&^DoNR)9kk)Ii0?r)HCTIqB5?(%cKA3urrE=z&yhK^Z za$yGp2SB)=ngE3kHaD3>lL~Xp)jRnPW3^YzQNM z3KwMtRKzkj3Mq+!W^z{|*s)lOMe0n@1wUsA^;oWzKFu!iI@8 zxKH$+1vkI6D0=g_yGl}C+L_zq?aOb;|8DLFzkhw<_je4s``M@R1NtgkP3@VDue^YD zbHE2#x!~Dr$8Y+Mq^l@g`gG_-Fe~6O#X*pL5hqIrR|ro(ud}6{uTy91kdk!xIw`@z zq!boL4SHk!ow`NSGCB$&+uO1Z@_O{Gnd=2$aJ8W&tMc_Tj@rQdR~Z@vB4q(@$!`KEh7FfR(B zRPuAUkccHe>Ssy+WhJyxKw>CRW-eukVU?;mgGP^NbWc7KXbCc$D4;~6{k4}qaPOz0 zbb*4#*#|AK}i|>?HQ&hU+l&f!+*v=MfbdykDhqFt*xXv2LfgM z01aRZU{~S<7)r#<$$+u+0S*j`sN_I!Y-n1Xo?voAAgBpT`-Bza1XMz=YmXY`>@#d( z(!R_579%hd2Or^l%^#>{>HRSuY>qb$b_P+6+8u9R`xqw|)P+DUB9o60X~{gpuQ{6o z%`9^*$OULR;F=}jZ7luEmPVF8oTzX5+qm(k;9<}WR`AS32--6tM?S78n9_JQi1B@> zp^_Cq0!dZ5@yS`s_}+-v>>VJsdt_%!0IjpJ>IMRW+UOwmSS11iF_w7_)gF1@ygYO^ zN0Z1Kv=#dIS~<396Y!9M=ppDbWPIwg$+3f4d8cy{qyAKgD~`tw)Z z_WtN=?g`J1HLlFA`+EAQl6f!B?S2e{pvs*^STy)f=ICC+9Wt_z_dXg_^Q4-h(I-o>}rdG0yi{>GU zg)6a)YIB!`Z1_lHA1q_m9Aij`JQK8=mdpbq&>CHgt!@Z*7lyeV71~yWk^200-1#NMa`wol`_SR8#xruVTSC6@z*KW{=vWQFSjs zpBg|Bt3nqCkvGe%!0uptQi{(>IH%L49<|S}#4Ga>NVLtFD;^1PssO}soaw=KV{O`= z*RGbc9@KLAtXIV{XNP33&SL4CFuUmyI3A;1SDv`+^xKiIig1>>H5wX*+qf}h#tX*w zTRQlP+EU-FcV&r^CCeJHB@$7t z!G1KZPsFXWoHbGi_3g$+D=mR-N>Fj;oZ&@Xzx8I>6sG_;R zInF0P5K1Ep9FWapSs|Fmhb|F1L?pzreu18!wTNZC6iXx!r_i0iP<9}WslX4 zhsh`Gr9*1GrxG$G17u|cV4PhPnSFhSR?Xges#bMSt2)}XYWDBjw`%t$wA@_}_4_~$ zb20D*2K0CzWZB?(H}T35kxgXLcBM=bnS(`27}k)P!}+S0&smTB=lk3vDg z%`!3OXdz(&LGw*+7eDL%EWx?nZ^Qe2%;}z@4k7uec*O`*F&Wq^;KmxAzKWF}9tt0}V z0MRN}faOe`STkU#3tPfDkh3(>FUAnIK3f+ribWT*T%Gf0V9QMoxYEJgFPnNyFkT8$ z?S>`?4gmZKCg11FK1kyV7^jnf_+hy_47q{38AlWL()2BkZ;NQKIiA4Iv}Xc|)6$zc zkA%_W)}c^xK7Oa;q(c8#GV@<20^`Yhru35+6 zqFt;pFthC&VCo`5@76#T?vP!MFq|RS71Xu_l^O?W!$EmTtY*AX6+uT?-ob`MtVv-A zT_q3Pxl$$rgwJ3kxDoTPyRV2=2j5!1_nN~a z7j55ic-M|EcAVS$Prn-V^<%jgW(;?aK%^O{c3Wd}ZCRIP4s-?1%V^~h1-u_LFI#A{ zy*22g^}m3$!6zgItVa>L#bhihz{W-!ac<&mKkESz9`YkQTd-CI)lJS0g?uj~ZlV>b#9DR%YJCssHGU`+~g zVl00vIINS8TL@gmBuI=t=H&c6ovzs~YMt;qzR)q6-KyY5rWBw7g_Q}o=Fx&{#t4nC zX$t!ItBA_v-_beK3(ccy0vHux1%aOjKtLmfUmW&MDBse6IYt{}jajhK?<7D9nsJ1P zet~j3nZaXU zU$|sa^^z-hU)6n5&4b#?PSO~4CCO6v+x&cXRXdg8g!yq$i5mAQWjG)wAPiD1Jm7;` zxL{bURgz=p+PXU5%p2;o?VZ5Ky1!J(N*+RY=)R4WY@**cnc5XZQ$j)~nTl)7ximzd zFx4nSVPJz5_cA{t^qJxh3nt=9$pW#WeJt-)NXS^ReNjYybtAu}k%x@Wb6NK9m$9N3 z=C!e+>%yAg7{wY`h~30Wf&lAmkvxx1O>xtk60-PR(ZAzC9W%suy#>@qG;F*iTsLjF4z!vV6$FT)c zR^9?Ku6;tIRfb_#2*`9Hq`CCvQtr&3KefdqdsdYErG;`W@DlU^&uf>(Zwd{r)B-a)69mP6I z#8Yvfv^oaiqY$oMG@I4lrjELhHu?nI}#*o}f!GXCu5M*{FFrcSAHf?jWl6TP+krL90lBp2A7$W@y`9w)7 zXf-kSCKX9wdrRii0#u&AupX@b4lW*m)YrNtUnrnHIUjfNT~f9rzO2NZA^E3L(m zCfSpNq|D1oNBOG&x76k3iqkS26NBjNU=pw(!U2T~Xu1cZT>7;nr$5TR-x*zq$aD7f zoA25+Sv}C_=>2=1e@Y$k!-TTSHeY{yZN`?KHA8lvdDR(11Nutci%j43v(mR?OdWz% zF#cDa%S!hUN}pQ1Xjy#tRGGUtq}<&ZsK*5^&ojm)t@m6^?N51i|7q84gs5(=2N_g-8%GY)Uii!-6>Um^2V*K;yO)p_gZ`HnLjc}MK* zbwyw8{c4N*nS*tYu6$z8%BjD;`Pvy*_RLYQxU=UAAI4_CcIp0o*S$I6nkS#1+IY!F zH;nAIabnAe+jhpb8k%^;wo2O*QfuR+>K;a-M-fgasX*P%c=EWzj)HaQwI~!5FP(hxk|s~3E{=zM@j_(i>`}f@oDmu@_z_wv z6oG5-(2LS>v#pBLY3G`O){3DVQ4oG9jl4aazU-JDNR_DpxD&prjq2dRn;rtu2HiB3SIh$taSf>* zpFt|r31G5PDNumLs$Ri-606PyPm&}9!F|*-r+!M}!J-RL&{L6fy5czP^#gsmRKY*r- z9}j-u=0D`52lb+dzvD0NM=zPD2Tt?}iU$ngF)AQ{6+s4W5e=yD@F*TQ30Z_fn`%dD z)kA*tcfyAXoi9VVl34wzNM<#Na(uUGP)Hvf92CRE5YUIaw6Qo&a;OG|hmOT5U#R}` z3zyrHUis%UyKaB=$1Uev``)=ve6r#^@2K?eZL4p1X{eR*8E}TA, -} - -impl Debug for CustomPrecompiles { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("CustomPrecompiles") - .field("addresses_to_names", &self.addresses_to_names) - .finish() - } -} - -impl Default for CustomPrecompiles { - fn default() -> Self { - Self { - precompiles: EthPrecompiles::default(), - // Addresses from https://www.evm.codes/precompiled - addresses_to_names: HashMap::from([ - (u64_to_address(1), "ecrecover".to_string()), - (u64_to_address(2), "sha256".to_string()), - (u64_to_address(3), "ripemd160".to_string()), - (u64_to_address(4), "identity".to_string()), - (u64_to_address(5), "modexp".to_string()), - (u64_to_address(6), "bn-add".to_string()), - (u64_to_address(7), "bn-mul".to_string()), - (u64_to_address(8), "bn-pair".to_string()), - (u64_to_address(9), "blake2f".to_string()), - (u64_to_address(10), "kzg-point-evaluation".to_string()), - ]), - } - } -} - -impl PrecompileProvider for CustomPrecompiles { - type Output = InterpreterResult; - - fn set_spec(&mut self, spec: ::Spec) -> bool { - >::set_spec(&mut self.precompiles, spec) - } - - fn run( - &mut self, - context: &mut CTX, - address: &Address, - inputs: &InputsImpl, - is_static: bool, - gas_limit: u64, - ) -> Result, String> { - if self.precompiles.contains(address) { - #[cfg(target_os = "zkvm")] - let name = self.addresses_to_names.get(address).cloned().unwrap_or(address.to_string()); - - #[cfg(target_os = "zkvm")] - println!("cycle-tracker-report-start: precompile-{name}"); - let result = self.precompiles.run(context, address, inputs, is_static, gas_limit); - #[cfg(target_os = "zkvm")] - println!("cycle-tracker-report-end: precompile-{name}"); - - result - } else { - Ok(None) - } - } - - fn warm_addresses(&self) -> Box> { - self.precompiles.warm_addresses() - } - - fn contains(&self, address: &Address) -> bool { - self.precompiles.contains(address) - } -} +use std::fmt::Debug; #[derive(Debug, Clone)] -pub struct CustomEvmFactory { +pub struct CustomEvmFactory { // Some chains uses Clique consensus, which is not implemented in Reth. // The main difference for execution is the block beneficiary: Reth will // credit the block reward to the beneficiary address, whereas in Clique, // the reward is credited to the signer. custom_beneficiary: Option
, - - phantom: PhantomData, } -impl CustomEvmFactory { +impl CustomEvmFactory { pub fn new(custom_beneficiary: Option
) -> Self { - Self { custom_beneficiary, phantom: PhantomData } + Self { custom_beneficiary } } } -impl EvmFactory for CustomEvmFactory { - type Evm>> = - EthEvm; +impl EvmFactory for CustomEvmFactory { + type Evm>> = EthEvm; type Context = Context; + type BlockEnv = BlockEnv; + type Tx = TxEnv; type Error = EVMError; @@ -131,6 +54,8 @@ impl EvmFactory for CustomEvmFactory { type Spec = SpecId; + type Precompiles = PrecompilesMap; + fn create_evm( &self, db: DB, @@ -140,14 +65,52 @@ impl EvmFactory for CustomEvmFactory { input.block_env.beneficiary = custom_beneficiary; } - let evm = Context::mainnet() - .with_db(db) - .with_cfg(input.cfg_env) - .with_block(input.block_env) - .build_mainnet_with_inspector(NoOpInspector {}) - .with_precompiles(CustomPrecompiles::default()); + #[allow(unused_mut)] + let mut precompiles = PrecompilesMap::from_static(Precompiles::new( + PrecompileSpecId::from_spec_id(input.cfg_env.spec), + )); - EthEvm::new(evm, false) + #[cfg(target_os = "zkvm")] + precompiles.map_precompiles(|address, p| { + use alloy_evm::precompiles::Precompile; + use reth_evm::precompiles::PrecompileInput; + use revm::precompile::u64_to_address; + use std::collections::HashMap; + + let addresses_to_names = HashMap::from([ + (u64_to_address(1), "ecrecover"), + (u64_to_address(2), "sha256"), + (u64_to_address(3), "ripemd160"), + (u64_to_address(4), "identity"), + (u64_to_address(5), "modexp"), + (u64_to_address(6), "bn-add"), + (u64_to_address(7), "bn-mul"), + (u64_to_address(8), "bn-pair"), + (u64_to_address(9), "blake2f"), + (u64_to_address(10), "kzg-point-evaluation"), + (u64_to_address(11), "bls-g1add"), + (u64_to_address(12), "bls-g1msm"), + (u64_to_address(13), "bls-g2add"), + (u64_to_address(14), "bls-g2msm"), + (u64_to_address(15), "bls-pairing"), + (u64_to_address(16), "bls-map-fp-to-g1"), + (u64_to_address(17), "bls-map-fp2-to-g2"), + (u64_to_address(256), "p256-verify"), + ]); + + let name = addresses_to_names.get(address).cloned().unwrap_or("unknown"); + + let precompile = move |input: PrecompileInput<'_>| { + println!("cycle-tracker-report-start: precompile-{name}"); + let result = p.call(input); + println!("cycle-tracker-report-end: precompile-{name}"); + + result + }; + precompile.into() + }); + + EthEvmBuilder::new(db, input).precompiles(precompiles).build() } fn create_evm_with_inspector>>( @@ -174,7 +137,7 @@ impl Inspector for OpCodeTrackingInspect fn step(&mut self, interp: &mut Interpreter, context: &mut CTX) { let _ = context; - if interp.control.instruction_result() != InstructionResult::Continue { + if interp.bytecode.instruction_result().is_some() { return; } @@ -193,3 +156,38 @@ impl Inspector for OpCodeTrackingInspect println!("cycle-tracker-report-end: opcode-{}", self.current); } } + +#[derive(Debug)] +pub struct CustomCrypto { + kzg_settings: KzgSettings, +} + +impl Default for CustomCrypto { + fn default() -> Self { + Self { kzg_settings: KzgSettings::load_trusted_setup_file().unwrap() } + } +} + +impl Crypto for CustomCrypto { + fn verify_kzg_proof( + &self, + z: &[u8; 32], + y: &[u8; 32], + commitment: &[u8; 48], + proof: &[u8; 48], + ) -> Result<(), PrecompileError> { + if !KzgProof::verify_kzg_proof( + &Bytes48(*commitment), + &Bytes32(*z), + &Bytes32(*y), + &Bytes48(*proof), + &self.kzg_settings, + ) + .map_err(|err| PrecompileError::other(err.to_string()))? + { + return Err(PrecompileError::BlobVerifyKzgProofFailed); + } + + Ok(()) + } +} diff --git a/crates/executor/guest/src/executor.rs b/crates/executor/guest/src/executor.rs index 7620ee9..d8e9972 100644 --- a/crates/executor/guest/src/executor.rs +++ b/crates/executor/guest/src/executor.rs @@ -1,8 +1,8 @@ use std::sync::Arc; -use alloy_consensus::{BlockHeader, Header, TxReceipt}; -use alloy_evm::EthEvmFactory; -use alloy_primitives::{Bloom, B256}; +use alloy_consensus::{BlockHeader, Header}; +use alloy_primitives::B256; +use itertools::Itertools; use reth_chainspec::ChainSpec; use reth_errors::BlockExecutionError; use reth_evm::{ @@ -13,55 +13,59 @@ use reth_evm_ethereum::EthEvmConfig; use reth_execution_types::ExecutionOutcome; use reth_primitives_traits::Block; use reth_trie::KeccakKeyHasher; -use revm::database::WrapDatabaseRef; +use revm::{database::WrapDatabaseRef, install_crypto}; use revm_primitives::Address; use crate::{ - custom::CustomEvmFactory, + custom::{CustomCrypto, CustomEvmFactory}, error::ClientError, into_primitives::FromInput, - io::{ClientExecutorInput, TrieDB}, + io::{ClientExecutorInput, TrieDB, WitnessInput}, tracking::OpCodesTrackingBlockExecutor, - ValidateBlockPostExecution, + BlockValidator, }; pub const DESERIALZE_INPUTS: &str = "deserialize inputs"; pub const INIT_WITNESS_DB: &str = "initialize witness db"; pub const RECOVER_SENDERS: &str = "recover senders"; pub const BLOCK_EXECUTION: &str = "block execution"; +pub const VALIDATE_HEADER: &str = "validate header"; pub const VALIDATE_EXECUTION: &str = "validate block post-execution"; -pub const ACCRUE_LOG_BLOOM: &str = "accrue logs bloom"; pub const COMPUTE_STATE_ROOT: &str = "compute state root"; -pub type EthClientExecutor = ClientExecutor>>; +pub type EthClientExecutor = ClientExecutor, ChainSpec>; #[cfg(feature = "optimism")] -pub type OpClientExecutor = ClientExecutor; +pub type OpClientExecutor = + ClientExecutor; /// An executor that executes a block inside a zkVM. #[derive(Debug, Clone)] -pub struct ClientExecutor { +pub struct ClientExecutor { evm_config: C, + chain_spec: Arc, } -impl ClientExecutor +impl ClientExecutor where C: ConfigureEvm, - C::Primitives: FromInput + ValidateBlockPostExecution, + C::Primitives: FromInput + BlockValidator, { pub fn execute( &self, mut input: ClientExecutorInput, ) -> Result<(Header, B256), ClientError> { + let chain_id: u64 = (&input.genesis).try_into().expect("convert chain id err"); + + let sealed_headers = input.sealed_headers().collect::>(); + // Initialize the witnessed database with verified storage proofs. let db = profile_report!(INIT_WITNESS_DB, { - let trie_db = input.witness_db().unwrap(); + let trie_db = input.witness_db(&sealed_headers).unwrap(); WrapDatabaseRef(trie_db) }); - let chain_id: u64 = (&input.genesis).try_into().expect("convert chain id err"); - - let block_executor = + let block_executor: BlockExecutor<'_, C> = BlockExecutor::new(self.evm_config.clone(), db, input.opcode_tracking, chain_id); let block = profile_report!(RECOVER_SENDERS, { @@ -70,22 +74,36 @@ where .map_err(|_| ClientError::SignatureRecoveryFailed) })?; + // Validate the blocks. + profile_report!(VALIDATE_HEADER, { + C::Primitives::validate_block(&block, self.chain_spec.clone()) + .expect("The block is invalid"); + + for (header, parent) in sealed_headers.iter().tuple_windows() { + C::Primitives::validate_header(parent, self.chain_spec.clone()) + .expect("A parent header is invalid"); + + C::Primitives::validate_header_against_parent( + header, + parent, + self.chain_spec.clone(), + ) + .expect("The header is invalid against its parent"); + } + }); + let execution_output = profile_report!(BLOCK_EXECUTION, { block_executor.execute(&block) })?; // Validate the block post execution. profile_report!(VALIDATE_EXECUTION, { - C::Primitives::validate_block_post_execution(&block, &input.genesis, &execution_output) + C::Primitives::validate_block_post_execution( + &block, + self.chain_spec.clone(), + &execution_output, + ) })?; - // Accumulate the logs bloom. - let mut logs_bloom = Bloom::default(); - profile_report!(ACCRUE_LOG_BLOOM, { - execution_output.result.receipts.iter().for_each(|r| { - logs_bloom.accrue_bloom(&r.bloom()); - }) - }); - // Convert the output to an execution outcome. let executor_outcome = ExecutionOutcome::new( execution_output.state, @@ -115,7 +133,7 @@ where state_root, transactions_root: input.current_block.header().transactions_root(), receipts_root: input.current_block.header().receipts_root(), - logs_bloom, + logs_bloom: input.current_block.logs_bloom, difficulty: input.current_block.header().difficulty(), number: input.current_block.header().number(), gas_limit: input.current_block.header().gas_limit(), @@ -138,11 +156,14 @@ where impl EthClientExecutor { pub fn eth(chain_spec: Arc, custom_beneficiary: Option
) -> Self { + install_crypto(CustomCrypto::default()); + Self { evm_config: EthEvmConfig::new_with_evm_factory( - chain_spec, - CustomEvmFactory::::new(custom_beneficiary), + chain_spec.clone(), + CustomEvmFactory::new(custom_beneficiary), ), + chain_spec, } } } @@ -150,7 +171,12 @@ impl EthClientExecutor { #[cfg(feature = "optimism")] impl OpClientExecutor { pub fn optimism(chain_spec: Arc) -> Self { - Self { evm_config: reth_optimism_evm::OpEvmConfig::optimism(chain_spec) } + install_crypto(CustomCrypto::default()); + + Self { + evm_config: reth_optimism_evm::OpEvmConfig::optimism(chain_spec.clone()), + chain_spec, + } } } diff --git a/crates/executor/guest/src/into_primitives.rs b/crates/executor/guest/src/into_primitives.rs index 4123ca8..d074190 100644 --- a/crates/executor/guest/src/into_primitives.rs +++ b/crates/executor/guest/src/into_primitives.rs @@ -1,16 +1,20 @@ +use std::sync::Arc; + use alloy_consensus::{Block, Header, TxEnvelope}; use alloy_network::{Ethereum, Network}; -use primitives::genesis::Genesis; -use reth_chainspec::ChainSpec; +use reth_chainspec::{ChainSpec, EthChainSpec, NamedChain}; +use reth_consensus::HeaderValidator; +use reth_consensus_common::validation::validate_body_against_header; use reth_errors::ConsensusError; +use reth_ethereum_consensus::EthBeaconConsensus; use reth_ethereum_primitives::EthPrimitives; use reth_execution_types::BlockExecutionOutput; -use reth_primitives_traits::{NodePrimitives, RecoveredBlock}; +use reth_primitives_traits::{NodePrimitives, RecoveredBlock, SealedHeader}; pub trait IntoPrimitives: NodePrimitives { fn into_primitive_block(block: N::BlockResponse) -> Self::Block; - fn into_primitive_header(block: N::BlockResponse) -> Header; + fn into_consensus_header(header: N::HeaderResponse) -> Header; } pub trait FromInput: NodePrimitives { @@ -21,10 +25,23 @@ pub trait IntoInput: NodePrimitives { fn into_input_block(block: Self::Block) -> Block; } -pub trait ValidateBlockPostExecution: NodePrimitives { +pub trait BlockValidator: NodePrimitives { + fn validate_header(header: &SealedHeader, chain_spec: Arc) -> Result<(), ConsensusError>; + + fn validate_block( + block: &RecoveredBlock, + chain_spec: Arc, + ) -> Result<(), ConsensusError>; + + fn validate_header_against_parent( + header: &SealedHeader, + parent: &SealedHeader, + chain_spec: Arc, + ) -> Result<(), ConsensusError>; + fn validate_block_post_execution( block: &RecoveredBlock, - genesis: &Genesis, + chain_spec: Arc, execution_output: &BlockExecutionOutput, ) -> Result<(), ConsensusError>; } @@ -35,8 +52,8 @@ impl IntoPrimitives for EthPrimitives { block.into_consensus() } - fn into_primitive_header(block: alloy_rpc_types::Block) -> Header { - block.header.into() + fn into_consensus_header(header: alloy_rpc_types::Header) -> Header { + header.into() } } @@ -52,13 +69,42 @@ impl IntoInput for EthPrimitives { } } -impl ValidateBlockPostExecution for EthPrimitives { +impl BlockValidator for EthPrimitives { + fn validate_header( + header: &SealedHeader, + chain_spec: Arc, + ) -> Result<(), ConsensusError> { + let validator = EthBeaconConsensus::new(chain_spec.clone()); + + handle_custom_chains(validator.validate_header(header), chain_spec) + } + + fn validate_block( + recovered: &RecoveredBlock, + chain_spec: Arc, + ) -> Result<(), ConsensusError> { + Self::validate_header(recovered.sealed_header(), chain_spec.clone())?; + + validate_body_against_header(recovered.body(), recovered.header())?; + + Ok(()) + } + + fn validate_header_against_parent( + header: &SealedHeader, + parent: &SealedHeader, + chain_spec: Arc, + ) -> Result<(), ConsensusError> { + let validator = EthBeaconConsensus::new(chain_spec); + + validator.validate_header_against_parent(header, parent) + } + fn validate_block_post_execution( block: &RecoveredBlock, - genesis: &Genesis, + chain_spec: Arc, execution_output: &BlockExecutionOutput, ) -> Result<(), ConsensusError> { - let chain_spec = ChainSpec::try_from(genesis).unwrap(); reth_ethereum_consensus::validate_block_post_execution( block, &chain_spec, @@ -73,14 +119,12 @@ impl IntoPrimitives for reth_optimism_primitives::Op fn into_primitive_block( block: alloy_rpc_types::Block, ) -> Self::Block { - let block = block.map_transactions(|tx| tx.inner.inner.into_inner().into()); + let block = block.map_transactions(|tx| tx.inner.inner.into_inner()); block.into_consensus() } - fn into_primitive_header( - block: alloy_rpc_types::Block, - ) -> Header { - block.header.into() + fn into_consensus_header(header: alloy_rpc_types::Header) -> Header { + header.into() } } @@ -99,17 +143,81 @@ impl IntoInput for reth_optimism_primitives::OpPrimitives { } #[cfg(feature = "optimism")] -impl ValidateBlockPostExecution for reth_optimism_primitives::OpPrimitives { +impl BlockValidator + for reth_optimism_primitives::OpPrimitives +{ + fn validate_header( + header: &SealedHeader, + chain_spec: Arc, + ) -> Result<(), ConsensusError> { + let validator = reth_optimism_consensus::OpBeaconConsensus::new(chain_spec); + + validator.validate_header(header) + } + + fn validate_block( + recovered: &RecoveredBlock, + chain_spec: Arc, + ) -> Result<(), ConsensusError> { + Self::validate_header(recovered.sealed_header(), chain_spec.clone())?; + + reth_optimism_consensus::validation::validate_body_against_header_op( + chain_spec, + recovered.body(), + recovered.header(), + )?; + + Ok(()) + } + + fn validate_header_against_parent( + header: &SealedHeader, + parent: &SealedHeader, + chain_spec: Arc, + ) -> Result<(), ConsensusError> { + let validator = reth_optimism_consensus::OpBeaconConsensus::new(chain_spec); + + validator.validate_header_against_parent(header, parent) + } + fn validate_block_post_execution( block: &RecoveredBlock, - genesis: &Genesis, + chain_spec: Arc, execution_output: &BlockExecutionOutput, ) -> Result<(), ConsensusError> { - let chain_spec = reth_optimism_chainspec::OpChainSpec::try_from(genesis).unwrap(); reth_optimism_consensus::validate_block_post_execution( block.header(), &chain_spec, - &execution_output.result.receipts, + &execution_output.result, ) } } + +fn handle_custom_chains( + result: Result<(), ConsensusError>, + chain_spec: Arc, +) -> Result<(), ConsensusError> { + let err = if let Err(err) = result { err } else { return Ok(()) }; + + let chain = if let Ok(chain) = NamedChain::try_from(chain_spec.chain_id()) { + chain + } else { + return Err(err) + }; + + match chain { + NamedChain::Linea | NamedChain::LineaSepolia | NamedChain::LineaGoerli => { + // Skip extra data and Merge difficulty checks for Linea chains + if matches!( + err, + ConsensusError::ExtraDataExceedsMax { .. } | + ConsensusError::TheMergeDifficultyIsNotZero + ) { + Ok(()) + } else { + Err(err) + } + } + _ => Err(err), + } +} diff --git a/crates/executor/guest/src/io.rs b/crates/executor/guest/src/io.rs index b4d78ba..63a4ccc 100644 --- a/crates/executor/guest/src/io.rs +++ b/crates/executor/guest/src/io.rs @@ -7,7 +7,7 @@ use mpt::EthereumState; use primitives::genesis::Genesis; use reth_errors::ProviderError; use reth_ethereum_primitives::EthPrimitives; -use reth_primitives_traits::NodePrimitives; +use reth_primitives_traits::{NodePrimitives, SealedHeader}; use reth_trie::{TrieAccount, EMPTY_ROOT_HASH}; use revm::{ state::{AccountInfo, Bytecode}, @@ -43,8 +43,6 @@ pub struct ClientExecutorInput { pub ancestor_headers: Vec
, /// Network state as of the parent block. pub parent_state: EthereumState, - /// Requests to account state and storage slots. - pub state_requests: HashMap>, /// Account bytecodes. pub bytecodes: Vec, /// The genesis block, as a json string. @@ -63,8 +61,8 @@ impl ClientExecutorInput

{ } /// Creates a [`WitnessDb`]. - pub fn witness_db(&self) -> Result, ClientError> { - ::witness_db(self) + pub fn witness_db(&self, sealed_headers: &[SealedHeader]) -> Result, ClientError> { + ::witness_db(self, sealed_headers) } } @@ -79,19 +77,29 @@ impl WitnessInput for ClientExecutorInput

{ self.parent_header().state_root() } - #[inline(always)] - fn state_requests(&self) -> impl Iterator)> { - self.state_requests.iter() - } - #[inline(always)] fn bytecodes(&self) -> impl Iterator { self.bytecodes.iter() } #[inline(always)] - fn headers(&self) -> impl Iterator { - once(&self.current_block.header).chain(self.ancestor_headers.iter()) + fn sealed_headers(&self) -> impl Iterator { + once(SealedHeader::seal_slow(self.current_block.header.clone())) + .chain(self.ancestor_headers.iter().map(|h| SealedHeader::seal_slow(h.clone()))) + } +} + +// The headed committed at the end of execution +#[serde_as] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct CommittedHeader { + #[serde_as(as = "alloy_consensus::serde_bincode_compat::Header")] + pub header: Header, +} + +impl From

for CommittedHeader { + fn from(header: Header) -> Self { + CommittedHeader { header } } } @@ -173,17 +181,12 @@ pub trait WitnessInput { /// [state()](trait.WitnessInput#tymethod.state) must conform to. fn state_anchor(&self) -> B256; - /// Gets an iterator over address state requests. For each request, the account info and storage - /// slots are loaded from the relevant tries in the state returned by - /// [state()](trait.WitnessInput#tymethod.state). - fn state_requests(&self) -> impl Iterator)>; - /// Gets an iterator over account bytecodes. fn bytecodes(&self) -> impl Iterator; /// Gets an iterator over references to a consecutive, reverse-chronological block headers /// starting from the current block header. - fn headers(&self) -> impl Iterator; + fn sealed_headers(&self) -> impl Iterator; /// Creates a [`WitnessDb`] from a [`WitnessInput`] implementation. To do so, it verifies the /// state root, ancestor headers and account bytecodes, and constructs the account and @@ -193,7 +196,7 @@ pub trait WitnessInput { /// implementing this trait causes a zkVM run to cost over 5M cycles more. To avoid this, define /// a method inside the type that calls this trait method instead. #[inline(always)] - fn witness_db(&self) -> Result, ClientError> { + fn witness_db(&self, sealed_headers: &[SealedHeader]) -> Result, ClientError> { let state = self.state(); if self.state_anchor() != state.state_root() { @@ -214,7 +217,7 @@ pub trait WitnessInput { // Verify and build block hashes let mut block_hashes: HashMap = HashMap::with_hasher(Default::default()); - for (child_header, parent_header) in self.headers().tuple_windows() { + for (child_header, parent_header) in sealed_headers.iter().tuple_windows() { if parent_header.number() != child_header.number() - 1 { return Err(ClientError::InvalidHeaderBlockNumber( parent_header.number() + 1, @@ -222,7 +225,7 @@ pub trait WitnessInput { )); } - let parent_header_hash = parent_header.hash_slow(); + let parent_header_hash = parent_header.hash(); if parent_header_hash != child_header.parent_hash() { return Err(ClientError::InvalidHeaderParentHash( parent_header_hash, diff --git a/crates/executor/guest/src/lib.rs b/crates/executor/guest/src/lib.rs index 9509b8f..bb754b7 100644 --- a/crates/executor/guest/src/lib.rs +++ b/crates/executor/guest/src/lib.rs @@ -10,7 +10,7 @@ pub mod executor; pub mod tracking; mod into_primitives; -pub use into_primitives::{FromInput, IntoInput, IntoPrimitives, ValidateBlockPostExecution}; +pub use into_primitives::{BlockValidator, FromInput, IntoInput, IntoPrimitives}; use alloy_primitives::B256; use executor::{EthClientExecutor, DESERIALZE_INPUTS}; diff --git a/crates/executor/guest/src/tracking/block_executor.rs b/crates/executor/guest/src/tracking/block_executor.rs index f81b6e9..48cf220 100644 --- a/crates/executor/guest/src/tracking/block_executor.rs +++ b/crates/executor/guest/src/tracking/block_executor.rs @@ -39,13 +39,14 @@ where block: &RecoveredBlock<::Block>, ) -> Result::Receipt>, Self::Error> { - let evm_env = self.evm_config.evm_env(block.header()); + let evm_env = + self.evm_config.evm_env(block.header()).map_err(BlockExecutionError::other)?; let evm = self.evm_config.evm_with_env_and_inspector( &mut self.db, evm_env, OpCodeTrackingInspector::default(), ); - let ctx = self.evm_config.context_for_block(block); + let ctx = self.evm_config.context_for_block(block).map_err(BlockExecutionError::other)?; let mut strategy = self.evm_config.create_executor(evm, ctx); strategy.apply_pre_execution_changes()?; @@ -70,6 +71,7 @@ where let mut strategy = self .evm_config .executor_for_block(&mut self.db, block) + .map_err(BlockExecutionError::other)? .with_state_hook(Some(Box::new(state_hook))); strategy.apply_pre_execution_changes()?; diff --git a/crates/executor/guest/src/utils.rs b/crates/executor/guest/src/utils.rs index 19aeee3..893a9dd 100644 --- a/crates/executor/guest/src/utils.rs +++ b/crates/executor/guest/src/utils.rs @@ -1,5 +1,5 @@ /// Profile the given code block cycle count. -#[allow(unused_macros)] +#[macro_export] macro_rules! profile { ($name:expr, $block:block) => {{ #[cfg(target_os = "zkvm")] @@ -18,6 +18,7 @@ macro_rules! profile { } /// Profile the given code block and add the cycle count to the execution report. +#[macro_export] macro_rules! profile_report { ($name:expr, $block:block) => {{ #[cfg(target_os = "zkvm")] diff --git a/crates/executor/host/Cargo.toml b/crates/executor/host/Cargo.toml index 24f54c1..0a318d5 100644 --- a/crates/executor/host/Cargo.toml +++ b/crates/executor/host/Cargo.toml @@ -26,7 +26,7 @@ hex = "0.4.3" # workspace rpc-db.workspace = true guest-executor = { workspace = true, features = ["optimism"] } -mpt = { workspace = true, features = ["preimage_context"] } +mpt = { workspace = true } primitives = { workspace = true, features = ["optimism"] } # Ziren @@ -79,3 +79,7 @@ dotenv = "0.15.0" [features] alerting = ["dep:reqwest"] +execution-witness = [ + "mpt/execution-witness", + "rpc-db/execution-witness", +] diff --git a/crates/executor/host/src/bins/persist_report_hook.rs b/crates/executor/host/src/bins/persist_report_hook.rs index 56bd531..41ad8e6 100644 --- a/crates/executor/host/src/bins/persist_report_hook.rs +++ b/crates/executor/host/src/bins/persist_report_hook.rs @@ -6,8 +6,8 @@ use std::{ use alloy_consensus::{Block, BlockHeader}; use csv::{Writer, WriterBuilder}; use guest_executor::executor::{ - ACCRUE_LOG_BLOOM, BLOCK_EXECUTION, COMPUTE_STATE_ROOT, DESERIALZE_INPUTS, INIT_WITNESS_DB, - RECOVER_SENDERS, VALIDATE_EXECUTION, + BLOCK_EXECUTION, COMPUTE_STATE_ROOT, DESERIALZE_INPUTS, INIT_WITNESS_DB, RECOVER_SENDERS, + VALIDATE_EXECUTION, }; use reth_primitives_traits::{BlockBody, NodePrimitives}; use revm_bytecode::opcode::OPCODE_INFO; @@ -32,6 +32,7 @@ const PRECOMPILES: [&str; 10] = [ ]; #[derive(Serialize, Deserialize)] +#[allow(dead_code)] struct ExecutionReportData { chain_id: u64, block_number: u64, @@ -154,9 +155,6 @@ impl PersistExecutionReport { record.push( execution_report.cycle_tracker.get(VALIDATE_EXECUTION).unwrap_or(&0).to_string(), ); - record.push( - execution_report.cycle_tracker.get(ACCRUE_LOG_BLOOM).unwrap_or(&0).to_string(), - ); record.push( execution_report.cycle_tracker.get(COMPUTE_STATE_ROOT).unwrap_or(&0).to_string(), ); diff --git a/crates/executor/host/src/error.rs b/crates/executor/host/src/error.rs index 49a3489..0ef008a 100644 --- a/crates/executor/host/src/error.rs +++ b/crates/executor/host/src/error.rs @@ -3,6 +3,7 @@ use alloy_transport::{RpcError, TransportError, TransportErrorKind}; use mpt::FromProofError; use reth_errors::BlockExecutionError; use revm_primitives::B256; +use rpc_db::RpcDbError; #[derive(Debug, thiserror::Error)] pub enum Error { @@ -26,11 +27,14 @@ pub enum Error { StateRootMismatch(B256, B256), #[error("Failed to read the genesis file: {}", .0)] FailedToReadGenesisFile(#[from] std::io::Error), + #[error("RPC error: {}", 0)] + RpcDbError(#[from] RpcDbError), #[error("custom error: {0}")] Custom(String), } #[derive(Debug, thiserror::Error)] +#[allow(dead_code)] pub(crate) enum SpawnedTaskError { #[error("rpc error: {0}")] Rpc(#[from] RpcError), diff --git a/crates/executor/host/src/executor_components.rs b/crates/executor/host/src/executor_components.rs index 8affca7..02d88bb 100644 --- a/crates/executor/host/src/executor_components.rs +++ b/crates/executor/host/src/executor_components.rs @@ -1,15 +1,16 @@ use std::marker::PhantomData; -use alloy_evm::EthEvmFactory; use alloy_network::Ethereum; use alloy_provider::Network; -use guest_executor::{ - custom::CustomEvmFactory, IntoInput, IntoPrimitives, ValidateBlockPostExecution, -}; +use eyre::Ok; +use guest_executor::{custom::CustomEvmFactory, BlockValidator, IntoInput, IntoPrimitives}; use op_alloy_network::Optimism; +use primitives::genesis::Genesis; +use reth_chainspec::ChainSpec; use reth_ethereum_primitives::EthPrimitives; use reth_evm::ConfigureEvm; use reth_evm_ethereum::EthEvmConfig; +use reth_optimism_chainspec::OpChainSpec; use reth_optimism_evm::OpEvmConfig; use reth_optimism_primitives::OpPrimitives; use reth_primitives_traits::NodePrimitives; @@ -28,11 +29,15 @@ pub trait ExecutorComponents { + DeserializeOwned + IntoPrimitives + IntoInput - + ValidateBlockPostExecution; + + BlockValidator; type EvmConfig: ConfigureEvm; + type ChainSpec; + type Hooks: ExecutionHooks; + + fn try_into_chain_spec(genesis: &Genesis) -> eyre::Result; } #[derive(Debug, Default)] @@ -51,9 +56,16 @@ where type Primitives = EthPrimitives; - type EvmConfig = EthEvmConfig>; + type EvmConfig = EthEvmConfig; + + type ChainSpec = ChainSpec; type Hooks = H; + + fn try_into_chain_spec(genesis: &Genesis) -> eyre::Result { + let spec = genesis.try_into()?; + Ok(spec) + } } #[derive(Debug, Default)] @@ -74,5 +86,12 @@ where type EvmConfig = OpEvmConfig; + type ChainSpec = OpChainSpec; + type Hooks = H; + + fn try_into_chain_spec(genesis: &Genesis) -> eyre::Result { + let spec = genesis.try_into()?; + Ok(spec) + } } diff --git a/crates/executor/host/src/full_executor.rs b/crates/executor/host/src/full_executor.rs index 4d3e383..907a52d 100644 --- a/crates/executor/host/src/full_executor.rs +++ b/crates/executor/host/src/full_executor.rs @@ -12,7 +12,6 @@ use eyre::bail; use guest_executor::io::ClientExecutorInput; use reth_primitives_traits::NodePrimitives; use revm_primitives::B256; -use rpc_db::RpcDb; use serde::de::DeserializeOwned; use sha2::{Digest, Sha256}; use tokio::{task, time::sleep}; @@ -38,7 +37,7 @@ pub async fn build_executor( ) -> eyre::Result> where C: ExecutorComponents, - P: Provider + Clone, + P: Provider + Clone + std::fmt::Debug, { if let Some(provider) = provider { let debug_provider = debug_provider.unwrap_or(provider.clone()); @@ -158,7 +157,7 @@ pub trait BlockExecutor { impl BlockExecutor for EitherExecutor where C: ExecutorComponents, - P: Provider + Clone + 'static, + P: Provider + Clone + std::fmt::Debug, { async fn execute(&self, block_number: u64) -> eyre::Result<()> { match self { @@ -192,11 +191,11 @@ where pub struct FullExecutor where C: ExecutorComponents, - P: Provider + Clone, + P: Provider + Clone + std::fmt::Debug, { provider: P, debug_provider: P, - host_executor: HostExecutor, + host_executor: HostExecutor, client: Arc, pk: Arc, vk: Arc, @@ -207,7 +206,7 @@ where impl FullExecutor where C: ExecutorComponents, - P: Provider + Clone, + P: Provider + Clone + std::fmt::Debug, { pub async fn try_new( provider: P, @@ -232,7 +231,10 @@ where Ok(Self { provider, debug_provider, - host_executor: HostExecutor::new(evm_config), + host_executor: HostExecutor::new( + evm_config, + Arc::new(C::try_into_chain_spec(&config.genesis)?), + ), client, pk: Arc::new(pk), vk: Arc::new(vk), @@ -254,7 +256,7 @@ where impl BlockExecutor for FullExecutor where C: ExecutorComponents, - P: Provider + Clone + 'static, + P: Provider + Clone + std::fmt::Debug, { async fn execute(&self, block_number: u64) -> eyre::Result<()> { self.hooks.on_execution_start(block_number).await?; @@ -281,19 +283,13 @@ where client_input_from_cache } None => { - let rpc_db = RpcDb::new( - self.provider.clone(), - self.debug_provider.clone(), - block_number - 1, - ); - // Execute the host. let client_input = self .host_executor .execute( block_number, - &rpc_db, &self.provider, + &self.debug_provider, self.config.genesis.clone(), self.config.custom_beneficiary, self.config.opcode_tracking, @@ -338,7 +334,7 @@ where impl Debug for FullExecutor where C: ExecutorComponents, - P: Provider + Clone, + P: Provider + Clone + std::fmt::Debug, { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.debug_struct("FullExecutor").field("config", &self.config).finish() diff --git a/crates/executor/host/src/host_executor.rs b/crates/executor/host/src/host_executor.rs index c1ced5d..38aad56 100644 --- a/crates/executor/host/src/host_executor.rs +++ b/crates/executor/host/src/host_executor.rs @@ -1,92 +1,90 @@ -use std::{collections::BTreeSet, sync::Arc}; +use std::sync::Arc; -use futures::future::try_join_all; -use tokio::sync::Semaphore; - -use crate::{error::SpawnedTaskError, HostError}; +use crate::HostError; use alloy_consensus::{BlockHeader, Header, TxReceipt}; -use alloy_evm::EthEvmFactory; +use alloy_network::BlockResponse; use alloy_primitives::{Bloom, Sealable}; use alloy_provider::{Network, Provider}; use guest_executor::{ - custom::CustomEvmFactory, io::ClientExecutorInput, IntoInput, IntoPrimitives, - ValidateBlockPostExecution, + custom::CustomEvmFactory, io::ClientExecutorInput, BlockValidator, IntoInput, IntoPrimitives, }; -use mpt::EthereumState; -use primitives::{account_proof::eip1186_proof_to_account_proof, genesis::Genesis}; +use primitives::genesis::Genesis; use reth_chainspec::ChainSpec; use reth_evm::{ execute::{BasicBlockExecutor, Executor}, ConfigureEvm, }; use reth_evm_ethereum::EthEvmConfig; -use reth_execution_types::ExecutionOutcome; +use reth_optimism_chainspec::OpChainSpec; use reth_optimism_evm::OpEvmConfig; -use reth_primitives_traits::{Block, BlockBody}; -use reth_trie::KeccakKeyHasher; +use reth_primitives_traits::{Block, BlockBody, SealedHeader}; +use reth_trie::{HashedPostState, KeccakKeyHasher}; use revm::database::CacheDB; -use revm_primitives::{Address, B256}; +use revm_primitives::Address; use rpc_db::RpcDb; -pub type EthHostExecutor = HostExecutor>>; +pub type EthHostExecutor = HostExecutor, ChainSpec>; -pub type OpHostExecutor = HostExecutor; +pub type OpHostExecutor = HostExecutor; /// An executor that fetches data from a [Provider] to execute blocks in the [ClientExecutor]. #[derive(Debug, Clone)] -pub struct HostExecutor { +pub struct HostExecutor { evm_config: C, + chain_spec: Arc, } impl EthHostExecutor { pub fn eth(chain_spec: Arc, custom_beneficiary: Option
) -> Self { Self { evm_config: EthEvmConfig::new_with_evm_factory( - chain_spec, - CustomEvmFactory::::new(custom_beneficiary), + chain_spec.clone(), + CustomEvmFactory::new(custom_beneficiary), ), + chain_spec, } } } impl OpHostExecutor { - pub fn optimism(chain_spec: Arc) -> Self { - Self { evm_config: OpEvmConfig::optimism(chain_spec) } + pub fn optimism(chain_spec: Arc) -> Self { + Self { evm_config: OpEvmConfig::optimism(chain_spec.clone()), chain_spec } } } -impl HostExecutor { +impl HostExecutor { /// Creates a new [HostExecutor]. - pub fn new(evm_config: C) -> Self { - Self { evm_config } + pub fn new(evm_config: C, chain_spec: Arc) -> Self { + Self { evm_config, chain_spec } } /// Executes the block with the given block number. pub async fn execute( &self, block_number: u64, - rpc_db: &RpcDb, provider: &P, + debug_provider: &P, genesis: Genesis, custom_beneficiary: Option
, opcode_tracking: bool, ) -> Result, HostError> where - C::Primitives: IntoPrimitives + IntoInput + ValidateBlockPostExecution, - P: Provider + Clone + 'static, + C::Primitives: IntoPrimitives + IntoInput + BlockValidator, + P: Provider + Clone + std::fmt::Debug, N: Network, { let chain_id: u64 = (&genesis).try_into().unwrap(); tracing::debug!("chain id: {}", chain_id); // Fetch the current block and the previous block from the provider. - tracing::info!("fetching the current block and the previous block"); - let current_block = provider + tracing::info!("[{}] fetching the current block and the previous block", block_number); + let rpc_block = provider .get_block_by_number(block_number.into()) .full() .await? - .ok_or(HostError::ExpectedBlock(block_number)) - .map(C::Primitives::into_primitive_block)?; + .ok_or(HostError::ExpectedBlock(block_number))?; + + let current_block = C::Primitives::into_primitive_block(rpc_block.clone()); let previous_block = provider .get_block_by_number((block_number - 1).into()) @@ -95,143 +93,76 @@ impl HostExecutor { .ok_or(HostError::ExpectedBlock(block_number)) .map(C::Primitives::into_primitive_block)?; - // Setup the database for the block executor. - tracing::info!("setting up the database for the block executor"); - let now = std::time::Instant::now(); - // rpc_db.preload_accounts_and_storage().await.map_err(|e| { - // HostError::Custom(format!("Failed to preload accounts and storage: {e}")) - // })?; - tracing::info!("preloaded accounts and storage took {:?}", now.elapsed()); - let cache_db = CacheDB::new(rpc_db); + tracing::info!("[{}] create rpc db", block_number); + #[cfg(not(feature = "execution-witness"))] + let rpc_db = rpc_db::BasicRpcDb::new( + debug_provider, + block_number - 1, + previous_block.header().state_root(), + ); + #[cfg(feature = "execution-witness")] + let rpc_db = rpc_db::ExecutionWitnessRpcDb::new( + debug_provider, + block_number - 1, + previous_block.header().state_root(), + ) + .await + .map_err(HostError::RpcDbError)?; + tracing::info!("[{}] create rpc db done", block_number); + + let cache_db = CacheDB::new(&rpc_db); - let block = current_block - .clone() - .try_into_recovered() - .map_err(|_| HostError::FailedToRecoverSenders) - .unwrap(); let block_executor = BasicBlockExecutor::new(self.evm_config.clone(), cache_db, Some(chain_id)); - // Execute the block and fetch all the necessary data along the way. tracing::info!( "executing the block with rpc db: block_number={}, transaction_count={}", block_number, current_block.body().transactions().len() ); + let block = current_block + .clone() + .try_into_recovered() + .map_err(|_| HostError::FailedToRecoverSenders)?; + + // Validate the block header. + C::Primitives::validate_header( + &SealedHeader::seal_slow(C::Primitives::into_consensus_header( + rpc_block.header().clone(), + )), + self.chain_spec.clone(), + )?; + + tracing::info!("[{}] execute block", block_number); let now = std::time::Instant::now(); let execution_output = block_executor.execute(&block)?; - tracing::info!("block execution took {:?}", now.elapsed()); + tracing::info!("[{}] block execution took {:?}", block_number, now.elapsed()); // Validate the block post execution. - tracing::info!("validating the block post execution"); - C::Primitives::validate_block_post_execution(&block, &genesis, &execution_output)?; + tracing::info!("[{}] validating the block post execution", block_number); + C::Primitives::validate_block_post_execution( + &block, + self.chain_spec.clone(), + &execution_output, + )?; // Accumulate the logs bloom. - tracing::info!("accumulating the logs bloom"); + tracing::info!("[{}] accumulating the logs bloom", block_number); let mut logs_bloom = Bloom::default(); execution_output.result.receipts.iter().for_each(|r| { logs_bloom.accrue_bloom(&r.bloom()); }); - // Convert the output to an execution outcome. - let executor_outcome = ExecutionOutcome::new( - execution_output.state, - vec![execution_output.result.receipts], - current_block.header().number(), - vec![execution_output.result.requests], - ); - - let state_requests = rpc_db.get_state_requests(); - - // For every account we touched, fetch the storage proofs for all the slots we touched. - tracing::info!("fetching storage proofs"); - - // max_concurrency - // TODO: use configurable concurrency limit - let semaphore = Arc::new(Semaphore::new(32)); - - let before_tasks = state_requests.iter().map(|(address, used_keys)| { - let permit = semaphore.clone().acquire_owned(); - let provider = provider.clone(); - let address = *address; - - let keys = { - let modified_keys = executor_outcome - .state() - .state - .get(&address) - .map(|account| { - account.storage.keys().map(|k| B256::from(*k)).collect::>() - }) - .unwrap_or_default(); - - used_keys - .iter() - .map(|k| B256::from(*k)) - .chain(modified_keys.into_iter()) - .collect::>() - .into_iter() - .collect::>() - }; - - tokio::spawn(async move { - let _permit = permit.await; - let proof = - provider.get_proof(address, keys).block_id((block_number - 1).into()).await?; - let converted = eip1186_proof_to_account_proof(proof); - Ok::<_, SpawnedTaskError>(converted) - }) - }); - - let after_tasks = state_requests.keys().map(|address| { - let permit = semaphore.clone().acquire_owned(); - let provider = provider.clone(); - let address = *address; - - let modified_keys = executor_outcome - .state() - .state - .get(&address) - .map(|account| account.storage.keys().map(|k| B256::from(*k)).collect::>()) - .unwrap_or_default(); - - tokio::spawn(async move { - let _permit = permit.await; - let proof = provider - .get_proof(address, modified_keys) - .block_id(block_number.into()) - .await?; - let converted = eip1186_proof_to_account_proof(proof); - Ok::<_, SpawnedTaskError>(converted) - }) - }); - - let before_storage_proofs = try_join_all(before_tasks) - .await - .map_err(|e| HostError::Custom(format!("join error: {e}")))? - .into_iter() - .map(|res| res.map_err(|e| HostError::Custom(format!("task error: {e}")))) - .collect::, _>>()?; - let after_storage_proofs = try_join_all(after_tasks) - .await - .map_err(|e| HostError::Custom(format!("join error: {e}")))? - .into_iter() - .map(|res| res.map_err(|e| HostError::Custom(format!("task error: {e}")))) - .collect::, _>>()?; - - tracing::info!("Building Ethereum state from storage proofs"); - let state = EthereumState::from_transition_proofs( - previous_block.header().state_root(), - &before_storage_proofs.iter().map(|item| (item.address, item.clone())).collect(), - &after_storage_proofs.iter().map(|item| (item.address, item.clone())).collect(), - )?; + let state = rpc_db.state(&execution_output.state).await.map_err(HostError::RpcDbError)?; // Verify the state root. - tracing::info!("verifying the state root"); + tracing::info!("[{}] verifying the state root", block_number); let state_root = { let mut mutated_state = state.clone(); - mutated_state.update(&executor_outcome.hash_state_slow::()); + mutated_state.update(&HashedPostState::from_bundle_state::( + &execution_output.state.state, + )); mutated_state.state_root() }; if state_root != current_block.header().state_root() { @@ -268,6 +199,8 @@ impl HostExecutor { requests_hash: current_block.header().requests_hash(), }; + let ancestor_headers = rpc_db.ancestor_headers().await.map_err(HostError::RpcDbError)?; + // Assert the derived header is correct. let constructed_header_hash = header.hash_slow(); let target_hash = current_block.header().hash_slow(); @@ -283,31 +216,17 @@ impl HostExecutor { state_root ); - // Fetch the parent headers needed to constrain the BLOCKHASH opcode. - let oldest_ancestor = *rpc_db.oldest_ancestor.read().unwrap(); - let mut ancestor_headers = vec![]; - tracing::info!("fetching {} ancestor headers", block_number - oldest_ancestor); - for height in (oldest_ancestor..=(block_number - 1)).rev() { - let block = provider - .get_block_by_number(height.into()) - .await? - .ok_or(HostError::ExpectedBlock(height))?; - - ancestor_headers.push(C::Primitives::into_primitive_header(block)) - } - // Create the client input. let client_input = ClientExecutorInput { current_block: C::Primitives::into_input_block(current_block), ancestor_headers, parent_state: state, - state_requests, - bytecodes: rpc_db.get_bytecodes(), + bytecodes: rpc_db.bytecodes(), genesis, custom_beneficiary, opcode_tracking, }; - tracing::info!("successfully generated client input"); + tracing::info!("[{}] successfully generated client input", block_number); Ok(client_input) } diff --git a/crates/executor/host/src/lib.rs b/crates/executor/host/src/lib.rs index 82cb2d9..c7a2515 100644 --- a/crates/executor/host/src/lib.rs +++ b/crates/executor/host/src/lib.rs @@ -1,7 +1,6 @@ #![cfg_attr(not(test), allow(unused_crate_dependencies))] use alloy_chains::Chain; -use alloy_evm::EthEvmFactory; pub use error::Error as HostError; use guest_executor::custom::CustomEvmFactory; use primitives::genesis::Genesis; @@ -38,13 +37,10 @@ mod utils; pub fn create_eth_block_execution_strategy_factory( genesis: &Genesis, custom_beneficiary: Option
, -) -> EthEvmConfig> { +) -> EthEvmConfig { let chain_spec: Arc = Arc::new(genesis.try_into().unwrap()); - EthEvmConfig::new_with_evm_factory( - chain_spec, - CustomEvmFactory::::new(custom_beneficiary), - ) + EthEvmConfig::new_with_evm_factory(chain_spec, CustomEvmFactory::new(custom_beneficiary)) } pub fn create_op_block_execution_strategy_factory(genesis: &Genesis) -> OpEvmConfig { @@ -52,6 +48,7 @@ pub fn create_op_block_execution_strategy_factory(genesis: &Genesis) -> OpEvmCon OpEvmConfig::optimism(chain_spec) } + #[derive(Debug)] pub struct Config { pub chain: Chain, diff --git a/crates/executor/host/tests/integration.rs b/crates/executor/host/tests/integration.rs index 23d0679..b246c31 100644 --- a/crates/executor/host/tests/integration.rs +++ b/crates/executor/host/tests/integration.rs @@ -4,7 +4,7 @@ use alloy_provider::{network::Ethereum, Network, RootProvider}; use guest_executor::{ executor::{ClientExecutor, EthClientExecutor}, io::ClientExecutorInput, - FromInput, IntoInput, IntoPrimitives, ValidateBlockPostExecution, + BlockValidator, FromInput, IntoInput, IntoPrimitives, }; use host_executor::{EthHostExecutor, HostExecutor}; use primitives::genesis::Genesis; @@ -12,7 +12,6 @@ use reth_chainspec::ChainSpec; use reth_evm::ConfigureEvm; use reth_optimism_chainspec::OpChainSpec; use revm_primitives::{address, Address}; -use rpc_db::RpcDb; use serde::{de::DeserializeOwned, Serialize}; use tracing_subscriber::{ fmt, prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter, @@ -34,7 +33,7 @@ async fn test_e2e_optimism() { // Setup the client executor. let guest_executor = guest_executor::executor::OpClientExecutor::optimism(chain_spec); - run_e2e::<_, op_alloy_network::Optimism>( + run_e2e::<_, OpChainSpec, op_alloy_network::Optimism>( host_executor, guest_executor, "RPC_10", @@ -75,7 +74,7 @@ async fn run_eth_e2e( // Setup the client executor. let guest_executor = EthClientExecutor::eth(chain_spec, custom_beneficiary); - run_e2e::<_, Ethereum>( + run_e2e::<_, ChainSpec, Ethereum>( host_executor, guest_executor, env_var_key, @@ -86,9 +85,9 @@ async fn run_eth_e2e( .await; } -async fn run_e2e( - host_executor: HostExecutor, - guest_executor: ClientExecutor, +async fn run_e2e( + host_executor: HostExecutor, + client_executor: ClientExecutor, env_var_key: &str, block_number: u64, genesis: &Genesis, @@ -98,7 +97,7 @@ async fn run_e2e( C::Primitives: FromInput + IntoPrimitives + IntoInput - + ValidateBlockPostExecution + + BlockValidator + Serialize + DeserializeOwned, N: Network, @@ -117,16 +116,14 @@ async fn run_e2e( Url::parse(std::env::var(env_var_key).unwrap().as_str()).expect("invalid rpc url"); let provider = RootProvider::::new_http(rpc_url); - let rpc_db = RpcDb::new(provider.clone(), provider.clone(), block_number - 1); - // Execute the host. let client_input = host_executor - .execute(block_number, &rpc_db, &provider, genesis.clone(), custom_beneficiary, false) + .execute(block_number, &provider, &provider, genesis.clone(), custom_beneficiary, false) .await .expect("failed to execute host"); // Execute the client. - guest_executor.execute(client_input.clone()).expect("failed to execute client"); + client_executor.execute(client_input.clone()).expect("failed to execute client"); // Save the client input to a buffer. let buffer = bincode::serialize(&client_input).unwrap(); diff --git a/crates/mpt/Cargo.toml b/crates/mpt/Cargo.toml index dccff12..528a91e 100644 --- a/crates/mpt/Cargo.toml +++ b/crates/mpt/Cargo.toml @@ -18,12 +18,14 @@ reth-trie.workspace = true # alloy alloy-primitives.workspace = true alloy-rlp.workspace = true +alloy-rpc-types.workspace = true +alloy-rpc-types-debug = {workspace = true, optional = true } [dev-dependencies] hex-literal.workspace = true -mpt = { path = ".", features = ["preimage_context"] } +mpt = { path = "." } [features] -default = [] -preimage_context = [] +default = ["execution-witness"] +execution-witness = ["dep:alloy-rpc-types-debug"] diff --git a/crates/mpt/src/execution_witness.rs b/crates/mpt/src/execution_witness.rs new file mode 100644 index 0000000..48cb0d1 --- /dev/null +++ b/crates/mpt/src/execution_witness.rs @@ -0,0 +1,106 @@ +use alloy_primitives::{keccak256, map::HashMap, B256}; +use alloy_rlp::Decodable; +use alloy_rpc_types_debug::ExecutionWitness; +use reth_trie::TrieAccount; + +use crate::mpt::{resolve_nodes, MptNode, MptNodeData, MptNodeReference}; + +// Builds tries from the witness state. +// +// NOTE: This method should be called outside zkVM! In general you construct tries, then +// validate them inside zkVM. +pub(crate) fn build_validated_tries( + witness: &ExecutionWitness, + pre_state_root: B256, +) -> Result<(MptNode, HashMap), String> { + // Step 1: Decode all RLP-encoded trie nodes and index by hash + // IMPORTANT: Witness state contains both *state trie* nodes and *storage tries* nodes! + let mut node_map: HashMap = HashMap::default(); + let mut node_by_hash: HashMap = HashMap::default(); + let mut root_node: Option = None; + + for encoded in &witness.state { + let node = MptNode::decode(encoded).expect("Valid MPT node in witness"); + let hash = keccak256(encoded); + if hash == pre_state_root { + root_node = Some(node.clone()); + } + node_by_hash.insert(hash, node.clone()); + node_map.insert(node.reference(), node); + } + + // Step 2: Use root_node or fallback to Digest + let root = root_node.unwrap_or_else(|| MptNodeData::Digest(pre_state_root).into()); + + // Build state trie. + let mut raw_storage_tries = vec![]; + let state_trie = resolve_nodes(&root, &node_map); + + state_trie.for_each_leaves(|key, mut value| { + let account = TrieAccount::decode(&mut value).unwrap(); + let hashed_address = B256::from_slice(key); + raw_storage_tries.push((hashed_address, account.storage_root)); + }); + + // Step 3: Build storage tries per account efficiently + let mut storage_tries: HashMap = HashMap::default(); + + for (hashed_address, storage_root) in raw_storage_tries { + let root_node = match node_by_hash.get(&storage_root).cloned() { + Some(node) => node, + None => { + // An execution witness can include an account leaf (with non-empty storageRoot), + // but omit its entire storage trie when that account's storage was + // NOT touched during the block. + continue; + } + }; + let storage_trie = resolve_nodes(&root_node, &node_map); + + if storage_trie.is_digest() { + panic!("Could not resolve storage trie for {storage_root}"); + } + + // Insert resolved storage trie. + storage_tries.insert(hashed_address, storage_trie); + } + + // Step 3a: Verify that state_trie was built correctly - confirm tree hash with pre state root. + validate_state_trie(&state_trie, pre_state_root); + + // Step 3b: Verify that each storage trie matches the declared storage_root in the state trie. + validate_storage_tries(&state_trie, &storage_tries)?; + + Ok((state_trie, storage_tries)) +} + +// Validate that state_trie was built correctly - confirm tree hash with pre state root. +fn validate_state_trie(state_trie: &MptNode, pre_state_root: B256) { + if state_trie.hash() != pre_state_root { + panic!("Computed state root does not match pre_state_root"); + } +} + +// Validates that each storage trie matches the declared storage_root in the state trie. +fn validate_storage_tries( + state_trie: &MptNode, + storage_tries: &HashMap, +) -> Result<(), String> { + for (hashed_address, storage_trie) in storage_tries.iter() { + let account = state_trie + .get_rlp::(hashed_address.as_slice()) + .map_err(|_| "Failed to decode account from state trie")? + .ok_or("Account not found in state trie")?; + + let storage_root = account.storage_root; + let actual_hash = storage_trie.hash(); + + if storage_root != actual_hash { + return Err(format!( + "Mismatched storage root for address hash {hashed_address:?}: expected {storage_root:?}, got {actual_hash:?}", + )); + } + } + + Ok(()) +} diff --git a/crates/mpt/src/lib.rs b/crates/mpt/src/lib.rs index 63fd4b4..97642df 100644 --- a/crates/mpt/src/lib.rs +++ b/crates/mpt/src/lib.rs @@ -1,16 +1,23 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] -use alloy_primitives::{map::HashMap, Address, B256}; +use alloy_primitives::{keccak256, map::HashMap, Address, B256}; +use alloy_rpc_types::EIP1186AccountProofResponse; use reth_trie::{AccountProof, HashedPostState, HashedStorage, TrieAccount}; use serde::{Deserialize, Serialize}; +#[cfg(feature = "execution-witness")] +mod execution_witness; + /// Module containing MPT code adapted from `zeth`. mod mpt; pub use mpt::Error; -use mpt::{proofs_to_tries, transition_proofs_to_tries, MptNode}; +use mpt::{ + mpt_from_proof, parse_proof, proofs_to_tries, resolve_nodes, transition_proofs_to_tries, + MptNode, +}; /// Ethereum state trie and account storage tries. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct EthereumState { pub state_trie: MptNode, pub storage_tries: HashMap, @@ -34,11 +41,51 @@ impl EthereumState { proofs_to_tries(state_root, proofs) } + /// Builds Ethereum state tries from a EIP-1186 proof. + pub fn from_account_proof(proof: EIP1186AccountProofResponse) -> Result { + let mut storage_tries = HashMap::with_hasher(Default::default()); + let mut storage_nodes = HashMap::with_hasher(Default::default()); + let mut storage_root_node = MptNode::default(); + + for storage_proof in &proof.storage_proof { + let proof_nodes = parse_proof(&storage_proof.proof)?; + mpt_from_proof(&proof_nodes)?; + + // the first node in the proof is the root + if let Some(node) = proof_nodes.first() { + storage_root_node = node.clone(); + } + + proof_nodes.into_iter().for_each(|node| { + storage_nodes.insert(node.reference(), node); + }); + } + + storage_tries + .insert(keccak256(proof.address), resolve_nodes(&storage_root_node, &storage_nodes)); + + let state = EthereumState { + state_trie: MptNode::from_account_proof(&proof.account_proof)?, + storage_tries, + }; + + Ok(state) + } + + #[cfg(feature = "execution-witness")] + pub fn from_execution_witness( + witness: &alloy_rpc_types_debug::ExecutionWitness, + pre_state_root: B256, + ) -> Self { + let (state_trie, storage_tries) = + execution_witness::build_validated_tries(witness, pre_state_root).unwrap(); + + Self { state_trie, storage_tries } + } + /// Mutates state based on diffs provided in [`HashedPostState`]. pub fn update(&mut self, post_state: &HashedPostState) { for (hashed_address, account) in post_state.accounts.iter() { - let hashed_address = hashed_address.as_slice(); - match account { Some(account) => { let state_storage = &post_state @@ -47,7 +94,7 @@ impl EthereumState { .cloned() .unwrap_or_else(|| HashedStorage::new(false)); let storage_root = { - let storage_trie = self.storage_tries.get_mut(hashed_address).unwrap(); + let storage_trie = self.storage_tries.entry(*hashed_address).or_default(); if state_storage.wiped { storage_trie.clear(); @@ -71,10 +118,10 @@ impl EthereumState { storage_root, code_hash: account.get_bytecode_hash(), }; - self.state_trie.insert_rlp(hashed_address, state_account).unwrap(); + self.state_trie.insert_rlp(hashed_address.as_slice(), state_account).unwrap(); } None => { - self.state_trie.delete(hashed_address).unwrap(); + self.state_trie.delete(hashed_address.as_slice()).unwrap(); } } } @@ -86,6 +133,18 @@ impl EthereumState { } } +impl core::fmt::Debug for EthereumState { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("EthereumState"); + ds.field("state_trie", &self.state_trie); + + // Use BTreeMap for stable ordering when printing + let ordered: std::collections::BTreeMap<_, _> = self.storage_tries.iter().collect(); + ds.field("storage_tries", &ordered); + ds.finish() + } +} + #[derive(Debug, thiserror::Error)] pub enum FromProofError { #[error("Node {} is not found by hash", .0)] @@ -96,7 +155,7 @@ pub enum FromProofError { NodeCannotHaveChildren(usize), #[error("Found mismatched storage root after reconstruction \n account {}, found {}, expected {}", .0, .1, .2)] MismatchedStorageRoot(Address, B256, B256), - #[error("Found mismatched staet root after reconstruction \n found {}, expected {}", .0, .1)] + #[error("Found mismatched state root after reconstruction \n found {}, expected {}", .0, .1)] MismatchedStateRoot(B256, B256), // todo: Should decode return a decoder error? #[error("Error decoding proofs from bytes, {}", .0)] diff --git a/crates/mpt/src/mpt.rs b/crates/mpt/src/mpt.rs index aae32f7..9fb7b35 100644 --- a/crates/mpt/src/mpt.rs +++ b/crates/mpt/src/mpt.rs @@ -23,12 +23,12 @@ use alloc::boxed::Box; use alloy_primitives::{b256, map::HashMap, B256}; use alloy_rlp::Encodable; use core::{ - cell::RefCell, cmp, fmt::{Debug, Write}, iter, mem, }; -use reth_trie::AccountProof; +use reth_trie::{AccountProof, Nibbles}; +use std::sync::Mutex; use rlp::{Decodable, DecoderError, Prototype, Rlp}; use serde::{Deserialize, Serialize}; @@ -91,14 +91,43 @@ pub fn keccak(data: impl AsRef<[u8]>) -> [u8; 32] { /// optimizing storage. However, operations targeting a truncated part will fail and /// return an error. Another distinction of this implementation is that branches cannot /// store values, aligning with the construction of MPTs in Ethereum. -#[derive(Clone, Debug, Default, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] +#[derive(Default, Serialize, Deserialize)] pub struct MptNode { /// The type and data of the node. data: MptNodeData, /// Cache for a previously computed reference of this node. This is skipped during /// serialization. #[serde(skip)] - cached_reference: RefCell>, + cached_reference: Mutex>, +} + +impl Ord for MptNode { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.data.cmp(&other.data) + } +} + +impl PartialOrd for MptNode { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Eq for MptNode {} + +impl PartialEq for MptNode { + fn eq(&self, other: &Self) -> bool { + self.data == other.data + } +} + +impl Clone for MptNode { + fn clone(&self) -> Self { + Self { + data: self.data.clone(), + cached_reference: Mutex::new(self.cached_reference.lock().unwrap().clone()), + } + } } /// Represents custom error types for the sparse Merkle Patricia Trie (MPT). @@ -131,7 +160,7 @@ pub enum Error { /// Each node in the trie can be of one of several types, each with its own specific data /// structure. This enum provides a clear and type-safe way to represent the data /// associated with each node type. -#[derive(Clone, Debug, Default, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, Default, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)] pub enum MptNodeData { /// Represents an empty trie node. #[default] @@ -154,7 +183,7 @@ pub enum MptNodeData { /// Nodes in the MPT can reference other nodes either directly through their byte /// representation or indirectly through a hash of their encoding. This enum provides a /// clear and type-safe way to represent these references. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] +#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)] pub enum MptNodeReference { /// Represents a direct reference to another node using its byte encoding. Typically /// used for short encodings that are less than 32 bytes in length. @@ -171,7 +200,62 @@ pub enum MptNodeReference { /// `cached_reference` field to `None`. impl From for MptNode { fn from(value: MptNodeData) -> Self { - Self { data: value, cached_reference: RefCell::new(None) } + Self { data: value, cached_reference: Mutex::new(None) } + } +} + +impl core::fmt::Debug for MptNodeReference { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + MptNodeReference::Bytes(b) => { + write!(f, "Ref::Bytes({})", alloy_primitives::hex::encode(b)) + } + MptNodeReference::Digest(h) => { + write!(f, "Ref::Digest({})", alloy_primitives::hex::encode(h.as_slice())) + } + } + } +} + +impl core::fmt::Debug for MptNodeData { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + MptNodeData::Null => write!(f, "Null"), + MptNodeData::Leaf(k, v) => write!( + f, + "Leaf(key={}, value={})", + alloy_primitives::hex::encode(k), + alloy_primitives::hex::encode(v) + ), + MptNodeData::Extension(k, child) => f + .debug_struct("Extension") + .field("key", &alloy_primitives::hex::encode(k)) + .field("child", child) + .finish(), + MptNodeData::Digest(h) => write!(f, "Digest({})", alloy_primitives::hex::encode(h)), + MptNodeData::Branch(children) => { + let mut ds = f.debug_struct("Branch"); + for (i, child) in children.iter().enumerate() { + if let Some(c) = child { + ds.field(&format!("child_{i}"), c); + } + } + ds.finish() + } + } + } +} + +impl core::fmt::Debug for MptNode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + let mut ds = f.debug_struct("MptNode"); + ds.field("data", &self.data); + if let Ok(guard) = self.cached_reference.lock() { + if let Some(reference) = guard.as_ref() { + ds.field("cached_reference", reference); + } + } + ds.finish() } } @@ -287,6 +371,12 @@ impl Decodable for MptNode { /// and retrieving values, as well as utility methods for encoding, decoding, and /// debugging. impl MptNode { + /// Creates a Merkle Patricia trie from an EIP-1186 proof. + pub fn from_account_proof(account_proof: &[impl AsRef<[u8]>]) -> Result { + let nodes = parse_proof(account_proof)?; + mpt_from_proof(&nodes) + } + /// Clears the trie, replacing its data with an empty node, [MptNodeData::Null]. /// /// This method effectively removes all key-value pairs from the trie. @@ -320,7 +410,36 @@ impl MptNode { /// storage or transmission purposes. #[inline] pub fn reference(&self) -> MptNodeReference { - self.cached_reference.borrow_mut().get_or_insert_with(|| self.calc_reference()).clone() + self.cached_reference.lock().unwrap().get_or_insert_with(|| self.calc_reference()).clone() + } + + pub fn for_each_leaves(&self, mut f: F) { + let mut stack = vec![(self, Nibbles::default())]; + + while let Some((node, path)) = stack.pop() { + match node.as_data() { + MptNodeData::Null | MptNodeData::Digest(_) => (), + MptNodeData::Branch(branch) => { + for (i, n) in + branch.iter().enumerate().filter_map(|(i, n)| n.as_ref().map(|n| (i, n))) + { + let mut new_path = path; + new_path.push(i as u8); + stack.push((n, new_path)); + } + } + MptNodeData::Leaf(prefix, value) => { + let mut full_path = path; + full_path.extend(&Nibbles::from_nibbles(prefix_nibs(prefix))); + f(&full_path.pack(), value) + } + MptNodeData::Extension(prefix, node) => { + let mut new_path = path; + new_path.extend(&Nibbles::from_nibbles(prefix_nibs(prefix))); + stack.push((node, new_path)); + } + } + } } /// Computes and returns the 256-bit hash of the node. @@ -330,12 +449,8 @@ impl MptNode { pub fn hash(&self) -> B256 { match self.data { MptNodeData::Null => EMPTY_ROOT, - _ => match self - .cached_reference - .borrow_mut() - .get_or_insert_with(|| self.calc_reference()) - { - MptNodeReference::Digest(digest) => *digest, + _ => match self.reference() { + MptNodeReference::Digest(digest) => digest, MptNodeReference::Bytes(bytes) => keccak(bytes).into(), }, } @@ -343,9 +458,9 @@ impl MptNode { /// Encodes the [MptNodeReference] of this node into the `out` buffer. fn reference_encode(&self, out: &mut dyn alloy_rlp::BufMut) { - match self.cached_reference.borrow_mut().get_or_insert_with(|| self.calc_reference()) { + match self.reference() { // if the reference is an RLP-encoded byte slice, copy it directly - MptNodeReference::Bytes(bytes) => out.put_slice(bytes), + MptNodeReference::Bytes(bytes) => out.put_slice(&bytes), // if the reference is a digest, RLP-encode it with its fixed known length MptNodeReference::Digest(digest) => { out.put_u8(alloy_rlp::EMPTY_STRING_CODE + 32); @@ -356,7 +471,7 @@ impl MptNode { /// Returns the length of the encoded [MptNodeReference] of this node. fn reference_length(&self) -> usize { - match self.cached_reference.borrow_mut().get_or_insert_with(|| self.calc_reference()) { + match self.reference() { MptNodeReference::Bytes(bytes) => bytes.len(), MptNodeReference::Digest(_) => 1 + 32, } @@ -711,7 +826,7 @@ impl MptNode { } fn invalidate_ref_cache(&mut self) { - self.cached_reference.borrow_mut().take(); + self.cached_reference.lock().unwrap().take(); } /// Returns the number of traversable nodes in the trie. @@ -1284,6 +1399,18 @@ mod tests { trie.get(b"a0").unwrap_err(); } + #[test] + pub fn test_for_each_leaves() { + let mut trie = MptNode::default(); + trie.insert(b"dog", b"puppy".to_vec()).unwrap(); + trie.insert(b"dock", b"boat".to_vec()).unwrap(); + + trie.for_each_leaves(|k, v| { + println!("key: {k:?}"); + println!("value: {v:?}"); + }); + } + #[test] pub fn test_branch_value() { let mut trie = MptNode::default(); diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index c5682f3..b2ae76d 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -17,6 +17,7 @@ reth-optimism-forks = { workspace = true, optional = true } reth-trie.workspace = true # alloy +alloy-eips.workspace = true alloy-genesis.workspace = true alloy-rpc-types.workspace = true diff --git a/crates/primitives/src/genesis.rs b/crates/primitives/src/genesis.rs index 06f7648..72e4c6b 100644 --- a/crates/primitives/src/genesis.rs +++ b/crates/primitives/src/genesis.rs @@ -1,5 +1,11 @@ +use alloy_eips::{eip7840::BlobParams, BlobScheduleBlobParams}; use eyre::eyre; -use reth_chainspec::{BaseFeeParams, BaseFeeParamsKind, Chain, ChainSpec, EthereumHardfork}; +use reth_chainspec::{ + mainnet::{MAINNET_BPO1_TIMESTAMP, MAINNET_BPO2_TIMESTAMP}, + sepolia::{SEPOLIA_BPO1_TIMESTAMP, SEPOLIA_BPO2_TIMESTAMP}, + BaseFeeParams, BaseFeeParamsKind, Chain, ChainSpec, EthereumHardfork, + MAINNET_PRUNE_DELETE_LIMIT, +}; use serde::{Deserialize, Serialize}; pub const LINEA_GENESIS_JSON: &str = include_str!("./genesis/59144.json"); @@ -70,8 +76,11 @@ impl TryFrom<&Genesis> for ChainSpec { hardforks: EthereumHardfork::mainnet().into(), deposit_contract: Default::default(), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), - prune_delete_limit: 20000, - blob_params: Default::default(), + prune_delete_limit: MAINNET_PRUNE_DELETE_LIMIT, + blob_params: BlobScheduleBlobParams::default().with_scheduled([ + (MAINNET_BPO1_TIMESTAMP, BlobParams::bpo1()), + (MAINNET_BPO2_TIMESTAMP, BlobParams::bpo2()), + ]), }; Ok(mainnet) @@ -86,7 +95,10 @@ impl TryFrom<&Genesis> for ChainSpec { deposit_contract: Default::default(), base_fee_params: BaseFeeParamsKind::Constant(BaseFeeParams::ethereum()), prune_delete_limit: 10000, - blob_params: Default::default(), + blob_params: BlobScheduleBlobParams::default().with_scheduled([ + (SEPOLIA_BPO1_TIMESTAMP, BlobParams::bpo1()), + (SEPOLIA_BPO2_TIMESTAMP, BlobParams::bpo2()), + ]), }; Ok(sepolia) } diff --git a/crates/primitives/src/genesis/2345.json b/crates/primitives/src/genesis/2345.json index cba561f..ade5ced 100644 --- a/crates/primitives/src/genesis/2345.json +++ b/crates/primitives/src/genesis/2345.json @@ -17,6 +17,7 @@ "shanghaiTime": 0, "cancunTime": 0, "pragueTime": 1753149600, + "osakaTime": 1766160000, "terminalTotalDifficulty": 0, "goat": {} }, diff --git a/crates/primitives/src/genesis/48816.json b/crates/primitives/src/genesis/48816.json index 6c61a6d..f765abc 100644 --- a/crates/primitives/src/genesis/48816.json +++ b/crates/primitives/src/genesis/48816.json @@ -17,6 +17,7 @@ "shanghaiTime": 0, "cancunTime": 0, "pragueTime": 1752544800, + "osakaTime": 1765810800, "terminalTotalDifficulty": 0, "goat": {} }, diff --git a/crates/storage/rpc-db/Cargo.toml b/crates/storage/rpc-db/Cargo.toml index 2ebf09e..4780e6c 100644 --- a/crates/storage/rpc-db/Cargo.toml +++ b/crates/storage/rpc-db/Cargo.toml @@ -5,23 +5,36 @@ version.workspace = true edition.workspace = true [dependencies] +async-trait.workspace = true tokio.workspace = true thiserror.workspace = true tracing.workspace = true +mpt.workspace = true +primitives.workspace = true + # reth reth-storage-errors.workspace = true # revm +revm-database.workspace = true revm-database-interface.workspace = true revm-primitives.workspace = true revm-state.workspace = true # alloy +alloy-consensus = { workspace = true, optional = true } alloy-primitives.workspace = true alloy-provider.workspace = true -alloy-rpc-types.workspace = true +alloy-transport.workspace = true +alloy-rlp = { workspace = true, optional = true } +alloy-trie = { workspace = true, optional = true, features = ["ethereum"] } -serde.workspace = true -serde_json.workspace = true -indexmap = { version = "2.9.0", features = ["serde"] } \ No newline at end of file +[features] +default = ["execution-witness"] +execution-witness = [ + "dep:alloy-consensus", + "dep:alloy-rlp", + "dep:alloy-trie", + "alloy-provider/debug-api" +] diff --git a/crates/storage/rpc-db/src/basic.rs b/crates/storage/rpc-db/src/basic.rs new file mode 100644 index 0000000..7d48991 --- /dev/null +++ b/crates/storage/rpc-db/src/basic.rs @@ -0,0 +1,311 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + marker::PhantomData, + sync::{Arc, RwLock}, +}; + +use alloy_consensus::{BlockHeader, Header}; +use alloy_primitives::{map::HashMap, U256}; +use alloy_provider::{ + network::{primitives::HeaderResponse, BlockResponse}, + Network, Provider, +}; +use async_trait::async_trait; +use mpt::EthereumState; +use primitives::account_proof::eip1186_proof_to_account_proof; +use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; +use revm_database::BundleState; +use revm_database_interface::DatabaseRef; +use revm_primitives::{Address, B256, KECCAK_EMPTY}; +use revm_state::{AccountInfo, Bytecode}; +use tracing::debug; + +use crate::{error::RpcDbError, RpcDb}; + +/// A database that fetches data from a [Provider] over a [Transport]. +#[derive(Debug, Clone)] +pub struct BasicRpcDb { + /// The provider which fetches data. + pub provider: P, + /// The block to fetch data from. + pub block_number: u64, + ///The state root to fetch data from. + pub state_root: B256, + /// The cached accounts. + pub accounts: Arc>>, + /// The cached storage values. + pub storage: Arc>>>, + /// The oldest block whose header/hash has been requested. + pub oldest_ancestor: Arc>, + + phantom: PhantomData, +} + +impl + Clone, N: Network> BasicRpcDb { + /// Create a new [`BasicRpcDb`]. + pub fn new(provider: P, block_number: u64, state_root: B256) -> Self { + Self { + provider, + block_number, + state_root, + accounts: Arc::new(RwLock::new(HashMap::with_hasher(Default::default()))), + storage: Arc::new(RwLock::new(HashMap::with_hasher(Default::default()))), + oldest_ancestor: Arc::new(RwLock::new(block_number)), + phantom: PhantomData, + } + } + + /// Fetch the [AccountInfo] for an [Address]. + pub async fn fetch_account_info(&self, address: Address) -> Result { + debug!("fetching account info for address: {}", address); + + // Fetch the proof for the account. + let proof = self + .provider + .get_proof(address, vec![]) + .number(self.block_number) + .await + .map_err(|e| RpcDbError::GetProofError(address, e.to_string()))?; + + // Fetch the code of the account. + let code = self + .provider + .get_code_at(address) + .number(self.block_number) + .await + .map_err(|e| RpcDbError::GetCodeError(address, e.to_string()))?; + + // Construct the account info & write it to the log. + let bytecode = Bytecode::new_raw(code); + + // Normalize code_hash for REVM compatibility: + // RPC response for getProof method for non-existing (unused) EOAs may contain B256::ZERO + // for code_hash, but REVM expects KECCAK_EMPTY + let code_hash = if proof.code_hash == B256::ZERO { KECCAK_EMPTY } else { proof.code_hash }; + + let account_info = AccountInfo { + nonce: proof.nonce, + balance: proof.balance, + code_hash, + code: Some(bytecode.clone()), + }; + + // Record the account info to the state. + self.accounts + .write() + .map_err(|_| RpcDbError::Poisoned)? + .insert(address, account_info.clone()); + + Ok(account_info) + } + + /// Fetch the storage value at an [Address] and [U256] index. + pub async fn fetch_storage_at( + &self, + address: Address, + index: U256, + ) -> Result { + debug!("fetching storage value at address: {}, index: {}", address, index); + + // Fetch the storage value. + let value = self + .provider + .get_storage_at(address, index) + .number(self.block_number) + .await + .map_err(|e| RpcDbError::GetStorageError(address, index, e.to_string()))?; + + // Record the storage value to the state. + let mut storage_values = self.storage.write().map_err(|_| RpcDbError::Poisoned)?; + let entry = storage_values.entry(address).or_default(); + entry.insert(index, value); + + Ok(value) + } + + /// Fetch the block hash for a block number. + pub async fn fetch_block_hash(&self, number: u64) -> Result { + debug!("fetching block hash for block number: {}", number); + + // Fetch the block. + let block = self + .provider + .get_block_by_number(number.into()) + .await + .map_err(|e| RpcDbError::GetBlockError(number, e.to_string()))?; + + // Record the block hash to the state. + let block = block.ok_or(RpcDbError::BlockNotFound(number))?; + let hash = block.header().hash(); + + let mut oldest_ancestor = self.oldest_ancestor.write().map_err(|_| RpcDbError::Poisoned)?; + *oldest_ancestor = number.min(*oldest_ancestor); + + Ok(hash) + } + + /// Gets all the state keys used. The client uses this to read the actual state data from tries. + pub fn get_state_requests(&self) -> HashMap> { + let accounts = self.accounts.read().unwrap(); + let storage = self.storage.read().unwrap(); + + accounts + .keys() + .chain(storage.keys()) + .map(|&address| { + let storage_keys_for_address: BTreeSet = storage + .get(&address) + .map(|storage_map| storage_map.keys().cloned().collect()) + .unwrap_or_default(); + + (address, storage_keys_for_address.into_iter().collect()) + }) + .collect() + } +} + +impl + Clone, N: Network> DatabaseRef for BasicRpcDb { + type Error = ProviderError; + + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + let handle = tokio::runtime::Handle::try_current().map_err(|_| { + ProviderError::Database(DatabaseError::Other("no tokio runtime found".to_string())) + })?; + let result = + tokio::task::block_in_place(|| handle.block_on(self.fetch_account_info(address))); + let account_info = + result.map_err(|e| ProviderError::Database(DatabaseError::Other(e.to_string())))?; + Ok(Some(account_info)) + } + + fn code_by_hash_ref(&self, _code_hash: B256) -> Result { + unimplemented!() + } + + fn storage_ref(&self, address: Address, index: U256) -> Result { + let handle = tokio::runtime::Handle::try_current().map_err(|_| { + ProviderError::Database(DatabaseError::Other("no tokio runtime found".to_string())) + })?; + let result = + tokio::task::block_in_place(|| handle.block_on(self.fetch_storage_at(address, index))); + let value = + result.map_err(|e| ProviderError::Database(DatabaseError::Other(e.to_string())))?; + Ok(value) + } + + fn block_hash_ref(&self, number: u64) -> Result { + let handle = tokio::runtime::Handle::try_current().map_err(|_| { + ProviderError::Database(DatabaseError::Other("no tokio runtime found".to_string())) + })?; + let result = tokio::task::block_in_place(|| handle.block_on(self.fetch_block_hash(number))); + let value = + result.map_err(|e| ProviderError::Database(DatabaseError::Other(e.to_string())))?; + Ok(value) + } +} + +#[async_trait] +impl RpcDb for BasicRpcDb +where + P: Provider + Clone, + N: Network, +{ + async fn state(&self, bundle_state: &BundleState) -> Result { + let state_requests = self.get_state_requests(); + + // For every account we touched, fetch the storage proofs for all the slots we touched. + tracing::info!("fetching storage proofs"); + let mut before_storage_proofs = Vec::new(); + let mut after_storage_proofs = Vec::new(); + + for (address, used_keys) in state_requests.iter() { + let modified_keys = bundle_state + .state + .get(address) + .map(|account| { + account.storage.keys().map(|key| B256::from(*key)).collect::>() + }) + .unwrap_or_default() + .into_iter() + .collect::>(); + + let keys = used_keys + .iter() + .map(|key| B256::from(*key)) + .chain(modified_keys.clone().into_iter()) + .collect::>() + .into_iter() + .collect::>(); + + let storage_proof = + self.provider.get_proof(*address, keys.clone()).number(self.block_number).await?; + before_storage_proofs.push(eip1186_proof_to_account_proof(storage_proof)); + + let storage_proof = self + .provider + .get_proof(*address, modified_keys) + .number(self.block_number + 1) + .await?; + after_storage_proofs.push(eip1186_proof_to_account_proof(storage_proof)); + } + + let state = EthereumState::from_transition_proofs( + self.state_root, + &before_storage_proofs.iter().map(|item| (item.address, item.clone())).collect(), + &after_storage_proofs.iter().map(|item| (item.address, item.clone())).collect(), + )?; + + Ok(state) + } + + fn bytecodes(&self) -> Vec { + let accounts = self.accounts.read().unwrap(); + + accounts + .values() + .flat_map(|account| account.code.clone()) + .map(|code| (code.hash_slow(), code)) + .collect::>() + .into_values() + .collect::>() + } + + async fn ancestor_headers(&self) -> Result, RpcDbError> { + let oldest_ancestor = *self.oldest_ancestor.read().unwrap(); + let mut ancestor_headers = vec![]; + tracing::info!("fetching {} ancestor headers", (self.block_number + 1) - oldest_ancestor); + for height in (oldest_ancestor..=(self.block_number)).rev() { + let block = self + .provider + .get_block_by_number(height.into()) + .await? + .ok_or(RpcDbError::BlockNotFound(height))?; + + ancestor_headers.push(Header { + parent_hash: block.header().parent_hash(), + ommers_hash: block.header().ommers_hash(), + beneficiary: block.header().beneficiary(), + state_root: block.header().state_root(), + transactions_root: block.header().transactions_root(), + receipts_root: block.header().receipts_root(), + logs_bloom: block.header().logs_bloom(), + difficulty: block.header().difficulty(), + number: block.header().number(), + gas_limit: block.header().gas_limit(), + gas_used: block.header().gas_used(), + timestamp: block.header().timestamp(), + extra_data: block.header().extra_data().clone(), + mix_hash: block.header().mix_hash().unwrap_or_default(), + nonce: block.header().nonce().unwrap_or_default(), + base_fee_per_gas: block.header().base_fee_per_gas(), + withdrawals_root: block.header().withdrawals_root(), + blob_gas_used: block.header().blob_gas_used(), + excess_blob_gas: block.header().excess_blob_gas(), + parent_beacon_block_root: block.header().parent_beacon_block_root(), + requests_hash: block.header().requests_hash(), + }); + } + + Ok(ancestor_headers) + } +} diff --git a/crates/storage/rpc-db/src/error.rs b/crates/storage/rpc-db/src/error.rs new file mode 100644 index 0000000..b62dc7c --- /dev/null +++ b/crates/storage/rpc-db/src/error.rs @@ -0,0 +1,26 @@ +use alloy_transport::TransportError; +use mpt::FromProofError; +use revm_primitives::{Address, U256}; + +/// Errors that can occur when interacting with the [RpcDb]. +#[derive(Debug, thiserror::Error)] +pub enum RpcDbError { + #[error("Transport Error: {}", .0)] + Transport(#[from] TransportError), + #[error("From proof Error: {}", .0)] + FromProof(#[from] FromProofError), + #[error("failed fetch proof at {0}: {1}")] + GetProofError(Address, String), + #[error("failed to fetch code at {0}: {1}")] + GetCodeError(Address, String), + #[error("failed to fetch storage at {0}, index {1}: {2}")] + GetStorageError(Address, U256, String), + #[error("failed to fetch block {0}: {1}")] + GetBlockError(u64, String), + #[error("failed to find block {0}")] + BlockNotFound(u64), + #[error("failed to find trie node preimage")] + PreimageNotFound, + #[error("poisoned lock")] + Poisoned, +} diff --git a/crates/storage/rpc-db/src/execution_witness.rs b/crates/storage/rpc-db/src/execution_witness.rs new file mode 100644 index 0000000..b7e5105 --- /dev/null +++ b/crates/storage/rpc-db/src/execution_witness.rs @@ -0,0 +1,139 @@ +use std::marker::PhantomData; + +use alloy_consensus::Header; +use alloy_primitives::{map::HashMap, Address, B256}; +use alloy_provider::{ext::DebugApi, Network, Provider}; +use alloy_rlp::Decodable; +use alloy_trie::TrieAccount; +use async_trait::async_trait; +use mpt::EthereumState; +use reth_storage_errors::ProviderError; +use revm_database::{BundleState, DatabaseRef}; +use revm_primitives::{keccak256, ruint::aliases::U256, StorageKey, StorageValue}; +use revm_state::{AccountInfo, Bytecode}; + +use crate::{RpcDb, RpcDbError}; + +#[derive(Debug)] +pub struct ExecutionWitnessRpcDb { + /// The provider which fetches data. + pub provider: P, + /// The cached state. + pub state: EthereumState, + /// The cached bytecodes. + pub codes: HashMap, + + pub ancestor_headers: HashMap, + + phantom: PhantomData, +} + +impl + Clone, N: Network> ExecutionWitnessRpcDb { + /// Create a new [`ExecutionWitnessRpcDb`]. + pub async fn new(provider: P, block_number: u64, state_root: B256) -> Result { + let execution_witness = provider.debug_execution_witness((block_number + 1).into()).await?; + + let state = EthereumState::from_execution_witness(&execution_witness, state_root); + + let codes = execution_witness + .codes + .iter() + .map(|encoded| (keccak256(encoded), Bytecode::new_raw(encoded.clone()))) + .collect(); + + let ancestor_headers = execution_witness + .headers + .iter() + .map(|encoded| Header::decode(&mut encoded.as_ref()).unwrap()) + .map(|h| (h.number, h)) + .collect(); + + let db = Self { provider, state, codes, ancestor_headers, phantom: PhantomData }; + + Ok(db) + } +} + +impl + Clone, N: Network> DatabaseRef for ExecutionWitnessRpcDb { + type Error = ProviderError; + + fn basic_ref(&self, address: Address) -> Result, Self::Error> { + let hash = keccak256(address); + if let Some(mut bytes) = self + .state + .state_trie + .get(hash.as_ref()) + .map_err(|err| ProviderError::TrieWitnessError(err.to_string()))? + { + let account = TrieAccount::decode(&mut bytes)?; + let account_info = AccountInfo { + balance: account.balance, + nonce: account.nonce, + code_hash: account.code_hash, + code: None, + }; + + Ok(Some(account_info)) + } else { + Ok(None) + } + } + + fn code_by_hash_ref(&self, code_hash: B256) -> Result { + self.codes + .get(&code_hash) + .ok_or_else(|| { + ProviderError::TrieWitnessError(format!("Code not found for {code_hash}")) + }) + .cloned() + } + + fn storage_ref( + &self, + address: Address, + index: StorageKey, + ) -> Result { + let slot = B256::from(index); + let hashed_address = keccak256(address); + let hashed_slot = keccak256(slot); + if let Some(mut value) = self + .state + .storage_tries + .get(&hashed_address) + .and_then(|storage_trie| storage_trie.get(hashed_slot.as_slice()).unwrap()) + { + Ok(U256::decode(&mut value)?) + } else { + Ok(U256::ZERO) + } + } + + fn block_hash_ref(&self, number: u64) -> Result { + let header = self.ancestor_headers.get(&number).ok_or_else(|| { + ProviderError::TrieWitnessError(format!("Header {number} not found in the ancestors")) + })?; + + Ok(header.hash_slow()) + } +} + +#[async_trait] +impl RpcDb for ExecutionWitnessRpcDb +where + P: Provider + Clone, + N: Network, +{ + async fn state(&self, _bundle_state: &BundleState) -> Result { + Ok(self.state.clone()) + } + + fn bytecodes(&self) -> Vec { + self.codes.values().cloned().collect() + } + + async fn ancestor_headers(&self) -> Result, RpcDbError> { + let mut ancestor_headers: Vec
= self.ancestor_headers.values().cloned().collect(); + ancestor_headers.sort_by(|a, b| b.number.cmp(&a.number)); + Ok(ancestor_headers) + } +} diff --git a/crates/storage/rpc-db/src/lib.rs b/crates/storage/rpc-db/src/lib.rs index e757a23..74ad858 100644 --- a/crates/storage/rpc-db/src/lib.rs +++ b/crates/storage/rpc-db/src/lib.rs @@ -1,352 +1,30 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] -use std::sync::{Arc, RwLock}; -use alloy_primitives::{map::HashMap, private::serde::Deserialize, Bytes, U256}; -use alloy_provider::{ - network::{primitives::HeaderResponse, BlockResponse}, - Network, Provider, -}; -use alloy_rpc_types::BlockId; -use indexmap::IndexMap; -use reth_storage_errors::{db::DatabaseError, provider::ProviderError}; -use revm_database_interface::DatabaseRef; -use revm_primitives::{Address, B256}; -use revm_state::{AccountInfo, Bytecode}; -use std::{ - collections::{BTreeMap, BTreeSet}, - marker::PhantomData, -}; -use tracing::{debug, info}; +use alloy_consensus::Header; +use alloy_provider::Network; +use async_trait::async_trait; +use mpt::EthereumState; +use revm_database::{BundleState, DatabaseRef}; +use revm_state::Bytecode; -/// A database that fetches data from a [Provider] over a [Transport]. -#[derive(Debug, Clone)] -pub struct RpcDb { - /// The provider which fetches data. - pub provider: P, - /// The provider which fetches debug info. - pub debug_provider: P, - /// The block to fetch data from. - pub block: BlockId, - /// The cached accounts. - pub accounts: Arc>>, - /// The cached storage values. - pub storage: Arc>>>, - /// The oldest block whose header/hash has been requested. - pub oldest_ancestor: Arc>, +mod basic; +pub use basic::BasicRpcDb; - phantom: std::marker::PhantomData, -} - -/// Top-level RPC response from debug_traceBlockByNumber with prestate enabled -#[derive(Debug, Clone, Deserialize)] -pub struct PrestateTraceRpcResponse(pub Vec); - -/// A single transaction's trace prestate result -#[derive(Debug, Clone, Deserialize)] -pub struct PrestateTxTrace { - /// Transaction hash - #[serde(rename = "txHash")] - pub tx_hash: B256, - - /// Mapping of address -> account info (preserves insertion order) - pub result: IndexMap, -} - -/// An account's state at the start of the transaction execution -#[derive(Debug, Clone, Deserialize)] -pub struct PrestateAccount { - /// Account balance - pub balance: Option, - - /// Account nonce - pub nonce: Option, - - /// Account code, if present - pub code: Option, - - /// Optional storage slot mapping - pub storage: Option>, -} - -/// Errors that can occur when interacting with the [RpcDb]. -#[derive(Debug, Clone, thiserror::Error)] -pub enum RpcDbError { - #[error("failed fetch proof at {0}: {1}")] - GetProofError(Address, String), - #[error("failed to fetch code at {0}: {1}")] - GetCodeError(Address, String), - #[error("failed to fetch storage at {0}, index {1}: {2}")] - GetStorageError(Address, U256, String), - #[error("failed to fetch block {0}: {1}")] - GetBlockError(u64, String), - #[error("failed to find block")] - BlockNotFound, - #[error("failed to find trie node preimage")] - PreimageNotFound, - #[error("poisoned lock")] - Poisoned, -} - -impl + Clone, N: Network> RpcDb { - /// Create a new [`RpcDb`]. - pub fn new(provider: P, debug_provider: P, block: u64) -> Self { - RpcDb { - provider, - debug_provider, - block: block.into(), - accounts: Arc::new(RwLock::new(HashMap::with_hasher(Default::default()))), - storage: Arc::new(RwLock::new(HashMap::with_hasher(Default::default()))), - oldest_ancestor: Arc::new(RwLock::new(block)), - phantom: PhantomData, - } - } - - /// Fetch the [AccountInfo] for an [Address]. - pub async fn fetch_account_info(&self, address: Address) -> Result { - debug!("fetching account info for address: {}", address); - if let Some(account_info) = - self.accounts.read().map_err(|_| RpcDbError::Poisoned)?.get(&address).cloned() - { - debug!("fetching account info from cache for address: {}", address); - return Ok(account_info); - } - - // Fetch the proof for the account. - let proof = self - .provider - .get_proof(address, vec![]) - .block_id(self.block) - .await - .map_err(|e| RpcDbError::GetProofError(address, e.to_string()))?; - - // Fetch the code of the account. - let code = self - .provider - .get_code_at(address) - .block_id(self.block) - .await - .map_err(|e| RpcDbError::GetCodeError(address, e.to_string()))?; - - // Construct the account info & write it to the log. - let bytecode = Bytecode::new_raw(code); - let account_info = AccountInfo { - nonce: proof.nonce, - balance: proof.balance, - code_hash: proof.code_hash, - code: Some(bytecode.clone()), - }; - debug!( - "[fetch_account_info]fetching basic account info for address: {}, balance: {:?}, nonce: {:?}, code_hash: {:?}", - address, account_info.balance, account_info.nonce, account_info.code_hash - ); - - // Record the account info to the state. - self.accounts - .write() - .map_err(|_| RpcDbError::Poisoned)? - .insert(address, account_info.clone()); - - Ok(account_info) - } - - /// Fetch the storage value at an [Address] and [U256] index. - pub async fn fetch_storage_at( - &self, - address: Address, - index: U256, - ) -> Result { - debug!("fetching storage value at address: {}, index: {}", address, index); - if let Some(value) = self - .storage - .read() - .map_err(|_| RpcDbError::Poisoned)? - .get(&address) - .and_then(|inner| inner.get(&index).copied()) - { - debug!( - "fetching account info from cache for address {}, index {:x}, value {}", - address, index, value - ); - return Ok(value); - } - - // Fetch the storage value. - let value = self - .provider - .get_storage_at(address, index) - .block_id(self.block) - .await - .map_err(|e| RpcDbError::GetStorageError(address, index, e.to_string()))?; - debug!( - "[fetch_storage_at] fetching storage value at address: {}, index: {}, value {}", - address, index, value - ); - - // Record the storage value to the state. - let mut storage_values = self.storage.write().map_err(|_| RpcDbError::Poisoned)?; - let entry = storage_values.entry(address).or_default(); - entry.insert(index, value); +#[cfg(feature = "execution-witness")] +mod execution_witness; +#[cfg(feature = "execution-witness")] +pub use execution_witness::ExecutionWitnessRpcDb; - Ok(value) - } +mod error; +pub use error::RpcDbError; - /// Fetch the block hash for a block number. - pub async fn fetch_block_hash(&self, number: u64) -> Result { - debug!("fetching block hash for block number: {}", number); - - // Fetch the block. - let block = self - .provider - .get_block_by_number(number.into()) - .await - .map_err(|e| RpcDbError::GetBlockError(number, e.to_string()))?; - - // Record the block hash to the state. - let block = block.ok_or(RpcDbError::BlockNotFound)?; - let hash = block.header().hash(); - - let mut oldest_ancestor = self.oldest_ancestor.write().map_err(|_| RpcDbError::Poisoned)?; - *oldest_ancestor = number.min(*oldest_ancestor); - - Ok(hash) - } - - /// Preloads accounts and storage for the current block. - /// We use debug_provider. - pub async fn preload_accounts_and_storage(&self) -> Result<(), RpcDbError> { - info!("Preloading accounts and storage for block: {}", self.block); - let current_block = self.block.as_u64().unwrap() + 1; - let params = ( - format!("0x{current_block:x}"), - serde_json::json!({ - "disableStorage": false, - "disableMemory": true, - "disableStack": true, - "tracer": "prestateTracer" - }), - ); - - let now = std::time::Instant::now(); - // TODO: use debug_traceTransaction in parallel instead of debug_traceBlockByNumber - let prestate: PrestateTraceRpcResponse = self - .debug_provider - .raw_request("debug_traceBlockByNumber".into(), params) - .await - .map_err(|e| RpcDbError::GetBlockError(current_block, e.to_string()))?; - info!("rpc request took: {:?}, got {} txs", now.elapsed(), prestate.0.len()); - - for tx_trace in prestate.0 { - for (address, account) in tx_trace.result { - // Fix error "TransferError::CreateCollision" in revm. - if account.nonce == Some(1) { - continue; - } - - if !self.accounts.read().map_err(|_| RpcDbError::Poisoned)?.contains_key(&address) { - let bytecode = account.code.clone().map(Bytecode::new_raw); - // Some RPC will return incorrect code and nonce for accounts with EIP-7702, - // we will ignore these accounts. - // This is a temporary fix - if bytecode.as_ref().is_some_and(|bc| bc.is_eip7702()) { - continue; - } - - let account_info = AccountInfo::from_bytecode(bytecode.unwrap_or_default()) - .with_balance(account.balance.unwrap_or_default()) - .with_nonce(account.nonce.unwrap_or_default()); - - self.accounts - .write() - .map_err(|_| RpcDbError::Poisoned)? - .entry(address) - .or_insert(account_info); - } - - if let Some(storage_map) = account.storage { - let mut storage_lock = - self.storage.write().map_err(|_| RpcDbError::Poisoned)?; - let account_storage = storage_lock - .entry(address) - .or_insert_with(|| HashMap::with_hasher(Default::default())); - - for (slot, value) in storage_map { - account_storage.entry(slot).or_insert(value); - } - } - } - } - Ok(()) - } - - /// Gets all the state keys used. The client uses this to read the actual state data from tries. - pub fn get_state_requests(&self) -> HashMap> { - let accounts = self.accounts.read().unwrap(); - let storage = self.storage.read().unwrap(); - - accounts - .keys() - .chain(storage.keys()) - .map(|&address| { - let storage_keys_for_address: BTreeSet = storage - .get(&address) - .map(|storage_map| storage_map.keys().cloned().collect()) - .unwrap_or_default(); - - (address, storage_keys_for_address.into_iter().collect()) - }) - .collect() - } +#[async_trait] +pub trait RpcDb: DatabaseRef { + async fn state(&self, bundle_state: &BundleState) -> Result; /// Gets all account bytecodes. - pub fn get_bytecodes(&self) -> Vec { - let accounts = self.accounts.read().unwrap(); - - accounts - .values() - .flat_map(|account| account.code.clone()) - .map(|code| (code.hash_slow(), code)) - .collect::>() - .into_values() - .collect::>() - } -} - -impl + Clone, N: Network> DatabaseRef for RpcDb { - type Error = ProviderError; - - fn basic_ref(&self, address: Address) -> Result, Self::Error> { - let handle = tokio::runtime::Handle::try_current().map_err(|_| { - ProviderError::Database(DatabaseError::Other("no tokio runtime found".to_string())) - })?; - let result = - tokio::task::block_in_place(|| handle.block_on(self.fetch_account_info(address))); - let account_info = - result.map_err(|e| ProviderError::Database(DatabaseError::Other(e.to_string())))?; - Ok(Some(account_info)) - } - - fn code_by_hash_ref(&self, _code_hash: B256) -> Result { - unimplemented!() - } - - fn storage_ref(&self, address: Address, index: U256) -> Result { - let handle = tokio::runtime::Handle::try_current().map_err(|_| { - ProviderError::Database(DatabaseError::Other("no tokio runtime found".to_string())) - })?; - let result = - tokio::task::block_in_place(|| handle.block_on(self.fetch_storage_at(address, index))); - let value = - result.map_err(|e| ProviderError::Database(DatabaseError::Other(e.to_string())))?; - Ok(value) - } + fn bytecodes(&self) -> Vec; - fn block_hash_ref(&self, number: u64) -> Result { - let handle = tokio::runtime::Handle::try_current().map_err(|_| { - ProviderError::Database(DatabaseError::Other("no tokio runtime found".to_string())) - })?; - let result = tokio::task::block_in_place(|| handle.block_on(self.fetch_block_hash(number))); - let value = - result.map_err(|e| ProviderError::Database(DatabaseError::Other(e.to_string())))?; - Ok(value) - } + // Fetches the parent headers needed to constrain the BLOCKHASH opcode. + async fn ancestor_headers(&self) -> Result, RpcDbError>; } diff --git a/crates/storage/witness-db/Cargo.toml b/crates/storage/witness-db/Cargo.toml index 9362d81..ee0b9af 100644 --- a/crates/storage/witness-db/Cargo.toml +++ b/crates/storage/witness-db/Cargo.toml @@ -16,4 +16,4 @@ reth-storage-errors.workspace = true # revm revm-database-interface.workspace = true revm-primitives.workspace = true -revm-state = { workspace = true, features = ["serde"] } \ No newline at end of file +revm-state = { workspace = true, features = ["serde"] }