From 9e19b0d14e43c685c0da481d5bc5c290020f9908 Mon Sep 17 00:00:00 2001 From: Ion Suman <47307091+isum@users.noreply.github.com> Date: Wed, 30 Oct 2024 20:30:11 +0200 Subject: [PATCH] migrate from `ethabi` to `alloy` --- Cargo.lock | 1346 ++++++++++++++++- Cargo.toml | 1 + chain/ethereum/src/adapter.rs | 24 +- chain/ethereum/src/data_source.rs | 164 +- chain/ethereum/src/ethereum_adapter.rs | 38 +- chain/ethereum/src/ingestor.rs | 4 +- chain/ethereum/src/runtime/abi.rs | 9 +- chain/ethereum/src/runtime/runtime_adapter.rs | 63 +- chain/ethereum/src/trigger.rs | 35 +- graph/Cargo.toml | 2 +- graph/src/abi/decoded_param.rs | 51 + graph/src/abi/decoded_value.rs | 50 + graph/src/abi/mod.rs | 23 + graph/src/cheap_clone.rs | 2 +- graph/src/components/adapter.rs | 2 +- graph/src/components/store/mod.rs | 2 +- graph/src/data/store/ethereum.rs | 4 +- graph/src/lib.rs | 4 +- runtime/test/src/common.rs | 6 +- runtime/test/src/test/abi.rs | 34 +- runtime/wasm/Cargo.toml | 1 - runtime/wasm/src/asc_abi/class.rs | 30 +- runtime/wasm/src/host_exports.rs | 18 +- runtime/wasm/src/to_from/external.rs | 94 +- store/postgres/src/chain_store.rs | 2 +- store/test-store/Cargo.toml | 1 + store/test-store/tests/postgres/store.rs | 24 +- tests/src/fixture/ethereum.rs | 18 +- tests/src/fixture/mod.rs | 2 +- tests/tests/runner_tests.rs | 2 +- 30 files changed, 1694 insertions(+), 362 deletions(-) create mode 100644 graph/src/abi/decoded_param.rs create mode 100644 graph/src/abi/decoded_value.rs create mode 100644 graph/src/abi/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 00762bcea58..1ef70023508 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,6 +43,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if 1.0.0", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -57,6 +58,459 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "alloy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea8ebf106e84a1c37f86244df7da0c7587e697b71a0d565cce079449b85ac6f8" +dependencies = [ + "alloy-consensus", + "alloy-core", + "alloy-eips", + "alloy-genesis", + "alloy-provider", + "alloy-rpc-client", + "alloy-serde", + "alloy-transport-http", +] + +[[package]] +name = "alloy-chains" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c660915971620592abe2c292c859957eb60e73a60c0eba34a6793eea60512cff" +dependencies = [ + "alloy-primitives", + "num_enum", + "strum", +] + +[[package]] +name = "alloy-consensus" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed961a48297c732a5d97ee321aa8bb5009ecadbcb077d8bec90cb54e651629" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "auto_impl", + "c-kzg", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-core" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72bf30967a232bec83809bea1623031f6285a013096229330c68c406192a4ca" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", +] + +[[package]] +name = "alloy-dyn-abi" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5228b189b18b85761340dc9eaac0141148a8503657b36f9bc3a869413d987ca" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-type-parser", + "alloy-sol-types", + "const-hex", + "itoa", + "serde", + "serde_json", + "winnow 0.6.13", +] + +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ffc577390ce50234e02d841214b3dc0bea6aaaae8e04bbf3cb82e9a45da9eb" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-eips" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69e06cf9c37be824b9d26d6d101114fdde6af0c87de2828b414c05c4b3daa71" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2", +] + +[[package]] +name = "alloy-genesis" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde15e14944a88bd6a57d325e9a49b75558746fe16aaccc79713ae50a6a9574c" +dependencies = [ + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31a0f0d51db8a1a30a4d98a9f90e090a94c8f44cb4d9eafc7e03aa6d00aae984" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af5979e0d5a7bf9c7eb79749121e8256e59021af611322aee56e77e20776b4b3" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "204237129086ce5dc17a58025e93739b01b45313841f98fa339eb1d780511e57" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "thiserror", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514f70ee2a953db21631cd817b13a1571474ec77ddc03d47616d5e8203489fde" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-primitives" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8edae627382349b56cd6a7a2106f4fd69b243a9233e560c55c2e03cabb7e1d3c" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if 1.0.0", + "const-hex", + "derive_more 1.0.0", + "foldhash", + "hashbrown 0.15.0", + "hex-literal 0.4.1", + "indexmap 2.6.0", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand", + "ruint", + "rustc-hash 2.0.0", + "serde", + "sha3", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "alloy-provider" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4814d141ede360bb6cd1b4b064f1aab9de391e7c4d0d4d50ac89ea4bc1e25fbd" +dependencies = [ + "alloy-chains", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-client", + "alloy-rpc-types-eth", + "alloy-transport", + "alloy-transport-http", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures 0.3.30", + "futures-utils-wasm", + "lru", + "parking_lot", + "pin-project", + "reqwest", + "schnellru", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0822426598f95e45dd1ea32a738dac057529a709ee645fcc516ffa4cbde08f" +dependencies = [ + "alloy-rlp-derive", + "arrayvec 0.7.4", + "bytes", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b09cae092c27b6f1bde952653a22708691802e57bfef4a2973b80bea21efd3f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.69", +] + +[[package]] +name = "alloy-rpc-client" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc2bd1e7403463a5f2c61e955bcc9d3072b63aa177442b0f9aa6a6d22a941e3" +dependencies = [ + "alloy-json-rpc", + "alloy-primitives", + "alloy-transport", + "alloy-transport-http", + "futures 0.3.30", + "pin-project", + "reqwest", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower 0.5.0", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b034779a4850b4b03f5be5ea674a1cf7d746b2da762b34d1860ab45e48ca27" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "derive_more 1.0.0", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028e72eaa9703e4882344983cfe7636ce06d8cce104a78ea62fd19b46659efc4" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592c185d7100258c041afac51877660c7bf6213447999787197db4842f0e938e" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841eabaa4710f719fddbc24c95d386eae313f07e6da4babc25830ee37945be0c" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.69", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6672337f19d837b9f7073c45853aeb528ed9f7dd6a4154ce683e9e5cb7794014" +dependencies = [ + "alloy-json-abi", + "alloy-sol-macro-input", + "const-hex", + "heck 0.5.0", + "indexmap 2.6.0", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.69", + "syn-solidity", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dff37dd20bfb118b777c96eda83b2067f4226d2644c5cfa00187b3bc01770ba" +dependencies = [ + "alloy-json-abi", + "const-hex", + "dunce", + "heck 0.5.0", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.69", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b853d42292dbb159671a3edae3b2750277ff130f32b726fe07dc2b17aa6f2b5" +dependencies = [ + "serde", + "winnow 0.6.13", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa828bb1b9a6dc52208fbb18084fb9ce2c30facc2bfda6a5d922349b4990354f" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-transport" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be77579633ebbc1266ae6fd7694f75c408beb1aeb6865d0b18f22893c265a061" +dependencies = [ + "alloy-json-rpc", + "base64 0.22.1", + "futures-util", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower 0.5.0", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-transport-http" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fd1a5d0827939847983b46f2f79510361f901dc82f8e3c38ac7397af142c6e" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "reqwest", + "serde_json", + "tower 0.5.0", + "tracing", + "url", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -67,77 +521,201 @@ checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" name = "android_system_properties" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "libc", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.4.0", + "zeroize", ] [[package]] -name = "anstream" -version = "0.6.14" +name = "ark-ff-asm" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", + "quote", + "syn 1.0.109", ] [[package]] -name = "anstyle" -version = "1.0.7" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "anstyle-parse" -version = "0.2.4" +name = "ark-ff-macros" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" dependencies = [ - "utf8parse", + "num-bigint 0.4.6", + "num-traits", + "quote", + "syn 1.0.109", ] [[package]] -name = "anstyle-query" -version = "1.1.0" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ - "windows-sys 0.52.0", + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "anstyle-wincon" -version = "3.0.3" +name = "ark-serialize" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" dependencies = [ - "anstyle", - "windows-sys 0.52.0", + "ark-std 0.3.0", + "digest 0.9.0", ] [[package]] -name = "anyhow" -version = "1.0.86" +name = "ark-serialize" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.6", +] [[package]] -name = "arbitrary" -version = "1.3.2" +name = "ark-std" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand", +] [[package]] -name = "arc-swap" -version = "1.7.1" +name = "ark-std" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] [[package]] name = "arrayref" @@ -199,7 +777,7 @@ dependencies = [ "futures-util", "handlebars", "http 1.1.0", - "indexmap 2.2.6", + "indexmap 2.6.0", "mime", "multer", "num-traits", @@ -269,7 +847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef5ec94176a12a8cbe985cd73f2e54dc9c702c88c766bdef12f1f3a67cedbee1" dependencies = [ "bytes", - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_json", ] @@ -330,6 +908,17 @@ version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41e67cd8309bbd06cd603a9e693a784ac2e5d1e955f11286e355089fcab3047c" +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.69", +] + [[package]] name = "autocfg" version = "1.3.0" @@ -460,6 +1049,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -487,6 +1082,12 @@ dependencies = [ "base64 0.22.1", ] +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "beef" version = "0.5.2" @@ -528,6 +1129,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitflags" version = "1.3.2" @@ -598,6 +1214,18 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blst" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + [[package]] name = "bs58" version = "0.4.0" @@ -641,6 +1269,21 @@ dependencies = [ "serde", ] +[[package]] +name = "c-kzg" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + [[package]] name = "cc" version = "1.0.105" @@ -766,6 +1409,25 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "const-hex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -1007,6 +1669,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -1083,6 +1757,20 @@ dependencies = [ "syn 2.0.69", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1142,6 +1830,16 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "930c7171c8df9fb1782bdf9b918ed9ed2d33d1d22300abb754f9085bc48bf8e8" +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -1172,8 +1870,29 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version", + "rustc_version 0.4.0", + "syn 2.0.69", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", "syn 2.0.69", + "unicode-xid", ] [[package]] @@ -1279,6 +1998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] @@ -1349,12 +2069,51 @@ dependencies = [ "syn 2.0.69", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + [[package]] name = "either" version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -1453,7 +2212,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" dependencies = [ "crunchy", - "fixed-hash", + "fixed-hash 0.7.0", "impl-rlp", "impl-serde", "tiny-keccak 2.0.2", @@ -1466,10 +2225,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" dependencies = [ "ethbloom", - "fixed-hash", + "fixed-hash 0.7.0", "impl-rlp", "impl-serde", - "primitive-types", + "primitive-types 0.11.1", "uint 0.9.5", ] @@ -1500,6 +2259,27 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec 0.7.4", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "firestorm" version = "0.4.6" @@ -1524,6 +2304,18 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand", + "rustc-hex", + "static_assertions", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -1546,6 +2338,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -1678,6 +2476,12 @@ dependencies = [ "slab", ] +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + [[package]] name = "fxhash" version = "0.2.1" @@ -1708,6 +2512,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1728,7 +2533,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" dependencies = [ "fallible-iterator 0.3.0", - "indexmap 2.2.6", + "indexmap 2.6.0", "stable_deref_trait", ] @@ -1760,6 +2565,12 @@ dependencies = [ "time", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "globset" version = "0.4.14" @@ -1778,6 +2589,7 @@ name = "graph" version = "0.35.0" dependencies = [ "Inflector", + "alloy", "anyhow", "async-stream", "async-trait", @@ -1794,7 +2606,6 @@ dependencies = [ "diesel", "diesel_derives", "envconfig", - "ethabi", "futures 0.1.31", "futures 0.3.30", "graph_derive", @@ -1825,7 +2636,7 @@ dependencies = [ "rand", "regex", "reqwest", - "semver", + "semver 1.0.23", "serde", "serde_derive", "serde_json", @@ -1891,7 +2702,7 @@ dependencies = [ "graph-runtime-wasm", "prost 0.12.6", "prost-types 0.12.6", - "semver", + "semver 1.0.23", "serde", "tonic-build", ] @@ -1911,7 +2722,7 @@ dependencies = [ "jsonrpc-core", "prost 0.12.6", "prost-types 0.12.6", - "semver", + "semver 1.0.23", "serde", "tiny-keccak 1.5.0", "tonic-build", @@ -1961,7 +2772,7 @@ dependencies = [ "lazy_static", "prost 0.12.6", "prost-types 0.12.6", - "semver", + "semver 1.0.23", "serde", "tokio", "tonic-build", @@ -2060,7 +2871,7 @@ dependencies = [ "graph-runtime-derive", "graph-runtime-wasm", "rand", - "semver", + "semver 1.0.23", "test-store", "wasmtime", ] @@ -2072,13 +2883,12 @@ dependencies = [ "anyhow", "async-trait", "bs58", - "ethabi", "graph", "graph-runtime-derive", "hex", "never", "parity-wasm", - "semver", + "semver 1.0.23", "uuid", "wasm-instrument", "wasmtime", @@ -2147,7 +2957,7 @@ dependencies = [ "blake3 1.5.1", "chrono", "clap", - "derive_more", + "derive_more 0.99.18", "diesel", "diesel-derive-enum", "diesel-dynamic-schema", @@ -2281,6 +3091,17 @@ dependencies = [ "serde_with", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "h2" version = "0.3.26" @@ -2293,7 +3114,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.6.0", "slab", "tokio", "tokio-util 0.7.11", @@ -2312,7 +3133,7 @@ dependencies = [ "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.2.6", + "indexmap 2.6.0", "slab", "tokio", "tokio-util 0.7.11", @@ -2357,6 +3178,18 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", + "serde", +] + [[package]] name = "hdrhistogram" version = "7.5.4" @@ -2752,12 +3585,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", "serde", ] @@ -2956,6 +3789,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", +] + [[package]] name = "keccak" version = "0.1.5" @@ -2965,6 +3811,16 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -2983,6 +3839,12 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +[[package]] +name = "libm" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00419de735aac21d53b0de5ce2c03bd3627277cf471300f27ebc89f7d828047" + [[package]] name = "libredox" version = "0.1.3" @@ -3015,6 +3877,15 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.0", +] + [[package]] name = "lru_time_cache" version = "0.11.11" @@ -3262,6 +4133,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -3274,6 +4146,26 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.69", +] + [[package]] name = "object" version = "0.32.2" @@ -3282,7 +4174,7 @@ checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "crc32fast", "hashbrown 0.14.5", - "indexmap 2.2.6", + "indexmap 2.6.0", "memchr", ] @@ -3515,7 +4407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.6.0", ] [[package]] @@ -3568,6 +4460,16 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.30" @@ -3687,13 +4589,24 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" dependencies = [ - "fixed-hash", + "fixed-hash 0.7.0", "impl-codec", "impl-rlp", "impl-serde", "uint 0.9.5", ] +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash 0.8.0", + "impl-codec", + "uint 0.9.5", +] + [[package]] name = "priority-queue" version = "2.0.3" @@ -3702,7 +4615,7 @@ checksum = "70c501afe3a2e25c9bd219aa56ec1e04cdb3fcdd763055be268778c13fa82c1f" dependencies = [ "autocfg", "equivalent", - "indexmap 2.2.6", + "indexmap 2.6.0", ] [[package]] @@ -3714,6 +4627,28 @@ dependencies = [ "toml_edit 0.21.1", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.69", +] + [[package]] name = "proc-macro-utils" version = "0.10.0" @@ -3751,6 +4686,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "prost" version = "0.11.9" @@ -3882,7 +4837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a16027030d4ec33e423385f73bb559821827e9ec18c50e7874e4d6de5a4e96f" dependencies = [ "anyhow", - "indexmap 2.2.6", + "indexmap 2.6.0", "log", "protobuf 3.5.0", "protobuf-support", @@ -3909,6 +4864,12 @@ dependencies = [ "cc", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-xml" version = "0.36.2" @@ -4001,6 +4962,7 @@ dependencies = [ "libc", "rand_chacha", "rand_core", + "serde", ] [[package]] @@ -4022,6 +4984,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + [[package]] name = "rayon" version = "1.10.0" @@ -4171,6 +5142,16 @@ dependencies = [ "winreg", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.17.8" @@ -4196,6 +5177,36 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "ruint" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c3cc4c2511671f327125da14133d0c5c5d137f006a1017a16f557bc85b16286" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint 0.4.6", + "num-traits", + "parity-scale-codec", + "primitive-types 0.12.2", + "proptest", + "rand", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4220,13 +5231,22 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.23", ] [[package]] @@ -4316,6 +5336,18 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.18" @@ -4349,12 +5381,37 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "schnellru" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" +dependencies = [ + "ahash", + "cfg-if 1.0.0", + "hashbrown 0.13.2", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "secp256k1" version = "0.21.3" @@ -4396,6 +5453,15 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.23" @@ -4405,6 +5471,15 @@ dependencies = [ "serde", ] +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.204" @@ -4520,7 +5595,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "itoa", "ryu", "serde", @@ -4572,6 +5647,16 @@ dependencies = [ "keccak", ] +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if 1.0.0", +] + [[package]] name = "shellexpand" version = "3.1.0" @@ -4590,6 +5675,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + [[package]] name = "siphasher" version = "0.3.11" @@ -4737,6 +5832,16 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "sptr" version = "0.3.2" @@ -4941,6 +6046,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16320d4a2021ba1a32470b3759676114a918885e9800e68ad60f2c67969fba62" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.69", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -5049,6 +6166,7 @@ dependencies = [ "lazy_static", "pretty_assertions", "prost-types 0.12.6", + "serde_json", ] [[package]] @@ -5081,6 +6199,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + [[package]] name = "time" version = "0.3.36" @@ -5380,7 +6507,7 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "toml_datetime", "winnow 0.5.40", ] @@ -5391,7 +6518,7 @@ version = "0.22.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", @@ -5482,6 +6609,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36b837f86b25d7c0d7988f00a54e74739be6477f2aac6201b8f429a7569991b7" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tower-service 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "tower-http" version = "0.5.2" @@ -5661,6 +6802,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicase" version = "2.7.0" @@ -5775,6 +6922,12 @@ dependencies = [ "serde", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" @@ -5793,6 +6946,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -5936,8 +7098,8 @@ version = "0.116.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" dependencies = [ - "indexmap 2.2.6", - "semver", + "indexmap 2.6.0", + "semver 1.0.23", ] [[package]] @@ -5946,8 +7108,8 @@ version = "0.118.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77f1154f1ab868e2a01d9834a805faca7bf8b50d041b4ca714d005d0dab1c50c" dependencies = [ - "indexmap 2.2.6", - "semver", + "indexmap 2.6.0", + "semver 1.0.23", ] [[package]] @@ -5962,7 +7124,7 @@ dependencies = [ "bumpalo", "cfg-if 1.0.0", "fxprof-processed-profile", - "indexmap 2.2.6", + "indexmap 2.6.0", "libc", "log", "object 0.32.2", @@ -6087,7 +7249,7 @@ dependencies = [ "anyhow", "cranelift-entity", "gimli 0.28.1", - "indexmap 2.2.6", + "indexmap 2.6.0", "log", "object 0.32.2", "serde", @@ -6172,7 +7334,7 @@ dependencies = [ "anyhow", "cc", "cfg-if 1.0.0", - "indexmap 2.2.6", + "indexmap 2.6.0", "libc", "log", "mach", @@ -6224,7 +7386,7 @@ checksum = "4b804dfd3d0c0d6d37aa21026fe7772ba1a769c89ee4f5c4f13b82d91d75216f" dependencies = [ "anyhow", "heck 0.4.1", - "indexmap 2.2.6", + "indexmap 2.6.0", "wit-parser", ] @@ -6234,6 +7396,20 @@ version = "15.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6060bc082cc32d9a45587c7640e29e3c7b89ada82677ac25d87850aaccb368" +[[package]] +name = "wasmtimer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7ed9d8b15c7fb594d72bfb4b5a276f3d2029333cd93a932f376f5937f6f80ee" +dependencies = [ + "futures 0.3.30", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "wast" version = "212.0.0" @@ -6274,7 +7450,7 @@ dependencies = [ "arrayvec 0.7.4", "base64 0.13.1", "bytes", - "derive_more", + "derive_more 0.99.18", "ethabi", "ethereum-types", "futures 0.3.30", @@ -6575,9 +7751,9 @@ checksum = "316b36a9f0005f5aa4b03c39bc3728d045df136f8c13a73b7db4510dec725e08" dependencies = [ "anyhow", "id-arena", - "indexmap 2.2.6", + "indexmap 2.6.0", "log", - "semver", + "semver 1.0.23", "serde", "serde_derive", "serde_json", @@ -6630,6 +7806,20 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.69", +] [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 0421a32e274..ad7acde8fa5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ repository = "https://github.com/graphprotocol/graph-node" license = "MIT OR Apache-2.0" [workspace.dependencies] +alloy = { version = "0.5.4", features = ["dyn-abi", "json-abi"] } anyhow = "1.0" async-graphql = { version = "7.0.11", features = ["chrono", "uuid"] } async-graphql-axum = "7.0.11" diff --git a/chain/ethereum/src/adapter.rs b/chain/ethereum/src/adapter.rs index f78ff1b0bec..7aa63cca6c9 100644 --- a/chain/ethereum/src/adapter.rs +++ b/chain/ethereum/src/adapter.rs @@ -1,5 +1,4 @@ use anyhow::Error; -use ethabi::{Error as ABIError, Function, ParamType, Token}; use graph::blockchain::ChainIdentifier; use graph::components::subgraph::MappingError; use graph::data::store::ethereum::call; @@ -98,8 +97,8 @@ pub struct ContractCall { pub contract_name: String, pub address: Address, pub block_ptr: BlockPtr, - pub function: Function, - pub args: Vec, + pub function: graph::abi::Function, + pub args: Vec, pub gas: Option, } @@ -113,13 +112,12 @@ pub enum EthereumRpcError { #[derive(Error, Debug)] pub enum ContractCallError { - #[error("ABI error: {0}")] - ABIError(#[from] ABIError), - /// `Token` is not of expected `ParamType` - #[error("type mismatch, token {0:?} is not of kind {1:?}")] - TypeError(Token, ParamType), - #[error("error encoding input call data: {0}")] - EncodingError(ethabi::Error), + #[error("ABI error: {0:#}")] + ABIError(anyhow::Error), + #[error("type mismatch, decoded value {0:?} is not of kind {1:?}")] + TypeError(graph::abi::DecodedValue, graph::abi::ParamType), + #[error("error encoding input call data: {0:#}")] + EncodingError(anyhow::Error), #[error("call error: {0}")] Web3Error(web3::Error), #[error("ethereum node took too long to perform call")] @@ -1174,7 +1172,7 @@ pub trait EthereumAdapter: Send + Sync + 'static { logger: &Logger, call: &ContractCall, cache: Arc, - ) -> Result<(Option>, call::Source), ContractCallError>; + ) -> Result<(Option>, call::Source), ContractCallError>; /// Make multiple contract calls in a single batch. The returned `Vec` /// has results in the same order as the calls in `calls` on input. The @@ -1184,7 +1182,7 @@ pub trait EthereumAdapter: Send + Sync + 'static { logger: &Logger, calls: &[&ContractCall], cache: Arc, - ) -> Result>, call::Source)>, ContractCallError>; + ) -> Result>, call::Source)>, ContractCallError>; fn get_balance( &self, @@ -1213,9 +1211,9 @@ mod tests { use graph::blockchain::TriggerFilter as _; use graph::firehose::{CallToFilter, CombinedFilter, LogFilter, MultiLogFilter}; use graph::petgraph::graphmap::GraphMap; - use graph::prelude::ethabi::ethereum_types::H256; use graph::prelude::web3::types::Address; use graph::prelude::web3::types::Bytes; + use graph::prelude::web3::types::H256; use graph::prelude::EthereumCall; use hex::ToHex; use itertools::Itertools; diff --git a/chain/ethereum/src/data_source.rs b/chain/ethereum/src/data_source.rs index c0253d2e60e..67c64314f70 100644 --- a/chain/ethereum/src/data_source.rs +++ b/chain/ethereum/src/data_source.rs @@ -11,10 +11,10 @@ use graph::env::ENV_VARS; use graph::futures03::future::try_join; use graph::futures03::stream::FuturesOrdered; use graph::futures03::TryStreamExt; -use graph::prelude::ethabi::ethereum_types::H160; -use graph::prelude::ethabi::{StateMutability, Token}; use graph::prelude::lazy_static; use graph::prelude::regex::Regex; +use graph::prelude::web3::types::Address; +use graph::prelude::web3::types::H160; use graph::prelude::{Link, SubgraphManifestValidationError}; use graph::slog::{debug, error, o, trace}; use itertools::Itertools; @@ -32,9 +32,7 @@ use graph::{ blockchain::{self, Blockchain}, derive::CheapClone, prelude::{ - async_trait, - ethabi::{Address, Contract, Event, Function, LogParam, ParamType, RawLog}, - serde_json, warn, + async_trait, serde_json, warn, web3::types::{Log, Transaction, H256}, BlockNumber, CheapClone, EthereumCall, LightEthereumBlock, LightEthereumBlockExt, LinkResolver, Logger, @@ -527,28 +525,28 @@ impl DataSource { } } - /// Returns the contract event with the given signature, if it exists. A an event from the ABI + /// Returns the contract event with the given signature, if it exists. An event from the ABI /// will be matched if: /// 1. An event signature is equal to `signature`. /// 2. There are no equal matches, but there is exactly one event that equals `signature` if all /// `indexed` modifiers are removed from the parameters. - fn contract_event_with_signature(&self, signature: &str) -> Option<&Event> { + fn contract_event_with_signature(&self, signature: &str) -> Option<&graph::abi::Event> { // Returns an `Event(uint256,address)` signature for an event, without `indexed` hints. - fn ambiguous_event_signature(event: &Event) -> String { + fn ambiguous_event_signature(event: &graph::abi::Event) -> String { format!( "{}({})", event.name, event .inputs .iter() - .map(|input| event_param_type_signature(&input.kind)) + .map(|input| input.selector_type().into_owned()) .collect::>() .join(",") ) } // Returns an `Event(indexed uint256,address)` type signature for an event. - fn event_signature(event: &Event) -> String { + fn event_signature(event: &graph::abi::Event) -> String { format!( "{}({})", event.name, @@ -558,40 +556,13 @@ impl DataSource { .map(|input| format!( "{}{}", if input.indexed { "indexed " } else { "" }, - event_param_type_signature(&input.kind) + input.selector_type() )) .collect::>() .join(",") ) } - // Returns the signature of an event parameter type (e.g. `uint256`). - fn event_param_type_signature(kind: &ParamType) -> String { - use ParamType::*; - - match kind { - Address => "address".into(), - Bytes => "bytes".into(), - Int(size) => format!("int{}", size), - Uint(size) => format!("uint{}", size), - Bool => "bool".into(), - String => "string".into(), - Array(inner) => format!("{}[]", event_param_type_signature(inner)), - FixedBytes(size) => format!("bytes{}", size), - FixedArray(inner, size) => { - format!("{}[{}]", event_param_type_signature(inner), size) - } - Tuple(components) => format!( - "({})", - components - .iter() - .map(event_param_type_signature) - .collect::>() - .join(",") - ), - } - } - self.contract_abi .contract .events() @@ -630,7 +601,12 @@ impl DataSource { }) } - fn contract_function_with_signature(&self, target_signature: &str) -> Option<&Function> { + fn contract_function_with_signature( + &self, + target_signature: &str, + ) -> Option<&graph::abi::Function> { + use graph::abi::StateMutability; + self.contract_abi .contract .functions() @@ -644,7 +620,7 @@ impl DataSource { let mut arguments = function .inputs .iter() - .map(|input| format!("{}", input.kind)) + .map(|input| format!("{}", input.selector_type())) .collect::>() .join(","); // `address,uint256,bool) @@ -676,6 +652,9 @@ impl DataSource { block: &Arc, logger: &Logger, ) -> Result>, Error> { + use graph::abi::ContractExt; + use graph::abi::FunctionExt; + if !self.matches_trigger_address(trigger) { return Ok(None); } @@ -733,12 +712,7 @@ impl DataSource { let mut matching_handlers = valid_handlers .into_iter() .filter_map(|(event_handler, event_abi)| { - event_abi - .parse_log(RawLog { - topics: log.topics.clone(), - data: log.data.clone().0, - }) - .map(|log| log.params) + graph::abi::decode_log(event_abi, &log) .map_err(|e| { trace!( logger, @@ -838,20 +812,15 @@ impl DataSource { ) })?; - // Parse the inputs - // - // Take the input for the call, chop off the first 4 bytes, then call - // `function.decode_input` to get a vector of `Token`s. Match the `Token`s - // with the `Param`s in `function.inputs` to create a `Vec`. - let tokens = match function_abi.decode_input(&call.input.0[4..]).with_context( - || { + let tokens = match function_abi + .abi_decode_input(&call.input.0[4..], true) + .with_context(|| { format!( "Generating function inputs for the call {:?} failed, raw input: {}", &function_abi, hex::encode(&call.input.0) ) - }, - ) { + }) { Ok(val) => val, // See also 280b0108-a96e-4738-bb37-60ce11eeb5bf Err(err) => { @@ -869,19 +838,14 @@ impl DataSource { let inputs = tokens .into_iter() .enumerate() - .map(|(i, token)| LogParam { + .map(|(i, token)| graph::abi::DecodedParam { name: function_abi.inputs[i].name.clone(), value: token, }) .collect::>(); - // Parse the outputs - // - // Take the output for the call, then call `function.decode_output` to - // get a vector of `Token`s. Match the `Token`s with the `Param`s in - // `function.outputs` to create a `Vec`. let tokens = function_abi - .decode_output(&call.output.0) + .abi_decode_output(&call.output.0, true) .with_context(|| { format!( "Decoding function outputs for the call {:?} failed, raw output: {}", @@ -899,7 +863,7 @@ impl DataSource { let outputs = tokens .into_iter() .enumerate() - .map(|(i, token)| LogParam { + .map(|(i, token)| graph::abi::DecodedParam { name: function_abi.outputs[i].name.clone(), value: token, }) @@ -939,8 +903,8 @@ pub struct DeclaredCall { label: String, contract_name: String, address: Address, - function: Function, - args: Vec, + function: graph::abi::Function, + args: Vec, } impl DeclaredCall { @@ -948,7 +912,7 @@ impl DeclaredCall { mapping: &Mapping, handler: &MappingEventHandler, log: &Log, - params: &[LogParam], + params: &[graph::abi::DecodedParam], ) -> Result, anyhow::Error> { let mut calls = Vec::new(); for decl in handler.calls.decls.iter() { @@ -961,12 +925,15 @@ impl DeclaredCall { // Behavior for apiVersion < 0.0.4: look up function by name; for overloaded // functions this always picks the same overloaded variant, which is incorrect // and may lead to encoding/decoding errors - abi.contract.function(function_name).with_context(|| { - format!( - "Unknown function \"{}::{}\" called from WASM runtime", - contract_name, function_name - ) - })? + abi.contract + .function(function_name) + .and_then(|matches| matches.first()) + .with_context(|| { + format!( + "Unknown function \"{}::{}\" called from WASM runtime", + contract_name, function_name + ) + })? }; let address = decl.address(log, params)?; @@ -1454,7 +1421,7 @@ impl UnresolvedMappingABI { self.name, self.file.link ) })?; - let contract = Contract::load(&*contract_bytes)?; + let contract = serde_json::from_slice(&contract_bytes)?; Ok(MappingABI { name: self.name, contract, @@ -1465,7 +1432,7 @@ impl UnresolvedMappingABI { #[derive(Clone, Debug, PartialEq)] pub struct MappingABI { pub name: String, - pub contract: Contract, + pub contract: graph::abi::Contract, } impl MappingABI { @@ -1474,24 +1441,27 @@ impl MappingABI { contract_name: &str, name: &str, signature: Option<&str>, - ) -> Result<&Function, Error> { + ) -> Result<&graph::abi::Function, Error> { let contract = &self.contract; let function = match signature { // Behavior for apiVersion < 0.0.4: look up function by name; for overloaded // functions this always picks the same overloaded variant, which is incorrect // and may lead to encoding/decoding errors - None => contract.function(name).with_context(|| { - format!( - "Unknown function \"{}::{}\" called from WASM runtime", - contract_name, name - ) - })?, + None => contract + .function(name) + .and_then(|matches| matches.first()) + .with_context(|| { + format!( + "Unknown function \"{}::{}\" called from WASM runtime", + contract_name, name + ) + })?, // Behavior for apiVersion >= 0.0.04: look up function by signature of // the form `functionName(uint256,string) returns (bytes32,string)`; this // correctly picks the correct variant of an overloaded function Some(ref signature) => contract - .functions_by_name(name) + .function(name) .with_context(|| { format!( "Unknown function \"{}::{}\" called from WASM runtime", @@ -1673,32 +1643,42 @@ pub struct CallDecl { readonly: (), } impl CallDecl { - fn address(&self, log: &Log, params: &[LogParam]) -> Result { + fn address(&self, log: &Log, params: &[graph::abi::DecodedParam]) -> Result { let address = match &self.expr.address { CallArg::Address => log.address, CallArg::HexAddress(address) => *address, CallArg::Param(name) => { - let value = params + let value = ¶ms .iter() .find(|param| ¶m.name == name.as_str()) .ok_or_else(|| anyhow!("unknown param {name}"))? - .value - .clone(); - value - .into_address() - .ok_or_else(|| anyhow!("param {name} is not an address"))? + .value; + + let address = value + .as_address() + .ok_or_else(|| anyhow!("param {name} is not an address"))?; + + Address::from(address.into_array()) } }; Ok(address) } - fn args(&self, log: &Log, params: &[LogParam]) -> Result, Error> { + fn args( + &self, + log: &Log, + params: &[graph::abi::DecodedParam], + ) -> Result, Error> { + use graph::abi::DecodedValue; + self.expr .args .iter() .map(|arg| match arg { - CallArg::Address => Ok(Token::Address(log.address)), - CallArg::HexAddress(address) => Ok(Token::Address(*address)), + CallArg::Address => Ok(DecodedValue::Address(log.address.to_fixed_bytes().into())), + CallArg::HexAddress(address) => { + Ok(DecodedValue::Address(address.to_fixed_bytes().into())) + } CallArg::Param(name) => { let value = params .iter() diff --git a/chain/ethereum/src/ethereum_adapter.rs b/chain/ethereum/src/ethereum_adapter.rs index c4ea6323c7d..387336c2656 100644 --- a/chain/ethereum/src/ethereum_adapter.rs +++ b/chain/ethereum/src/ethereum_adapter.rs @@ -14,8 +14,6 @@ use graph::futures03::future::try_join_all; use graph::futures03::{ self, compat::Future01CompatExt, FutureExt, StreamExt, TryFutureExt, TryStreamExt, }; -use graph::prelude::ethabi::ParamType; -use graph::prelude::ethabi::Token; use graph::prelude::tokio::try_join; use graph::prelude::web3::types::U256; use graph::slog::o; @@ -25,8 +23,7 @@ use graph::{ blockchain::{block_stream::BlockWithTriggers, BlockPtr, IngestorError}, prelude::{ anyhow::{self, anyhow, bail, ensure, Context}, - async_trait, debug, error, ethabi, hex, info, retry, serde_json as json, tiny_keccak, - trace, warn, + async_trait, debug, error, hex, info, retry, serde_json as json, tiny_keccak, trace, warn, web3::{ self, types::{ @@ -656,9 +653,10 @@ impl EthereumAdapter { match bytes.len() >= 4 && &bytes[..4] == solidity_revert_function_selector { false => None, - true => ethabi::decode(&[ParamType::String], &bytes[4..]) + true => graph::abi::ParamType::String + .abi_decode(&bytes[4..]) .ok() - .and_then(|tokens| tokens[0].clone().into_string()), + .and_then(|tokens| tokens.clone().as_str().map(ToOwned::to_owned)), } }; @@ -1501,7 +1499,7 @@ impl EthereumAdapterTrait for EthereumAdapter { logger: &Logger, inp_call: &ContractCall, cache: Arc, - ) -> Result<(Option>, call::Source), ContractCallError> { + ) -> Result<(Option>, call::Source), ContractCallError> { let mut result = self.contract_calls(logger, &[inp_call], cache).await?; // unwrap: self.contract_calls returns as many results as there were calls Ok(result.pop().unwrap()) @@ -1512,19 +1510,27 @@ impl EthereumAdapterTrait for EthereumAdapter { logger: &Logger, calls: &[&ContractCall], cache: Arc, - ) -> Result>, call::Source)>, ContractCallError> { + ) -> Result>, call::Source)>, ContractCallError> { fn as_req( logger: &Logger, call: &ContractCall, index: u32, ) -> Result { + use graph::abi::ContractExt; + // Emit custom error for type mismatches. for (token, kind) in call .args .iter() - .zip(call.function.inputs.iter().map(|p| &p.kind)) + .zip(call.function.inputs.iter().map(|p| p.selector_type())) { - if !token.type_check(kind) { + let kind: graph::abi::ParamType = kind.parse().map_err(|err| { + ContractCallError::ABIError(anyhow!( + "failed to parse function input type '{kind}': {err}" + )) + })?; + + if !token.matches(&kind) { return Err(ContractCallError::TypeError(token.clone(), kind.clone())); } } @@ -1533,8 +1539,8 @@ impl EthereumAdapterTrait for EthereumAdapter { let req = { let encoded_call = call .function - .encode_input(&call.args) - .map_err(ContractCallError::EncodingError)?; + .abi_encode_input(&call.args) + .map_err(|err| ContractCallError::EncodingError(err.into()))?; call::Request::new(call.address, encoded_call, index) }; @@ -1552,7 +1558,9 @@ impl EthereumAdapterTrait for EthereumAdapter { logger: &Logger, resp: call::Response, call: &ContractCall, - ) -> (Option>, call::Source) { + ) -> (Option>, call::Source) { + use graph::abi::FunctionExt; + let call::Response { retval, source, @@ -1560,7 +1568,7 @@ impl EthereumAdapterTrait for EthereumAdapter { } = resp; use call::Retval::*; match retval { - Value(output) => match call.function.decode_output(&output) { + Value(output) => match call.function.abi_decode_output(&output, true) { Ok(tokens) => (Some(tokens), source), Err(e) => { // Decode failures are reverts. The reasoning is that if Solidity fails to @@ -2607,9 +2615,9 @@ mod tests { EthereumBlockWithCalls, }; use graph::blockchain::BlockPtr; - use graph::prelude::ethabi::ethereum_types::U64; use graph::prelude::tokio::{self}; use graph::prelude::web3::transports::test::TestTransport; + use graph::prelude::web3::types::U64; use graph::prelude::web3::types::{Address, Block, Bytes, H256}; use graph::prelude::web3::Web3; use graph::prelude::EthereumCall; diff --git a/chain/ethereum/src/ingestor.rs b/chain/ethereum/src/ingestor.rs index d22e08c4294..5b281d9ba80 100644 --- a/chain/ethereum/src/ingestor.rs +++ b/chain/ethereum/src/ingestor.rs @@ -10,8 +10,8 @@ use graph::{ blockchain::{BlockHash, BlockIngestor, BlockPtr, IngestorError}, cheap_clone::CheapClone, prelude::{ - async_trait, error, ethabi::ethereum_types::H256, info, tokio, trace, warn, ChainStore, - Error, EthereumBlockWithCalls, LogCode, Logger, + async_trait, error, info, tokio, trace, warn, web3::types::H256, ChainStore, Error, + EthereumBlockWithCalls, LogCode, Logger, }, }; use std::{sync::Arc, time::Duration}; diff --git a/chain/ethereum/src/runtime/abi.rs b/chain/ethereum/src/runtime/abi.rs index d88bf2b22d7..cf83c2f1f66 100644 --- a/chain/ethereum/src/runtime/abi.rs +++ b/chain/ethereum/src/runtime/abi.rs @@ -4,7 +4,6 @@ use crate::trigger::{ }; use graph::{ prelude::{ - ethabi, web3::types::{Log, TransactionReceipt, H256}, BigInt, }, @@ -37,7 +36,7 @@ impl AscType for AscLogParamArray { } } -impl ToAscObj for Vec { +impl ToAscObj for Vec { fn to_asc_obj( &self, heap: &mut H, @@ -519,7 +518,7 @@ impl ToAscObj for EthereumTransactionData { value: asc_new(heap, &BigInt::from_unsigned_u256(&self.value), gas)?, gas_limit: asc_new(heap, &BigInt::from_unsigned_u256(&self.gas_limit), gas)?, gas_price: asc_new(heap, &BigInt::from_unsigned_u256(&self.gas_price), gas)?, - input: asc_new(heap, &*self.input, gas)?, + input: asc_new(heap, &self.input, gas)?, }) } } @@ -541,7 +540,7 @@ impl ToAscObj for EthereumTransactionData { value: asc_new(heap, &BigInt::from_unsigned_u256(&self.value), gas)?, gas_limit: asc_new(heap, &BigInt::from_unsigned_u256(&self.gas_limit), gas)?, gas_price: asc_new(heap, &BigInt::from_unsigned_u256(&self.gas_price), gas)?, - input: asc_new(heap, &*self.input, gas)?, + input: asc_new(heap, &self.input, gas)?, nonce: asc_new(heap, &BigInt::from_unsigned_u256(&self.nonce), gas)?, }) } @@ -771,7 +770,7 @@ impl ToAscObj for ethabi::LogParam { +impl ToAscObj for graph::abi::DecodedParam { fn to_asc_obj( &self, heap: &mut H, diff --git a/chain/ethereum/src/runtime/runtime_adapter.rs b/chain/ethereum/src/runtime/runtime_adapter.rs index 4147d61f5b0..ca758d8f051 100644 --- a/chain/ethereum/src/runtime/runtime_adapter.rs +++ b/chain/ethereum/src/runtime/runtime_adapter.rs @@ -8,12 +8,14 @@ use crate::{ }; use anyhow::{anyhow, Context, Error}; use blockchain::HostFn; +use graph::abi::DecodedValueExt; use graph::blockchain::ChainIdentifier; use graph::components::subgraph::HostMetrics; use graph::data::store::ethereum::call; use graph::data::store::scalar::BigInt; use graph::data::subgraph::API_VERSION_0_0_9; use graph::futures03::compat::Future01CompatExt; +use graph::prelude::web3::types::Address; use graph::prelude::web3::types::H160; use graph::runtime::gas::Gas; use graph::runtime::{AscIndexId, IndexForAscTypeId}; @@ -21,10 +23,7 @@ use graph::slog::debug; use graph::{ blockchain::{self, BlockPtr, HostFnCtx}, cheap_clone::CheapClone, - prelude::{ - ethabi::{self, Address, Token}, - EthereumCallCache, - }, + prelude::EthereumCallCache, runtime::{asc_get, asc_new, AscPtr, HostExportError}, semver::Version, slog::Logger, @@ -256,20 +255,7 @@ fn eth_call( abis: &[Arc], eth_call_gas: Option, metrics: Arc, -) -> Result>, HostExportError> { - // Helpers to log the result of the call at the end - fn tokens_as_string(tokens: &[Token]) -> String { - tokens.iter().map(|arg| arg.to_string()).join(", ") - } - - fn result_as_string(result: &Result>, HostExportError>) -> String { - match result { - Ok(Some(tokens)) => format!("({})", tokens_as_string(&tokens)), - Ok(None) => "none".to_string(), - Err(_) => "error".to_string(), - } - } - +) -> Result>, HostExportError> { let start_time = Instant::now(); // Obtain the path to the contract ABI @@ -348,16 +334,26 @@ fn eth_call( ); } - debug!(logger, "Contract call finished"; - "address" => format!("0x{:x}", &unresolved_call.contract_address), - "contract" => &unresolved_call.contract_name, - "signature" => &unresolved_call.function_signature, - "args" => format!("[{}]", tokens_as_string(&unresolved_call.function_args)), - "time_ms" => format!("{}ms", elapsed.as_millis()), - "result" => result_as_string(&result), - "block_hash" => block_ptr.hash_hex(), - "block_number" => block_ptr.block_number(), - "source" => source.to_string()); + let args_as_string = format!("[{}]", values_to_string(&unresolved_call.function_args)); + + let result_as_string = match &result { + Ok(Some(values)) => format!("({})", values_to_string(values)), + Ok(None) => "none".to_owned(), + Err(_err) => "error".to_owned(), + }; + + debug!( + logger, "Contract call finished"; + "address" => format!("0x{:x}", &unresolved_call.contract_address), + "contract" => &unresolved_call.contract_name, + "signature" => &unresolved_call.function_signature, + "args" => args_as_string, + "time_ms" => format!("{}ms", elapsed.as_millis()), + "result" => result_as_string, + "block_hash" => block_ptr.hash_hex(), + "block_number" => block_ptr.block_number(), + "source" => source.to_string(), + ); result } @@ -368,9 +364,18 @@ pub struct UnresolvedContractCall { pub contract_address: Address, pub function_name: String, pub function_signature: Option, - pub function_args: Vec, + pub function_args: Vec, } impl AscIndexId for AscUnresolvedContractCall { const INDEX_ASC_TYPE_ID: IndexForAscTypeId = IndexForAscTypeId::SmartContractCall; } + +#[inline] +fn values_to_string(values: &[graph::abi::DecodedValue]) -> String { + values + .iter() + .map(|x| x.to_string()) + .collect_vec() + .join(", ") +} diff --git a/chain/ethereum/src/trigger.rs b/chain/ethereum/src/trigger.rs index 128ed8d3e98..33dd81da0bb 100644 --- a/chain/ethereum/src/trigger.rs +++ b/chain/ethereum/src/trigger.rs @@ -3,18 +3,17 @@ use graph::blockchain::TriggerData; use graph::data::subgraph::API_VERSION_0_0_2; use graph::data::subgraph::API_VERSION_0_0_6; use graph::data::subgraph::API_VERSION_0_0_7; -use graph::prelude::ethabi::ethereum_types::H160; -use graph::prelude::ethabi::ethereum_types::H256; -use graph::prelude::ethabi::ethereum_types::U128; -use graph::prelude::ethabi::ethereum_types::U256; -use graph::prelude::ethabi::ethereum_types::U64; -use graph::prelude::ethabi::Address; -use graph::prelude::ethabi::Bytes; -use graph::prelude::ethabi::LogParam; +use graph::prelude::web3::types::Address; use graph::prelude::web3::types::Block; +use graph::prelude::web3::types::Bytes; use graph::prelude::web3::types::Log; use graph::prelude::web3::types::Transaction; use graph::prelude::web3::types::TransactionReceipt; +use graph::prelude::web3::types::H160; +use graph::prelude::web3::types::H256; +use graph::prelude::web3::types::U128; +use graph::prelude::web3::types::U256; +use graph::prelude::web3::types::U64; use graph::prelude::BlockNumber; use graph::prelude::BlockPtr; use graph::prelude::{CheapClone, EthereumCall}; @@ -47,7 +46,7 @@ pub enum MappingTrigger { block: Arc, transaction: Arc, log: Arc, - params: Vec, + params: Vec, receipt: Option>, calls: Vec, }, @@ -55,8 +54,8 @@ pub enum MappingTrigger { block: Arc, transaction: Arc, call: Arc, - inputs: Vec, - outputs: Vec, + inputs: Vec, + outputs: Vec, }, Block { block: Arc, @@ -86,13 +85,13 @@ impl std::fmt::Debug for MappingTrigger { Log { _transaction: Arc, _log: Arc, - _params: Vec, + _params: Vec, }, Call { _transaction: Arc, _call: Arc, - _inputs: Vec, - _outputs: Vec, + _inputs: Vec, + _outputs: Vec, }, Block, } @@ -488,7 +487,7 @@ impl From<&'_ Transaction> for EthereumTransactionData { value: tx.value, gas_limit: tx.gas, gas_price: tx.gas_price.unwrap_or(U256::zero()), // EIP-1559 made this optional. - input: tx.input.0.clone(), + input: tx.input.clone(), nonce: tx.nonce, } } @@ -503,7 +502,7 @@ pub struct EthereumEventData { pub log_type: Option, pub block: EthereumBlockData, pub transaction: EthereumTransactionData, - pub params: Vec, + pub params: Vec, } /// An Ethereum call executed within a transaction within a block to a contract address. @@ -513,6 +512,6 @@ pub struct EthereumCallData { pub to: Address, pub block: EthereumBlockData, pub transaction: EthereumTransactionData, - pub inputs: Vec, - pub outputs: Vec, + pub inputs: Vec, + pub outputs: Vec, } diff --git a/graph/Cargo.toml b/graph/Cargo.toml index 089d46bd9ec..bf3cd4882df 100644 --- a/graph/Cargo.toml +++ b/graph/Cargo.toml @@ -4,6 +4,7 @@ version.workspace = true edition.workspace = true [dependencies] +alloy = { workspace = true } base64 = "=0.21.7" anyhow = "1.0" async-trait = "0.1.74" @@ -24,7 +25,6 @@ envconfig = "0.10.0" Inflector = "0.11.3" isatty = "0.1.9" reqwest = { version = "0.12.5", features = ["json", "stream", "multipart"] } -ethabi = "17.2" hex = "0.4.3" http0 = { version = "0", package = "http" } http = "1" diff --git a/graph/src/abi/decoded_param.rs b/graph/src/abi/decoded_param.rs new file mode 100644 index 00000000000..cc5fd290b8c --- /dev/null +++ b/graph/src/abi/decoded_param.rs @@ -0,0 +1,51 @@ +use alloy::dyn_abi::EventExt; +use alloy::json_abi::Event; +use alloy::primitives::LogData; +use anyhow::anyhow; +use anyhow::Result; +use itertools::Itertools; +use web3::types::Log; + +#[derive(Clone, Debug)] +pub struct DecodedParam { + pub name: String, + pub value: crate::abi::DecodedValue, +} + +pub fn decode_log(event: &Event, log: &Log) -> Result> { + let log_data = log_to_log_data(log); + let decoded_event = event.decode_log(&log_data, true)?; + + if event.inputs.len() != decoded_event.indexed.len() + decoded_event.body.len() { + return Err(anyhow!( + "unexpected number of decoded event inputs; expected {}, got {}", + event.inputs.len(), + decoded_event.indexed.len() + decoded_event.body.len(), + )); + } + + let decoded_params = decoded_event + .indexed + .into_iter() + .chain(decoded_event.body.into_iter()) + .enumerate() + .map(|(i, value)| DecodedParam { + name: event.inputs[i].name.clone(), + value, + }) + .collect(); + + Ok(decoded_params) +} + +fn log_to_log_data(log: &Log) -> LogData { + let topics = log + .topics + .iter() + .map(|x| x.to_fixed_bytes().into()) + .collect_vec(); + + let data = log.data.0.clone().into(); + + LogData::new_unchecked(topics, data) +} diff --git a/graph/src/abi/decoded_value.rs b/graph/src/abi/decoded_value.rs new file mode 100644 index 00000000000..e4ded7362df --- /dev/null +++ b/graph/src/abi/decoded_value.rs @@ -0,0 +1,50 @@ +use anyhow::anyhow; +use anyhow::Result; +use itertools::Itertools; + +pub type DecodedValue = alloy::dyn_abi::DynSolValue; + +pub trait DecodedValueExt { + /// Creates a fixed-byte decoded value from a slice. + /// Fails if the source slice exceeds 32 bytes. + fn fixed_bytes_from_slice(s: &[u8]) -> Result; + + /// Returns the decoded value as a string. + /// The resulting string contains no type information. + fn to_string(&self) -> String; +} + +impl DecodedValueExt for DecodedValue { + fn fixed_bytes_from_slice(s: &[u8]) -> Result { + let num_bytes = s.len(); + + if num_bytes > 32 { + return Err(anyhow!( + "input slice must contain a maximum of 32 bytes, got {num_bytes}" + )); + } + + let mut bytes = [0u8; 32]; + bytes[..num_bytes].copy_from_slice(s); + + Ok(Self::FixedBytes(bytes.into(), num_bytes)) + } + + fn to_string(&self) -> String { + let s = |v: &[DecodedValue]| v.iter().map(|x| x.to_string()).collect_vec().join(","); + + match self { + Self::Bool(v) => v.to_string(), + Self::Int(v, _) => format!("{v:x}"), + Self::Uint(v, _) => format!("{v:x}"), + Self::FixedBytes(v, _) => hex::encode(v), + Self::Address(v) => format!("{v:x}"), + Self::Function(v) => format!("{v:x}"), + Self::Bytes(v) => hex::encode(v), + Self::String(v) => v.to_owned(), + Self::Array(v) => format!("[{}]", s(v)), + Self::FixedArray(v) => format!("[{}]", s(v)), + Self::Tuple(v) => format!("({})", s(v)), + } + } +} diff --git a/graph/src/abi/mod.rs b/graph/src/abi/mod.rs new file mode 100644 index 00000000000..b6540d0a71a --- /dev/null +++ b/graph/src/abi/mod.rs @@ -0,0 +1,23 @@ +mod decoded_param; +mod decoded_value; + +pub use alloy::dyn_abi::EventExt; +pub use alloy::dyn_abi::FunctionExt; +pub use alloy::dyn_abi::JsonAbiExt as ContractExt; + +pub use alloy::json_abi::Event; +pub use alloy::json_abi::Function; +pub use alloy::json_abi::StateMutability; + +pub use alloy::primitives::LogData; +pub use alloy::primitives::I256; +pub use alloy::primitives::U256; + +pub use self::decoded_param::decode_log; +pub use self::decoded_param::DecodedParam; +pub use self::decoded_value::DecodedValue; +pub use self::decoded_value::DecodedValueExt; + +pub type ParamType = alloy::dyn_abi::DynSolType; + +pub type Contract = alloy::json_abi::JsonAbi; diff --git a/graph/src/cheap_clone.rs b/graph/src/cheap_clone.rs index b8863d3918e..0d894d84434 100644 --- a/graph/src/cheap_clone.rs +++ b/graph/src/cheap_clone.rs @@ -118,4 +118,4 @@ cheap_clone_is_copy!( &'static str, std::time::Duration ); -cheap_clone_is_copy!(ethabi::Address); +cheap_clone_is_copy!(web3::types::Address); diff --git a/graph/src/components/adapter.rs b/graph/src/components/adapter.rs index aaae5a89518..f56f36dc25b 100644 --- a/graph/src/components/adapter.rs +++ b/graph/src/components/adapter.rs @@ -595,8 +595,8 @@ mod test { }; use async_trait::async_trait; use chrono::{Duration, Utc}; - use ethabi::ethereum_types::H256; use slog::{o, Discard, Logger}; + use web3::types::H256; use crate::{blockchain::ChainIdentifier, components::adapter::ProviderManagerError}; diff --git a/graph/src/components/store/mod.rs b/graph/src/components/store/mod.rs index 31b0e62cfae..c79b5b3a9e0 100644 --- a/graph/src/components/store/mod.rs +++ b/graph/src/components/store/mod.rs @@ -1262,7 +1262,7 @@ pub struct CachedEthereumCall { pub block_ptr: BlockPtr, /// The address to the called contract. - pub contract_address: ethabi::Address, + pub contract_address: web3::types::Address, /// The encoded return value of this call. pub return_value: Vec, diff --git a/graph/src/data/store/ethereum.rs b/graph/src/data/store/ethereum.rs index 12d48f992df..ae39f1ffcbc 100644 --- a/graph/src/data/store/ethereum.rs +++ b/graph/src/data/store/ethereum.rs @@ -104,7 +104,7 @@ pub mod call { /// on the call's return value #[derive(Debug, Clone, CheapClone)] pub struct Request { - pub address: ethabi::Address, + pub address: web3::types::Address, pub encoded_call: Arc, /// The index is set by the caller and is used to identify the /// request in related data structures that the caller might have @@ -112,7 +112,7 @@ pub mod call { } impl Request { - pub fn new(address: ethabi::Address, encoded_call: Vec, index: u32) -> Self { + pub fn new(address: web3::types::Address, encoded_call: Vec, index: u32) -> Self { Request { address, encoded_call: Arc::new(Bytes::from(encoded_call)), diff --git a/graph/src/lib.rs b/graph/src/lib.rs index fe1b6949642..e48755f848f 100644 --- a/graph/src/lib.rs +++ b/graph/src/lib.rs @@ -37,8 +37,11 @@ pub mod env; pub mod ipfs; +pub mod abi; + /// Wrapper for spawning tasks that abort on panic, which is our default. mod task_spawn; + pub use task_spawn::{ block_on, spawn, spawn_allow_panic, spawn_blocking, spawn_blocking_allow_panic, spawn_thread, }; @@ -81,7 +84,6 @@ pub mod prelude { pub use chrono; pub use diesel; pub use envconfig; - pub use ethabi; pub use hex; pub use isatty; pub use lazy_static::lazy_static; diff --git a/runtime/test/src/common.rs b/runtime/test/src/common.rs index 2416a96a198..776bd3fa91a 100644 --- a/runtime/test/src/common.rs +++ b/runtime/test/src/common.rs @@ -1,4 +1,3 @@ -use ethabi::Contract; use graph::blockchain::BlockTime; use graph::components::store::DeploymentLocator; use graph::data::subgraph::*; @@ -84,7 +83,7 @@ fn mock_host_exports( fn mock_abi() -> MappingABI { MappingABI { name: "mock_abi".to_string(), - contract: Contract::load( + contract: serde_json::from_str( r#"[ { "inputs": [ @@ -95,8 +94,7 @@ fn mock_abi() -> MappingABI { ], "type": "constructor" } - ]"# - .as_bytes(), + ]"#, ) .unwrap(), } diff --git a/runtime/test/src/test/abi.rs b/runtime/test/src/test/abi.rs index b681287c50c..3588634c220 100644 --- a/runtime/test/src/test/abi.rs +++ b/runtime/test/src/test/abi.rs @@ -1,4 +1,4 @@ -use graph::prelude::{ethabi::Token, web3::types::U256}; +use graph::prelude::web3::types::U256; use graph_runtime_wasm::asc_abi::class::{ ArrayBuffer, AscAddress, AscEnum, AscEnumArray, EthereumValueKind, StoreValueKind, TypedArray, }; @@ -178,9 +178,9 @@ async fn abi_bytes_and_fixed_bytes_v0_0_5() { test_abi_bytes_and_fixed_bytes(API_VERSION_0_0_5).await; } -async fn test_abi_ethabi_token_identity(api_version: Version) { +async fn test_abi_alloy_token_identity(api_version: Version) { let mut instance = test_module( - "abiEthabiTokenIdentity", + "abiAlloyTokenIdentity", mock_data_source( &wasm_file_path("abi_token.wasm", api_version.clone()), api_version.clone(), @@ -191,7 +191,7 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { // Token::Address let address = H160([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]); - let token_address = Token::Address(address); + let token_address = graph::abi::DecodedValue::Address(address.to_fixed_bytes().into()); let new_address_obj: AscPtr = instance.invoke_export1("token_to_address", &token_address); @@ -202,7 +202,7 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { assert_eq!(token_address, new_token); // Token::Bytes - let token_bytes = Token::Bytes(vec![42, 45, 7, 245, 45]); + let token_bytes = graph::abi::DecodedValue::Bytes(vec![42, 45, 7, 245, 45]); let new_bytes_obj: AscPtr = instance.invoke_export1("token_to_bytes", &token_bytes); let new_token_ptr = instance.takes_ptr_returns_ptr("token_from_bytes", new_bytes_obj); @@ -211,7 +211,8 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { assert_eq!(token_bytes, new_token); // Token::Int - let int_token = Token::Int(U256([256, 453452345, 0, 42])); + let int = graph::abi::I256::from_limbs([256, 453452345, 0, 42]); + let int_token = graph::abi::DecodedValue::Int(int, int.bits() as usize); let new_int_obj: AscPtr = instance.invoke_export1("token_to_int", &int_token); let new_token_ptr = instance.takes_ptr_returns_ptr("token_from_int", new_int_obj); @@ -220,7 +221,8 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { assert_eq!(int_token, new_token); // Token::Uint - let uint_token = Token::Uint(U256([256, 453452345, 0, 42])); + let uint = graph::abi::U256::from_limbs([256, 453452345, 0, 42]); + let uint_token = graph::abi::DecodedValue::Uint(uint, uint.bit_len()); let new_uint_obj: AscPtr = instance.invoke_export1("token_to_uint", &uint_token); let new_token_ptr = instance.takes_ptr_returns_ptr("token_from_uint", new_uint_obj); @@ -230,7 +232,7 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { assert_ne!(uint_token, int_token); // Token::Bool - let token_bool = Token::Bool(true); + let token_bool = graph::abi::DecodedValue::Bool(true); let token_bool_ptr = instance.asc_new(&token_bool).unwrap(); let func = instance @@ -251,7 +253,7 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { assert_eq!(token_bool, new_token); // Token::String - let token_string = Token::String("漢字Go🇧🇷".into()); + let token_string = graph::abi::DecodedValue::String("漢字Go🇧🇷".into()); let new_string_obj: AscPtr = instance.invoke_export1("token_to_string", &token_string); let new_token_ptr = instance.takes_ptr_returns_ptr("token_from_string", new_string_obj); @@ -260,13 +262,13 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { assert_eq!(token_string, new_token); // Token::Array - let token_array = Token::Array(vec![token_address, token_bytes, token_bool]); - let token_array_nested = Token::Array(vec![token_string, token_array]); + let token_array = graph::abi::DecodedValue::Array(vec![token_address, token_bytes, token_bool]); + let token_array_nested = graph::abi::DecodedValue::Array(vec![token_string, token_array]); let new_array_obj: AscEnumArray = instance.invoke_export1("token_to_array", &token_array_nested); let new_token_ptr = instance.takes_ptr_returns_ptr("token_from_array", new_array_obj); - let new_token: Token = instance.asc_get(new_token_ptr).unwrap(); + let new_token: graph::abi::DecodedValue = instance.asc_get(new_token_ptr).unwrap(); assert_eq!(new_token, token_array_nested); } @@ -274,15 +276,15 @@ async fn test_abi_ethabi_token_identity(api_version: Version) { /// Test a roundtrip Token -> Payload -> Token identity conversion through asc, /// and assert the final token is the same as the starting one. #[tokio::test] -async fn abi_ethabi_token_identity_v0_0_4() { - test_abi_ethabi_token_identity(API_VERSION_0_0_4).await; +async fn abi_alloy_token_identity_v0_0_4() { + test_abi_alloy_token_identity(API_VERSION_0_0_4).await; } /// Test a roundtrip Token -> Payload -> Token identity conversion through asc, /// and assert the final token is the same as the starting one. #[tokio::test] -async fn abi_ethabi_token_identity_v0_0_5() { - test_abi_ethabi_token_identity(API_VERSION_0_0_5).await; +async fn abi_alloy_token_identity_v0_0_5() { + test_abi_alloy_token_identity(API_VERSION_0_0_5).await; } async fn test_abi_store_value(api_version: Version) { diff --git a/runtime/wasm/Cargo.toml b/runtime/wasm/Cargo.toml index 0e6e5d64100..28af409d8ed 100644 --- a/runtime/wasm/Cargo.toml +++ b/runtime/wasm/Cargo.toml @@ -5,7 +5,6 @@ edition.workspace = true [dependencies] async-trait = "0.1.50" -ethabi = "17.2" hex = "0.4.3" graph = { path = "../../graph" } bs58 = "0.4.0" diff --git a/runtime/wasm/src/asc_abi/class.rs b/runtime/wasm/src/asc_abi/class.rs index 366ff844b08..efdd44bf4b3 100644 --- a/runtime/wasm/src/asc_abi/class.rs +++ b/runtime/wasm/src/asc_abi/class.rs @@ -1,5 +1,3 @@ -use ethabi; - use graph::{ data::store::{self, scalar::Timestamp}, runtime::{ @@ -520,21 +518,25 @@ pub enum EthereumValueKind { FixedArray, Array, Tuple, + Function, } impl EthereumValueKind { - pub(crate) fn get_kind(token: ðabi::Token) -> Self { - match token { - ethabi::Token::Address(_) => EthereumValueKind::Address, - ethabi::Token::FixedBytes(_) => EthereumValueKind::FixedBytes, - ethabi::Token::Bytes(_) => EthereumValueKind::Bytes, - ethabi::Token::Int(_) => EthereumValueKind::Int, - ethabi::Token::Uint(_) => EthereumValueKind::Uint, - ethabi::Token::Bool(_) => EthereumValueKind::Bool, - ethabi::Token::String(_) => EthereumValueKind::String, - ethabi::Token::FixedArray(_) => EthereumValueKind::FixedArray, - ethabi::Token::Array(_) => EthereumValueKind::Array, - ethabi::Token::Tuple(_) => EthereumValueKind::Tuple, + pub(crate) fn get_kind(value: &graph::abi::DecodedValue) -> Self { + use graph::abi::DecodedValue; + + match value { + DecodedValue::Bool(_) => Self::Bool, + DecodedValue::Int(_, _) => Self::Int, + DecodedValue::Uint(_, _) => Self::Uint, + DecodedValue::FixedBytes(_, _) => Self::FixedBytes, + DecodedValue::Address(_) => Self::Address, + DecodedValue::Function(_) => Self::Function, + DecodedValue::Bytes(_) => Self::Bytes, + DecodedValue::String(_) => Self::String, + DecodedValue::Array(_) => Self::Array, + DecodedValue::FixedArray(_) => Self::FixedArray, + DecodedValue::Tuple(_) => Self::Tuple, } } } diff --git a/runtime/wasm/src/host_exports.rs b/runtime/wasm/src/host_exports.rs index 4d050db23de..0e64c422174 100644 --- a/runtime/wasm/src/host_exports.rs +++ b/runtime/wasm/src/host_exports.rs @@ -21,8 +21,6 @@ use graph::components::subgraph::{ use graph::data::store::{self}; use graph::data_source::{CausalityRegion, DataSource, EntityTypeAccess}; use graph::ensure; -use graph::prelude::ethabi::param_type::Reader; -use graph::prelude::ethabi::{decode, encode, Token}; use graph::prelude::serde_json; use graph::prelude::{slog::b, slog::record_static, *}; use graph::runtime::gas::{self, complexity, Gas, GasCounter}; @@ -1190,11 +1188,11 @@ impl HostExports { pub(crate) fn ethereum_encode( &self, - token: Token, + value: graph::abi::DecodedValue, gas: &GasCounter, state: &mut BlockState, ) -> Result, DeterministicHostError> { - let encoded = encode(&[token]); + let encoded = value.abi_encode(); Self::track_gas_and_ops( gas, @@ -1212,7 +1210,7 @@ impl HostExports { data: Vec, gas: &GasCounter, state: &mut BlockState, - ) -> Result { + ) -> Result { Self::track_gas_and_ops( gas, state, @@ -1220,15 +1218,9 @@ impl HostExports { "ethereum_decode", )?; - let param_types = - Reader::read(&types).map_err(|e| anyhow::anyhow!("Failed to read types: {}", e))?; + let param_types: graph::abi::ParamType = types.parse().context("Failed to read types")?; - decode(&[param_types], &data) - // The `.pop().unwrap()` here is ok because we're always only passing one - // `param_types` to `decode`, so the returned `Vec` has always size of one. - // We can't do `tokens[0]` because the value can't be moved out of the `Vec`. - .map(|mut tokens| tokens.pop().unwrap()) - .context("Failed to decode") + param_types.abi_decode(&data).context("Failed to decode") } } diff --git a/runtime/wasm/src/to_from/external.rs b/runtime/wasm/src/to_from/external.rs index f08eacee94f..1aa0dc2d270 100644 --- a/runtime/wasm/src/to_from/external.rs +++ b/runtime/wasm/src/to_from/external.rs @@ -1,5 +1,4 @@ -use ethabi; - +use graph::abi::DecodedValueExt; use graph::data::store::scalar::Timestamp; use graph::data::value::Word; use graph::prelude::{BigDecimal, BigInt}; @@ -162,32 +161,42 @@ impl ToAscObj>> for Vec { } } -impl ToAscObj> for ethabi::Token { +impl ToAscObj> for graph::abi::DecodedValue { fn to_asc_obj( &self, heap: &mut H, gas: &GasCounter, ) -> Result, HostExportError> { - use ethabi::Token::*; - let kind = EthereumValueKind::get_kind(self); + let payload = match self { - Address(address) => asc_new::(heap, address, gas)?.to_payload(), - FixedBytes(bytes) | Bytes(bytes) => { - asc_new::(heap, &**bytes, gas)?.to_payload() - } - Int(uint) => { - let n = BigInt::from_signed_u256(uint); + Self::Bool(val) => *val as u64, + Self::Int(val, _) => { + let bytes = val.to_le_bytes::<32>(); + let n = BigInt::from_signed_bytes_le(&bytes)?; + asc_new(heap, &n, gas)?.to_payload() } - Uint(uint) => { - let n = BigInt::from_unsigned_u256(uint); + Self::Uint(val, _) => { + let bytes = val.to_le_bytes::<32>(); + let n = BigInt::from_unsigned_bytes_le(&bytes)?; + asc_new(heap, &n, gas)?.to_payload() } - Bool(b) => *b as u64, - String(string) => asc_new(heap, &**string, gas)?.to_payload(), - FixedArray(tokens) | Array(tokens) => asc_new(heap, &**tokens, gas)?.to_payload(), - Tuple(tokens) => asc_new(heap, &**tokens, gas)?.to_payload(), + Self::FixedBytes(val, _) => { + asc_new::(heap, val.as_slice(), gas)?.to_payload() + } + Self::Address(val) => { + asc_new::(heap, val.as_slice(), gas)?.to_payload() + } + Self::Function(val) => { + asc_new::(heap, val.as_slice(), gas)?.to_payload() + } + Self::Bytes(val) => asc_new::(heap, &**val, gas)?.to_payload(), + Self::String(val) => asc_new(heap, &**val, gas)?.to_payload(), + Self::Array(values) => asc_new(heap, &**values, gas)?.to_payload(), + Self::FixedArray(values) => asc_new(heap, &**values, gas)?.to_payload(), + Self::Tuple(values) => asc_new(heap, &**values, gas)?.to_payload(), }; Ok(AscEnum { @@ -198,57 +207,78 @@ impl ToAscObj> for ethabi::Token { } } -impl FromAscObj> for ethabi::Token { +impl FromAscObj> for graph::abi::DecodedValue { fn from_asc_obj( asc_enum: AscEnum, heap: &H, gas: &GasCounter, depth: usize, ) -> Result { - use ethabi::Token; - let payload = asc_enum.payload; - Ok(match asc_enum.kind { - EthereumValueKind::Bool => Token::Bool(bool::from(payload)), + + let value = match asc_enum.kind { EthereumValueKind::Address => { let ptr: AscPtr = AscPtr::from(payload); - Token::Address(asc_get(heap, ptr, gas, depth)?) + let bytes: [u8; 20] = asc_get(heap, ptr, gas, depth)?; + + Self::Address(bytes.into()) } EthereumValueKind::FixedBytes => { let ptr: AscPtr = AscPtr::from(payload); - Token::FixedBytes(asc_get(heap, ptr, gas, depth)?) + let bytes: Vec = asc_get(heap, ptr, gas, depth)?; + + Self::fixed_bytes_from_slice(&bytes)? } EthereumValueKind::Bytes => { let ptr: AscPtr = AscPtr::from(payload); - Token::Bytes(asc_get(heap, ptr, gas, depth)?) + let bytes: Vec = asc_get(heap, ptr, gas, depth)?; + + Self::Bytes(bytes) } EthereumValueKind::Int => { let ptr: AscPtr = AscPtr::from(payload); let n: BigInt = asc_get(heap, ptr, gas, depth)?; - Token::Int(n.to_signed_u256()) + let x = graph::abi::I256::from_limbs(n.to_signed_u256().0); + + Self::Int(x, x.bits() as usize) } EthereumValueKind::Uint => { let ptr: AscPtr = AscPtr::from(payload); let n: BigInt = asc_get(heap, ptr, gas, depth)?; - Token::Uint(n.to_unsigned_u256()) + let x = graph::abi::U256::from_limbs(n.to_unsigned_u256().0); + + Self::Uint(x, x.bit_len()) } + EthereumValueKind::Bool => Self::Bool(bool::from(payload)), EthereumValueKind::String => { let ptr: AscPtr = AscPtr::from(payload); - Token::String(asc_get(heap, ptr, gas, depth)?) + + Self::String(asc_get(heap, ptr, gas, depth)?) } EthereumValueKind::FixedArray => { let ptr: AscEnumArray = AscPtr::from(payload); - Token::FixedArray(asc_get(heap, ptr, gas, depth)?) + + Self::FixedArray(asc_get(heap, ptr, gas, depth)?) } EthereumValueKind::Array => { let ptr: AscEnumArray = AscPtr::from(payload); - Token::Array(asc_get(heap, ptr, gas, depth)?) + + Self::Array(asc_get(heap, ptr, gas, depth)?) } EthereumValueKind::Tuple => { let ptr: AscEnumArray = AscPtr::from(payload); - Token::Tuple(asc_get(heap, ptr, gas, depth)?) + + Self::Tuple(asc_get(heap, ptr, gas, depth)?) } - }) + EthereumValueKind::Function => { + let ptr: AscPtr = AscPtr::from(payload); + let bytes: [u8; 24] = asc_get(heap, ptr, gas, depth)?; + + Self::Function(bytes.into()) + } + }; + + Ok(value) } } diff --git a/store/postgres/src/chain_store.rs b/store/postgres/src/chain_store.rs index b399b15b788..448d0c6065f 100644 --- a/store/postgres/src/chain_store.rs +++ b/store/postgres/src/chain_store.rs @@ -90,8 +90,8 @@ mod data { use graph::blockchain::{Block, BlockHash}; use graph::constraint_violation; use graph::data::store::scalar::Bytes; - use graph::prelude::ethabi::ethereum_types::H160; use graph::prelude::transaction_receipt::LightTransactionReceipt; + use graph::prelude::web3::types::H160; use graph::prelude::web3::types::H256; use graph::prelude::{ serde_json as json, BlockNumber, BlockPtr, CachedEthereumCall, Error, StoreError, diff --git a/store/test-store/Cargo.toml b/store/test-store/Cargo.toml index fe05f12233e..c6e0ad5f59f 100644 --- a/store/test-store/Cargo.toml +++ b/store/test-store/Cargo.toml @@ -19,3 +19,4 @@ prost-types = { workspace = true } [dev-dependencies] hex = "0.4.3" pretty_assertions = "1.4.0" +serde_json = { workspace = true } diff --git a/store/test-store/tests/postgres/store.rs b/store/test-store/tests/postgres/store.rs index aba953975a3..c50d407fe2f 100644 --- a/store/test-store/tests/postgres/store.rs +++ b/store/test-store/tests/postgres/store.rs @@ -22,7 +22,6 @@ use graph::{ BlockStore as _, EntityFilter, EntityOrder, EntityQuery, StatusStore, SubscriptionManager as _, }, - prelude::ethabi::Contract, }; use graph::{data::store::scalar, semver::Version}; use graph::{entity, prelude::*}; @@ -1145,19 +1144,18 @@ fn mock_data_source() -> graph_chain_ethereum::DataSource { fn mock_abi() -> MappingABI { MappingABI { name: "mock_abi".to_string(), - contract: Contract::load( + contract: serde_json::from_str( r#"[ - { - "inputs": [ - { - "name": "a", - "type": "address" - } - ], - "type": "constructor" - } - ]"# - .as_bytes(), + { + "inputs": [ + { + "name": "a", + "type": "address" + } + ], + "type": "constructor" + } + ]"#, ) .unwrap(), } diff --git a/tests/src/fixture/ethereum.rs b/tests/src/fixture/ethereum.rs index b20672ce563..4ccbe7a8c25 100644 --- a/tests/src/fixture/ethereum.rs +++ b/tests/src/fixture/ethereum.rs @@ -6,13 +6,14 @@ use super::{ test_ptr, CommonChainConfig, MutexBlockStreamBuilder, NoopAdapterSelector, NoopRuntimeAdapterBuilder, StaticBlockRefetcher, StaticStreamBuilder, Stores, TestChain, }; +use graph::blockchain::block_stream::BlockWithTriggers; use graph::blockchain::client::ChainClient; use graph::blockchain::{BlockPtr, TriggersAdapterSelector}; use graph::cheap_clone::CheapClone; -use graph::prelude::ethabi::ethereum_types::H256; +use graph::prelude::web3::types::H256; +use graph::prelude::web3::types::U64; use graph::prelude::web3::types::{Address, Log, Transaction, H160}; -use graph::prelude::{ethabi, tiny_keccak, LightEthereumBlock, ENV_VARS}; -use graph::{blockchain::block_stream::BlockWithTriggers, prelude::ethabi::ethereum_types::U64}; +use graph::prelude::{tiny_keccak, LightEthereumBlock, ENV_VARS}; use graph_chain_ethereum::network::EthereumNetworkAdapters; use graph_chain_ethereum::trigger::LogRef; use graph_chain_ethereum::Chain; @@ -136,7 +137,9 @@ pub fn push_test_log(block: &mut BlockWithTriggers, payload: impl Into