From b449c1f67472d2e4332fbafaf7f5f1a5136a0559 Mon Sep 17 00:00:00 2001 From: "refcell.eth" Date: Sun, 4 Dec 2022 12:28:44 -0800 Subject: [PATCH 01/44] fix(readme): Resolve Dependency Type Conflicts (#129) * :bug: resolve dependency type conflicts * :hammer: fix inline payload construction in tests --- Cargo.lock | 353 ++++++++++++++++++----------------- Cargo.toml | 10 +- client/Cargo.toml | 2 +- client/src/rpc.rs | 4 +- common/Cargo.toml | 2 +- common/src/types.rs | 2 +- common/src/utils.rs | 2 +- config/Cargo.toml | 2 +- config/src/checkpoints.rs | 4 +- config/src/config.rs | 12 +- config/tests/checkpoints.rs | 8 +- consensus/Cargo.toml | 2 +- consensus/src/consensus.rs | 4 +- examples/checkpoints.rs | 8 +- examples/config.rs | 2 +- examples/readme.rs | 43 +++++ execution/Cargo.toml | 2 +- execution/src/proof.rs | 2 +- execution/tests/execution.rs | 42 +++-- 19 files changed, 286 insertions(+), 220 deletions(-) create mode 100644 examples/readme.rs diff --git a/Cargo.lock b/Cargo.lock index 657f4e6..98e05a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,20 +25,20 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" dependencies = [ - "getrandom 0.2.8", + "cfg-if", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.19" +version = "0.7.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" dependencies = [ "memchr", ] @@ -88,9 +88,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" dependencies = [ "proc-macro2", "quote", @@ -252,11 +252,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.4" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -358,9 +358,9 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" +checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" dependencies = [ "serde", ] @@ -385,9 +385,9 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "406c859255d568f4f742b3146d51851f3bfd49f734a2c289d9107c4395ee0062" +checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a" dependencies = [ "camino", "cargo-platform", @@ -399,9 +399,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.74" +version = "1.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581f5dba903aac52ea3feb5ec4810848460ee833876f1f9b0fdeab1f19091574" +checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" [[package]] name = "cfg-if" @@ -411,9 +411,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" dependencies = [ "iana-time-zone", "js-sys", @@ -529,7 +529,7 @@ dependencies = [ "bincode", "bs58", "coins-core", - "digest 0.10.5", + "digest 0.10.6", "getrandom 0.2.8", "hmac", "k256", @@ -566,7 +566,7 @@ dependencies = [ "base64 0.12.3", "bech32", "blake2", - "digest 0.10.5", + "digest 0.10.6", "generic-array 0.14.6", "hex", "ripemd", @@ -637,9 +637,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" +checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" [[package]] name = "convert_case" @@ -724,9 +724,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7d4e43b25d3c994662706a1d4fcfc32aaa6afd287502c111b237093bb23f3a" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" dependencies = [ "cc", "cxxbridge-flags", @@ -736,9 +736,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f8829ddc213e2c1368e51a2564c552b65a8cb6a28f31e576270ac81d5e5827" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" dependencies = [ "cc", "codespan-reporting", @@ -751,15 +751,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e72537424b474af1460806647c41d4b6d35d09ef7fe031c5c2fa5766047cc56a" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" [[package]] name = "cxxbridge-macro" -version = "1.0.80" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "309e4fb93eed90e1e14bea0da16b209f81813ba9fc7830c20ed151dd7bc0a4d7" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" dependencies = [ "proc-macro2", "quote", @@ -807,9 +807,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", "crypto-common", @@ -869,7 +869,7 @@ dependencies = [ "base16ct", "crypto-bigint", "der", - "digest 0.10.5", + "digest 0.10.6", "ff", "generic-array 0.14.6", "group", @@ -891,9 +891,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.9.1" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c90bf5f19754d10198ccb95b70664fc925bd1fc090a0fd9a6ebc54acc8cd6272" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" dependencies = [ "atty", "humantime", @@ -910,7 +910,7 @@ checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" dependencies = [ "aes", "ctr", - "digest 0.10.5", + "digest 0.10.6", "hex", "hmac", "pbkdf2", @@ -926,11 +926,11 @@ dependencies = [ [[package]] name = "ethabi" -version = "17.2.0" +version = "18.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" dependencies = [ - "ethereum-types 0.13.1", + "ethereum-types 0.14.1", "hex", "once_cell", "regex", @@ -938,7 +938,7 @@ dependencies = [ "serde_json", "sha3", "thiserror", - "uint 0.9.4", + "uint 0.9.5", ] [[package]] @@ -956,15 +956,15 @@ dependencies = [ [[package]] name = "ethbloom" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" dependencies = [ "crunchy", - "fixed-hash 0.7.0", + "fixed-hash 0.8.0", "impl-codec 0.6.0", "impl-rlp 0.3.0", - "impl-serde 0.3.2", + "impl-serde 0.4.0", "scale-info", "tiny-keccak 2.0.2", ] @@ -985,24 +985,25 @@ dependencies = [ [[package]] name = "ethereum-types" -version = "0.13.1" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" dependencies = [ - "ethbloom 0.12.1", - "fixed-hash 0.7.0", + "ethbloom 0.13.0", + "fixed-hash 0.8.0", "impl-codec 0.6.0", "impl-rlp 0.3.0", - "impl-serde 0.3.2", - "primitive-types 0.11.1", + "impl-serde 0.4.0", + "primitive-types 0.12.1", "scale-info", - "uint 0.9.4", + "uint 0.9.5", ] [[package]] name = "ethers" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f26f9d8d80da18ca72aca51804c65eb2153093af3bec74fd5ce32aa0c1f665" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1015,8 +1016,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4be54dd2260945d784e06ccdeb5ad573e8f1541838cee13a1ab885485eaa0b" dependencies = [ "ethers-core", "once_cell", @@ -1026,8 +1028,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c3c3e119a89f0a9a1e539e7faecea815f74ddcf7c90d0b00d1f524db2fdc9c" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -1044,8 +1047,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4e5ad46aede34901f71afdb7bb555710ed9613d88d644245c657dc371aa228" dependencies = [ "Inflector", "cfg-if", @@ -1061,14 +1065,16 @@ dependencies = [ "serde", "serde_json", "syn", + "toml", "url", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f192e8e4cf2b038318aae01e94e7644e0659a76219e94bcd3203df744341d61f" dependencies = [ "ethers-contract-abigen", "ethers-core", @@ -1081,8 +1087,9 @@ dependencies = [ [[package]] name = "ethers-core" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" dependencies = [ "arrayvec 0.7.2", "bytes", @@ -1100,7 +1107,6 @@ dependencies = [ "rand 0.8.5", "rlp 0.5.2", "rlp-derive", - "rust_decimal", "serde", "serde_json", "strum", @@ -1112,8 +1118,9 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9713f525348e5dde025d09b0a4217429f8074e8ff22c886263cc191e87d8216" dependencies = [ "ethers-core", "getrandom 0.2.8", @@ -1128,8 +1135,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e71df7391b0a9a51208ffb5c7f2d068900e99d6b3128d3a4849d138f194778b7" dependencies = [ "async-trait", "auto_impl 0.5.0", @@ -1153,8 +1161,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" dependencies = [ "async-trait", "auto_impl 1.0.1", @@ -1187,8 +1196,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "1.0.0" -source = "git+https://github.com/ncitron/ethers-rs?branch=fix-retry#04e375470b7ef52d55075aff2f1f7d93daa12a93" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f41ced186867f64773db2e55ffdd92959e094072a1d09a5e5e831d443204f98" dependencies = [ "async-trait", "coins-bip32", @@ -1296,9 +1306,9 @@ dependencies = [ [[package]] name = "fixed-hash" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", "rand 0.8.5", @@ -1413,7 +1423,6 @@ checksum = "3eb42d4fb72227be5778429f9ef5240a38a358925a49f05b5cf702ce7c7e558a" dependencies = [ "futures-channel", "futures-task", - "tokio", ] [[package]] @@ -1540,9 +1549,9 @@ dependencies = [ [[package]] name = "gloo-net" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec897194fb9ac576c708f63d35604bc58f2a262b8cec0fabfed26f3991255f21" +checksum = "9050ff8617e950288d7bf7f300707639fdeda5ca0d0ecf380cff448cfd52f4a6" dependencies = [ "futures-channel", "futures-core", @@ -1560,9 +1569,9 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" +checksum = "98c4a8d6391675c6b2ee1a6c8d06e8e2d03605c44cec1270675985a4c2a5500b" dependencies = [ "futures-channel", "futures-core", @@ -1572,9 +1581,9 @@ dependencies = [ [[package]] name = "gloo-utils" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40913a05c8297adca04392f707b1e73b12ba7b8eab7244a4961580b1fd34063c" +checksum = "a8e8fc851e9c7b9852508bc6e3f690f452f474417e8545ec9857b7f7377036b5" dependencies = [ "js-sys", "serde", @@ -1624,6 +1633,12 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" dependencies = [ "ahash", ] @@ -1651,9 +1666,12 @@ dependencies = [ "common", "config", "consensus", + "env_logger", + "ethers", "execution", "eyre", "home", + "log", "tokio", ] @@ -1678,7 +1696,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -1732,9 +1750,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.22" +version = "0.14.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abfba89e19b959ca163c7752ba59d737c1ceea53a5d31a149c805446fc958064" +checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" dependencies = [ "bytes", "futures-channel", @@ -1756,9 +1774,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.0" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +checksum = "59df7c4e19c950e6e0e868dcc0a300b09a9b88e9ec55bd879ca819087a77355d" dependencies = [ "http", "hyper", @@ -1871,6 +1889,15 @@ dependencies = [ "serde", ] +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -1890,12 +1917,12 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -1927,9 +1954,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" [[package]] name = "itoa" @@ -2144,9 +2171,12 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +dependencies = [ + "cpufeatures", +] [[package]] name = "keccak-hasher" @@ -2170,9 +2200,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.137" +version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] name = "link-cplusplus" @@ -2256,9 +2286,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.0" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e322c04a9e3440c327fca7b6c8a63e6890a32fa2ad689db972425f07e0d22abb" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", "bitflags", @@ -2393,14 +2423,14 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "open-fastrlp" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131de184f045153e72c537ef4f1d57babddf2a897ca19e67bdff697aebba7f3d" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ "arrayvec 0.7.2", "auto_impl 1.0.1", "bytes", - "ethereum-types 0.13.1", + "ethereum-types 0.14.1", "open-fastrlp-derive", ] @@ -2418,9 +2448,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376" dependencies = [ "bitflags", "cfg-if", @@ -2459,9 +2489,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.77" +version = "0.9.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03b84c3b2d099b81f0953422b4d4ad58761589d0229b5506356afca05a3670a" +checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132" dependencies = [ "autocfg", "cc", @@ -2473,9 +2503,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.3.1" +version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" [[package]] name = "parity-scale-codec" @@ -2539,7 +2569,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.4", + "parking_lot_core 0.9.5", ] [[package]] @@ -2558,9 +2588,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" dependencies = [ "cfg-if", "libc", @@ -2586,7 +2616,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", "hmac", "password-hash", "sha2 0.10.6", @@ -2690,9 +2720,9 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "primitive-types" @@ -2709,16 +2739,16 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.11.1" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" dependencies = [ - "fixed-hash 0.7.0", + "fixed-hash 0.8.0", "impl-codec 0.6.0", "impl-rlp 0.3.0", - "impl-serde 0.3.2", + "impl-serde 0.4.0", "scale-info", - "uint 0.9.4", + "uint 0.9.5", ] [[package]] @@ -2892,9 +2922,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ "aho-corasick", "memchr", @@ -2903,9 +2933,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" [[package]] name = "remove_dir_all" @@ -3008,16 +3038,16 @@ dependencies = [ [[package]] name = "revm" -version = "2.1.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87344ffd3eec06b568e1fc69c225e4cbd8d68d8d9051b6d2652d596947efa1ce" +checksum = "73d84c8f9836efb0f5f5f8de4700a953c4e1f3119e5cfcb0aad8e5be73daf991" dependencies = [ "arrayref", "auto_impl 1.0.1", "bytes", - "hashbrown", + "hashbrown 0.13.1", "num_enum", - "primitive-types 0.11.1", + "primitive-types 0.12.1", "revm_precompiles", "rlp 0.5.2", "sha3", @@ -3025,15 +3055,15 @@ dependencies = [ [[package]] name = "revm_precompiles" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e68901326fe20437526cb6d64a2898d2976383b7d222329dfce1717902da50" +checksum = "0353d456ef3e989dc9190f42c6020f09bc2025930c37895826029304413204b5" dependencies = [ "bytes", - "hashbrown", + "hashbrown 0.13.1", "num", "once_cell", - "primitive-types 0.11.1", + "primitive-types 0.12.1", "ripemd", "secp256k1", "sha2 0.10.6", @@ -3073,7 +3103,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -3106,17 +3136,6 @@ dependencies = [ "syn", ] -[[package]] -name = "rust_decimal" -version = "1.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee9164faf726e4f3ece4978b25ca877ddc6802fa77f38cdccb32c7f805ecd70c" -dependencies = [ - "arrayvec 0.7.2", - "num-traits", - "serde", -] - [[package]] name = "rustc-hash" version = "1.1.0" @@ -3347,18 +3366,18 @@ checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7" [[package]] name = "serde" -version = "1.0.147" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" dependencies = [ "serde_derive", ] [[package]] name = "serde-aux" -version = "4.0.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c79c1a5a310c28bf9f7a4b9bd848553051120d80a5952f993c7eb62f6ed6e4c5" +checksum = "c599b3fd89a75e0c18d6d2be693ddb12cccaf771db4ff9e39097104808a014c0" dependencies = [ "serde", "serde_json", @@ -3366,9 +3385,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" dependencies = [ "proc-macro2", "quote", @@ -3377,9 +3396,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" dependencies = [ "itoa", "ryu", @@ -3457,7 +3476,7 @@ checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.5", + "digest 0.10.6", ] [[package]] @@ -3466,7 +3485,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", "keccak", ] @@ -3485,7 +3504,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.5", + "digest 0.10.6", "rand_core 0.6.4", ] @@ -3625,9 +3644,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" dependencies = [ "proc-macro2", "quote", @@ -3721,9 +3740,9 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", @@ -3765,9 +3784,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.21.2" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" dependencies = [ "autocfg", "bytes", @@ -3785,9 +3804,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" dependencies = [ "proc-macro2", "quote", @@ -3944,9 +3963,9 @@ dependencies = [ [[package]] name = "uint" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45526d29728d135c2900b0d30573fe3ee79fceb12ef534c7bb30e810a91b601" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder", "crunchy", @@ -4108,8 +4127,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" dependencies = [ "cfg-if", - "serde", - "serde_json", "wasm-bindgen-macro", ] @@ -4384,9 +4401,9 @@ dependencies = [ [[package]] name = "wyz" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b31594f29d27036c383b53b59ed3476874d518f0efb151b27a4c275141390e" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ "tap", ] @@ -4408,9 +4425,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a5cabc1..e099335 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,18 +21,22 @@ common = { path = "./common" } consensus = { path = "./consensus" } execution = { path = "./execution" } -[patch.crates-io] -ethers = { git = "https://github.com/ncitron/ethers-rs", branch = "fix-retry" } - [dev-dependencies] tokio = { version = "1", features = ["full"] } eyre = "0.6.8" home = "0.5.4" +ethers = "1.0.2" +env_logger = "0.9.0" +log = "0.4.17" [[example]] name = "checkpoints" path = "examples/checkpoints.rs" +[[example]] +name = "readme" +path = "examples/readme.rs" + [[example]] name = "client" path = "examples/client.rs" diff --git a/client/Cargo.toml b/client/Cargo.toml index cbaa020..59bec83 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -9,7 +9,7 @@ eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } hex = "0.4.3" ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.0" +ethers = "1.0.2" jsonrpsee = { version = "0.15.1", features = ["full"] } futures = "0.3.23" log = "0.4.17" diff --git a/client/src/rpc.rs b/client/src/rpc.rs index db34689..93832c3 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -123,7 +123,7 @@ impl EthRpcServer for RpcInner { let node = self.node.read().await; let nonce = convert_err(node.get_nonce(&address, block).await)?; - Ok(format!("0x{:x}", nonce)) + Ok(format!("0x{nonce:x}")) } async fn get_code(&self, address: &str, block: BlockTag) -> Result { @@ -267,5 +267,5 @@ fn format_hex(num: &U256) -> String { .trim_start_matches('0') .to_string(); - format!("0x{}", stripped) + format!("0x{stripped}") } diff --git a/common/Cargo.toml b/common/Cargo.toml index 9ae1181..7edc1db 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -8,5 +8,5 @@ eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } hex = "0.4.3" ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.0" +ethers = "1.0.2" thiserror = "1.0.37" diff --git a/common/src/types.rs b/common/src/types.rs index af15ce9..5f8cbec 100644 --- a/common/src/types.rs +++ b/common/src/types.rs @@ -20,7 +20,7 @@ impl Display for BlockTag { Self::Number(num) => num.to_string(), }; - write!(f, "{}", formatted) + write!(f, "{formatted}") } } diff --git a/common/src/utils.rs b/common/src/utils.rs index 97baf91..b041fe4 100644 --- a/common/src/utils.rs +++ b/common/src/utils.rs @@ -22,5 +22,5 @@ pub fn address_to_hex_string(address: &Address) -> String { } pub fn u64_to_hex_string(val: u64) -> String { - format!("0x{:x}", val) + format!("0x{val:x}") } diff --git a/config/Cargo.toml b/config/Cargo.toml index 8162df8..120885b 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -10,7 +10,7 @@ eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } hex = "0.4.3" ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.0" +ethers = "1.0.2" figment = { version = "0.10.7", features = ["toml", "env"] } thiserror = "1.0.37" log = "0.4.17" diff --git a/config/src/checkpoints.rs b/config/src/checkpoints.rs index 7aa4c1f..827cac6 100644 --- a/config/src/checkpoints.rs +++ b/config/src/checkpoints.rs @@ -101,7 +101,7 @@ impl CheckpointFallback { let service_list = list .get(network.to_string().to_lowercase()) .ok_or_else(|| { - eyre::eyre!(format!("missing {} fallback checkpoint services", network)) + eyre::eyre!(format!("missing {network} fallback checkpoint services")) })?; let parsed: Vec = serde_yaml::from_value(service_list.clone())?; @@ -202,7 +202,7 @@ impl CheckpointFallback { /// assert_eq!("https://sync-mainnet.beaconcha.in/checkpointz/v1/beacon/slots", url); /// ``` pub fn construct_url(endpoint: &str) -> String { - format!("{}/checkpointz/v1/beacon/slots", endpoint) + format!("{endpoint}/checkpointz/v1/beacon/slots") } /// Returns a list of all checkpoint fallback endpoints. diff --git a/config/src/config.rs b/config/src/config.rs index daf7149..c2692a0 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -55,20 +55,14 @@ impl Config { figment::error::Kind::MissingField(field) => { let field = field.replace('_', "-"); - println!( - "\x1b[91merror\x1b[0m: missing configuration field: {}", - field - ); + println!("\x1b[91merror\x1b[0m: missing configuration field: {field}"); - println!( - "\n\ttry supplying the propoper command line argument: --{}", - field - ); + println!("\n\ttry supplying the propoper command line argument: --{field}"); println!("\talternatively, you can add the field to your helios.toml file or as an environment variable"); println!("\nfor more information, check the github README"); } - _ => println!("cannot parse configuration: {}", err), + _ => println!("cannot parse configuration: {err}"), } exit(1); } diff --git a/config/tests/checkpoints.rs b/config/tests/checkpoints.rs index acb535e..1d50e61 100644 --- a/config/tests/checkpoints.rs +++ b/config/tests/checkpoints.rs @@ -50,9 +50,9 @@ async fn test_get_all_fallback_endpoints() { .await .unwrap(); let urls = cf.get_all_fallback_endpoints(&networks::Network::MAINNET); - assert!(urls.len() > 0); + assert!(!urls.is_empty()); let urls = cf.get_all_fallback_endpoints(&networks::Network::GOERLI); - assert!(urls.len() > 0); + assert!(!urls.is_empty()); } #[tokio::test] @@ -62,7 +62,7 @@ async fn test_get_healthy_fallback_endpoints() { .await .unwrap(); let urls = cf.get_healthy_fallback_endpoints(&networks::Network::MAINNET); - assert!(urls.len() > 0); + assert!(!urls.is_empty()); let urls = cf.get_healthy_fallback_endpoints(&networks::Network::GOERLI); - assert!(urls.len() > 0); + assert!(!urls.is_empty()); } diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index bf96ac2..5f3fa4c 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -11,7 +11,7 @@ serde_json = "1.0.85" hex = "0.4.3" ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } blst = "0.3.10" -ethers = "1.0.0" +ethers = "1.0.2" bytes = "1.2.1" toml = "0.5.9" async-trait = "0.1.57" diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index 7c4d106..8eb6258 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -661,7 +661,7 @@ mod tests { let mut update = updates[0].clone(); update.finalized_header = Header::default(); - let err = client.verify_update(&mut update).err().unwrap(); + let err = client.verify_update(&update).err().unwrap(); assert_eq!( err.to_string(), ConsensusError::InvalidFinalityProof.to_string() @@ -681,7 +681,7 @@ mod tests { let mut update = updates[0].clone(); update.sync_aggregate.sync_committee_signature = Vector::default(); - let err = client.verify_update(&mut update).err().unwrap(); + let err = client.verify_update(&update).err().unwrap(); assert_eq!( err.to_string(), ConsensusError::InvalidSignature.to_string() diff --git a/examples/checkpoints.rs b/examples/checkpoints.rs index e74a4f0..1337a9f 100644 --- a/examples/checkpoints.rs +++ b/examples/checkpoints.rs @@ -19,24 +19,24 @@ async fn main() -> Result<()> { .fetch_latest_checkpoint(&networks::Network::GOERLI) .await .unwrap(); - println!("Fetched latest goerli checkpoint: {}", goerli_checkpoint); + println!("Fetched latest goerli checkpoint: {goerli_checkpoint}"); // Fetch the latest mainnet checkpoint let mainnet_checkpoint = cf .fetch_latest_checkpoint(&networks::Network::MAINNET) .await .unwrap(); - println!("Fetched latest mainnet checkpoint: {}", mainnet_checkpoint); + println!("Fetched latest mainnet checkpoint: {mainnet_checkpoint}"); // Let's get a list of all the fallback service endpoints for mainnet let endpoints = cf.get_all_fallback_endpoints(&networks::Network::MAINNET); - println!("Fetched all mainnet fallback endpoints: {:?}", endpoints); + println!("Fetched all mainnet fallback endpoints: {endpoints:?}"); // Since we built the checkpoint fallback services, we can also just get the raw checkpoint fallback services. // The `get_fallback_services` method returns a reference to the internal list of CheckpointFallbackService objects // for the given network. let services = cf.get_fallback_services(&networks::Network::MAINNET); - println!("Fetched all mainnet fallback services: {:?}", services); + println!("Fetched all mainnet fallback services: {services:?}"); Ok(()) } diff --git a/examples/config.rs b/examples/config.rs index c055477..e16d86d 100644 --- a/examples/config.rs +++ b/examples/config.rs @@ -8,7 +8,7 @@ async fn main() -> Result<()> { // Load the config from the global config file let config_path = home::home_dir().unwrap().join(".helios/helios.toml"); let config = Config::from_file(&config_path, "mainnet", &CliConfig::default()); - println!("Constructed config: {:#?}", config); + println!("Constructed config: {config:#?}"); Ok(()) } diff --git a/examples/readme.rs b/examples/readme.rs new file mode 100644 index 0000000..24e4ddc --- /dev/null +++ b/examples/readme.rs @@ -0,0 +1,43 @@ +use std::str::FromStr; + +use env_logger::Env; +use ethers::{types::Address, utils}; +use eyre::Result; +use helios::{client::ClientBuilder, config::networks::Network, types::BlockTag}; + +#[tokio::main] +async fn main() -> Result<()> { + env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); + + let untrusted_rpc_url = "https://mainnet.infura.io/v3/"; + log::info!("Using untrusted RPC URL [REDACTED]"); + + let consensus_rpc = "https://www.lightclientdata.org"; + log::info!("Using consensus RPC URL: {}", consensus_rpc); + + let mut client = ClientBuilder::new() + .network(Network::MAINNET) + .consensus_rpc(consensus_rpc) + .execution_rpc(untrusted_rpc_url) + .load_external_fallback() + .build()?; + log::info!( + "Built client on network \"{}\" with external checkpoint fallbacks", + Network::MAINNET + ); + + client.start().await?; + + let head_block_num = client.get_block_number().await?; + let addr = Address::from_str("0x00000000219ab540356cBB839Cbe05303d7705Fa")?; + let block = BlockTag::Latest; + let balance = client.get_balance(&addr, block).await?; + + log::info!("synced up to block: {}", head_block_num); + log::info!( + "balance of deposit contract: {}", + utils::format_ether(balance) + ); + + Ok(()) +} diff --git a/execution/Cargo.toml b/execution/Cargo.toml index ee819f5..012c271 100644 --- a/execution/Cargo.toml +++ b/execution/Cargo.toml @@ -11,7 +11,7 @@ serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.85" hex = "0.4.3" ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.0" +ethers = "1.0.2" revm = "2.1.0" bytes = "1.2.1" futures = "0.3.23" diff --git a/execution/src/proof.rs b/execution/src/proof.rs index 72b5e9a..0d836ab 100644 --- a/execution/src/proof.rs +++ b/execution/src/proof.rs @@ -90,7 +90,7 @@ fn get_rest_path(p: &Vec, s: usize) -> String { let mut ret = String::new(); for i in s..p.len() * 2 { let n = get_nibble(p, i); - ret += &format!("{:01x}", n); + ret += &format!("{n:01x}"); } ret } diff --git a/execution/tests/execution.rs b/execution/tests/execution.rs index ddcd890..5c95859 100644 --- a/execution/tests/execution.rs +++ b/execution/tests/execution.rs @@ -18,11 +18,13 @@ async fn test_get_account() { let execution = get_client(); let address = Address::from_str("14f9D4aF749609c1438528C0Cce1cC3f6D411c47").unwrap(); - let mut payload = ExecutionPayload::default(); - payload.state_root = Vector::from_iter( - hex_str_to_bytes("0xaa02f5db2ee75e3da400d10f3c30e894b6016ce8a2501680380a907b6674ce0d") - .unwrap(), - ); + let payload = ExecutionPayload { + state_root: Vector::from_iter( + hex_str_to_bytes("0xaa02f5db2ee75e3da400d10f3c30e894b6016ce8a2501680380a907b6674ce0d") + .unwrap(), + ), + ..ExecutionPayload::default() + }; let account = execution .get_account(&address, None, &payload) @@ -102,11 +104,13 @@ async fn test_get_tx_not_included() { #[tokio::test] async fn test_get_logs() { let execution = get_client(); - let mut payload = ExecutionPayload::default(); - payload.receipts_root = Vector::from_iter( - hex_str_to_bytes("dd82a78eccb333854f0c99e5632906e092d8a49c27a21c25cae12b82ec2a113f") - .unwrap(), - ); + let mut payload = ExecutionPayload { + receipts_root: Vector::from_iter( + hex_str_to_bytes("dd82a78eccb333854f0c99e5632906e092d8a49c27a21c25cae12b82ec2a113f") + .unwrap(), + ), + ..ExecutionPayload::default() + }; payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap())); @@ -130,11 +134,13 @@ async fn test_get_receipt() { let tx_hash = H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap(); - let mut payload = ExecutionPayload::default(); - payload.receipts_root = Vector::from_iter( - hex_str_to_bytes("dd82a78eccb333854f0c99e5632906e092d8a49c27a21c25cae12b82ec2a113f") - .unwrap(), - ); + let mut payload = ExecutionPayload { + receipts_root: Vector::from_iter( + hex_str_to_bytes("dd82a78eccb333854f0c99e5632906e092d8a49c27a21c25cae12b82ec2a113f") + .unwrap(), + ), + ..ExecutionPayload::default() + }; payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap())); @@ -185,8 +191,10 @@ async fn test_get_receipt_not_included() { #[tokio::test] async fn test_get_block() { let execution = get_client(); - let mut payload = ExecutionPayload::default(); - payload.block_number = 12345; + let payload = ExecutionPayload { + block_number: 12345, + ..ExecutionPayload::default() + }; let block = execution.get_block(&payload, false).await.unwrap(); From d8db74ede9b37ad517c02443fa7aa502ce4cb0e4 Mon Sep 17 00:00:00 2001 From: sragss <65786432+sragss@users.noreply.github.com> Date: Thu, 8 Dec 2022 07:57:21 -0800 Subject: [PATCH 02/44] fix: surface eth_getStorageAt (#124) * feat: surface eth_getStorageAt * add blocktag * cargo fmt --- client/src/client.rs | 13 +++++++++++-- client/src/node.rs | 9 +++++++-- client/src/rpc.rs | 20 ++++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 23c435c..353cc1c 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -344,8 +344,17 @@ impl Client { self.node.read().await.get_code(address, block).await } - pub async fn get_storage_at(&self, address: &Address, slot: H256) -> Result { - self.node.read().await.get_storage_at(address, slot).await + pub async fn get_storage_at( + &self, + address: &Address, + slot: H256, + block: BlockTag, + ) -> Result { + self.node + .read() + .await + .get_storage_at(address, slot, block) + .await } pub async fn send_raw_transaction(&self, bytes: &[u8]) -> Result { diff --git a/client/src/node.rs b/client/src/node.rs index fb98292..02d02af 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -163,10 +163,15 @@ impl Node { Ok(account.code) } - pub async fn get_storage_at(&self, address: &Address, slot: H256) -> Result { + pub async fn get_storage_at( + &self, + address: &Address, + slot: H256, + block: BlockTag, + ) -> Result { self.check_head_age()?; - let payload = self.get_payload(BlockTag::Latest)?; + let payload = self.get_payload(block)?; let account = self .execution .get_account(address, Some(&[slot]), payload) diff --git a/client/src/rpc.rs b/client/src/rpc.rs index 93832c3..3f72c7b 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -94,6 +94,13 @@ trait EthRpc { async fn get_transaction_by_hash(&self, hash: &str) -> Result, Error>; #[method(name = "getLogs")] async fn get_logs(&self, filter: Filter) -> Result, Error>; + #[method(name = "getStorageAt")] + async fn get_storage_at( + &self, + address: &str, + slot: H256, + block: BlockTag, + ) -> Result; } #[rpc(client, server, namespace = "net")] @@ -227,6 +234,19 @@ impl EthRpcServer for RpcInner { let node = self.node.read().await; convert_err(node.get_logs(&filter).await) } + + async fn get_storage_at( + &self, + address: &str, + slot: H256, + block: BlockTag, + ) -> Result { + let address = convert_err(Address::from_str(address))?; + let node = self.node.read().await; + let storage = convert_err(node.get_storage_at(&address, slot, block).await)?; + + Ok(format_hex(&storage)) + } } #[async_trait] From f37aa2aa45d8f85c5bd4813b71acef62be83af03 Mon Sep 17 00:00:00 2001 From: Giovanni Vignone <72773059+giovannivignone@users.noreply.github.com> Date: Sun, 11 Dec 2022 11:45:34 -0500 Subject: [PATCH 03/44] documentation: add rpc docs (#136) * adding documentation for rpc.md * adding rpc methods in table for rpc.md * adjusting readme to link to rpc.md * fixing grammar * grammar * adding RPC Methods according to documentation and listing column as Client Function * adding more description space * undoing description spacing --- README.md | 3 ++- rpc.md | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 rpc.md diff --git a/README.md b/README.md index b6129c8..3d51dd1 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,9 @@ helios --execution-rpc $ETH_RPC_URL Helios will now run a local RPC server at `http://127.0.0.1:8545`. -Helios also provides examples in the [`examples/`](./examples/) directory. To run an example, you can execute `cargo run --example ` from inside the helios repository. +Helios provides examples in the [`examples/`](./examples/) directory. To run an example, you can execute `cargo run --example ` from inside the helios repository. +Helios also provides documentation of its supported RPC methods in the [rpc.md](./rpc.md) file. ### Warning diff --git a/rpc.md b/rpc.md new file mode 100644 index 0000000..987a21e --- /dev/null +++ b/rpc.md @@ -0,0 +1,23 @@ +# Helios Remote Procedure Calls + +Helios provides a variety of RPC methods for interacting with the Ethereum network. These methods are exposed via the `Client` struct. The RPC methods follow the [Ethereum JSON RPC Spec](https://ethereum.github.io/execution-apis/api-documentation). See [examples](./examples/readme.rs) of running remote procedure calls with Helios. + +## RPC Methods + +| RPC Method | Client Function | Description | Example | +| ---------- | --------------- | ----------- | ------- | +| `eth_getBalance` | `get_balance` | Returns the balance of the account given an address. | `client.get_balance(&self, address: &str, block: BlockTag)` | +| `eth_getTransactionCount` | `get_transaction_count` | Returns the number of transactions sent from the given address. | `client.get_transaction_count(&self, address: &str, block: BlockTag)` | +| `eth_getCode` | `get_code` | Returns the code at a given address. | `client.get_code(&self, address: &str, block: BlockTag)` | +| `eth_call` | `call` | Executes a new message call immediately without creating a transaction on the blockchain. | `client.call(&self, opts: CallOpts, block: BlockTag)` | +| `eth_estimateGas` | `estimate_gas` | Generates and returns an estimate of how much gas is necessary to allow the transaction to complete. | `client.estimate_gas(&self, opts: CallOpts)` | +| `eth_getChainId` | `chain_id` | Returns the chain ID of the current network. | `client.chain_id(&self)` | +| `eth_gasPrice` | `gas_price` | Returns the current price per gas in wei. | `client.gas_price(&self)` | +| `eth_maxPriorityFeePerGas` | `max_priority_fee_per_gas` | Returns the current max priority fee per gas in wei. | `client.max_priority_fee_per_gas(&self)` | +| `eth_blockNumber` | `block_number` | Returns the number of the most recent block. | `client.block_number(&self)` | +| `eth_getBlockByNumber` | `get_block_by_number` | Returns the information of a block by number. | `get_block_by_number(&self, block: BlockTag, full_tx: bool)` | +| `eth_getBlockByHash` | `get_block_by_hash` | Returns the information of a block by hash. | `get_block_by_hash(&self, hash: &str, full_tx: bool)` | +| `eth_sendRawTransaction` | `send_raw_transaction` | Submits a raw transaction to the network. | `client.send_raw_transaction(&self, bytes: &str)` | +| `eth_getTransactionReceipt` | `get_transaction_receipt` | Returns the receipt of a transaction by transaction hash. | `client.get_transaction_receipt(&self, hash: &str)` | +| `eth_getLogs` | `get_logs` | Returns an array of logs matching the filter. | `client.get_logs(&self, filter: Filter)` | +| `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` | \ No newline at end of file From 94bf458d941f30e34faeaa7d2484898dba54234d Mon Sep 17 00:00:00 2001 From: "refcell.eth" Date: Sun, 11 Dec 2022 11:42:52 -0800 Subject: [PATCH 04/44] feat(benches): Criterion + Iai Benchmarking [RFC] (#131) * :gear: benches * :memo: docs * :building_construction: file_db benches and checkpoint fixes * :hammer: fix github action env vars * :white_check_mark: benchmark env vars * :gear: sync benchmarks * :sparkles: cargo fmt touchups --- .github/workflows/test.yml | 33 +- .gitignore | 2 + Cargo.lock | 699 ++++++++++++++++++++++++++++++++++++- Cargo.toml | 32 +- README.md | 13 +- benches/file_db.rs | 43 +++ benches/get_balance.rs | 63 ++++ benches/get_code.rs | 63 ++++ benches/harness.rs | 113 ++++++ benches/sync.rs | 81 +++++ client/src/database.rs | 18 +- config/src/checkpoints.rs | 41 ++- 12 files changed, 1167 insertions(+), 34 deletions(-) create mode 100644 benches/file_db.rs create mode 100644 benches/get_balance.rs create mode 100644 benches/get_code.rs create mode 100644 benches/harness.rs create mode 100644 benches/sync.rs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 295d046..1066a60 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,12 +6,15 @@ on: pull_request: branches: [ "master" ] +env: + MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }} + GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }} + jobs: check: - name: check runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -23,10 +26,9 @@ jobs: command: check test: - name: test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -39,10 +41,9 @@ jobs: args: --all fmt: - name: fmt runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: profile: minimal @@ -55,11 +56,25 @@ jobs: command: fmt args: --all -- --check - clippy: - name: clippy + benches: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: rustfmt + - uses: Swatinem/rust-cache@v2 + - uses: actions-rs/cargo@v1 + with: + command: bench + + clippy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: profile: minimal diff --git a/.gitignore b/.gitignore index ea8c4bf..5868362 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target + +*.env diff --git a/Cargo.lock b/Cargo.lock index 98e05a9..88ad67b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,6 +12,12 @@ dependencies = [ "regex", ] +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aes" version = "0.8.2" @@ -52,6 +58,12 @@ dependencies = [ "libc", ] +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + [[package]] name = "anyhow" version = "1.0.66" @@ -105,7 +117,7 @@ checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ "futures", "pharos", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -350,6 +362,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" +[[package]] +name = "bytemuck" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" + [[package]] name = "byteorder" version = "1.4.3" @@ -391,12 +409,18 @@ checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a" dependencies = [ "camino", "cargo-platform", - "semver", + "semver 1.0.14", "serde", "serde_json", "thiserror", ] +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + [[package]] name = "cc" version = "1.0.77" @@ -424,6 +448,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "ciborium" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" + +[[package]] +name = "ciborium-ll" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.3" @@ -510,6 +561,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "cmake" +version = "0.1.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +dependencies = [ + "cc", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -577,6 +637,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "common" version = "0.1.0" @@ -635,6 +701,12 @@ dependencies = [ "toml", ] +[[package]] +name = "const-cstr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3d0b5ff30645a68f35ece8cea4556ca14ef8a1651455f789a099a0513532a6" + [[package]] name = "const-oid" version = "0.9.1" @@ -666,6 +738,43 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types", + "libc", +] + +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.5" @@ -675,6 +784,96 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" +dependencies = [ + "anes", + "atty", + "cast", + "ciborium", + "clap", + "criterion-plot", + "futures", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "tokio", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -825,6 +1024,16 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + [[package]] name = "dirs-sys" version = "0.3.7" @@ -836,12 +1045,44 @@ dependencies = [ "winapi", ] +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading", +] + [[package]] name = "dunce" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "winapi", + "wio", +] + [[package]] name = "ecdsa" version = "0.14.8" @@ -1125,7 +1366,7 @@ dependencies = [ "ethers-core", "getrandom 0.2.8", "reqwest", - "semver", + "semver 1.0.14", "serde", "serde-aux", "serde_json", @@ -1316,12 +1557,53 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-ord" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "font-kit" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21fe28504d371085fae9ac7a3450f0b289ab71e07c8e57baa3fb68b9e57d6ce5" +dependencies = [ + "bitflags", + "byteorder", + "core-foundation", + "core-graphics", + "core-text", + "dirs-next", + "dwrote", + "float-ord", + "freetype", + "lazy_static", + "libc", + "log", + "pathfinder_geometry", + "pathfinder_simd", + "walkdir", + "winapi", + "yeslogic-fontconfig-sys", +] + [[package]] name = "foreign-types" version = "0.3.2" @@ -1346,6 +1628,27 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "freetype" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" +dependencies = [ + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + [[package]] name = "funty" version = "2.0.0" @@ -1528,6 +1831,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06" +dependencies = [ + "color_quant", + "weezl", +] + [[package]] name = "glob" version = "0.3.0" @@ -1622,6 +1935,12 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hash-db" version = "0.15.2" @@ -1660,19 +1979,24 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "helios" -version = "0.1.1" +version = "0.1.2" dependencies = [ "client", "common", "config", "consensus", + "criterion", "env_logger", "ethers", "execution", "eyre", + "hex", "home", "log", + "plotters", + "tempfile", "tokio", + "tracing-test", ] [[package]] @@ -1835,6 +2159,21 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", +] + [[package]] name = "impl-codec" version = "0.4.2" @@ -1958,12 +2297,27 @@ version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" + [[package]] name = "js-sys" version = "0.3.60" @@ -2204,6 +2558,16 @@ version = "0.2.138" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "link-cplusplus" version = "1.0.7" @@ -2232,12 +2596,30 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.16" @@ -2254,6 +2636,15 @@ dependencies = [ "unicase", ] +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.5" @@ -2296,6 +2687,16 @@ dependencies = [ "libc", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num" version = "0.4.0" @@ -2409,6 +2810,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + [[package]] name = "opaque-debug" version = "0.2.3" @@ -2507,6 +2914,12 @@ version = "6.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parity-scale-codec" version = "1.3.7" @@ -2610,6 +3023,25 @@ dependencies = [ "subtle", ] +[[package]] +name = "pathfinder_geometry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" +dependencies = [ + "log", + "pathfinder_simd", +] + +[[package]] +name = "pathfinder_simd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" +dependencies = [ + "rustc_version 0.3.3", +] + [[package]] name = "pbkdf2" version = "0.11.0" @@ -2651,6 +3083,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pest" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" +dependencies = [ + "thiserror", + "ucd-trie", +] + [[package]] name = "pharos" version = "0.5.3" @@ -2658,7 +3100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" dependencies = [ "futures", - "rustc_version", + "rustc_version 0.4.0", ] [[package]] @@ -2718,6 +3160,64 @@ dependencies = [ "crunchy", ] +[[package]] +name = "plotters" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +dependencies = [ + "chrono", + "font-kit", + "image", + "lazy_static", + "num-traits", + "pathfinder_geometry", + "plotters-backend", + "plotters-bitmap", + "plotters-svg", + "ttf-parser", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" + +[[package]] +name = "plotters-bitmap" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4a1f21490a6cf4a84c272ad20bd7844ed99a3178187a4c5ab7f2051295beef" +dependencies = [ + "gif", + "image", + "plotters-backend", +] + +[[package]] +name = "plotters-svg" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2900,6 +3400,29 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rayon" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" +dependencies = [ + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -2931,6 +3454,15 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + [[package]] name = "regex-syntax" version = "0.6.28" @@ -3148,13 +3680,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.14", ] [[package]] @@ -3343,6 +3884,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.14" @@ -3352,6 +3902,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 = "send_wrapper" version = "0.4.0" @@ -3489,6 +4048,15 @@ dependencies = [ "keccak", ] +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -3729,6 +4297,15 @@ dependencies = [ "syn", ] +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + [[package]] name = "threadpool" version = "1.8.1" @@ -3767,6 +4344,16 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -3905,6 +4492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", + "valuable", ] [[package]] @@ -3917,6 +4505,58 @@ dependencies = [ "tracing", ] +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-test" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3d272c44878d2bbc9f4a20ad463724f03e19dbc667c6e84ac433ab7ffcc70b" +dependencies = [ + "lazy_static", + "tracing-core", + "tracing-subscriber", + "tracing-test-macro", +] + +[[package]] +name = "tracing-test-macro" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744324b12d69a9fc1edea4b38b7b1311295b662d161ad5deac17bb1358224a08" +dependencies = [ + "lazy_static", + "quote", + "syn", +] + [[package]] name = "triehash" version = "0.8.4" @@ -3943,12 +4583,24 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "ttf-parser" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" + [[package]] name = "typenum" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +[[package]] +name = "ucd-trie" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" + [[package]] name = "uint" version = "0.8.5" @@ -4063,6 +4715,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" @@ -4230,6 +4888,12 @@ dependencies = [ "webpki", ] +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "which" version = "4.3.0" @@ -4381,6 +5045,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + [[package]] name = "ws_stream_wasm" version = "0.7.3" @@ -4391,7 +5064,7 @@ dependencies = [ "futures", "js-sys", "pharos", - "rustc_version", + "rustc_version 0.4.0", "send_wrapper 0.5.0", "thiserror", "wasm-bindgen", @@ -4414,6 +5087,18 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +[[package]] +name = "yeslogic-fontconfig-sys" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2bbd69036d397ebbff671b1b8e4d918610c181c5a16073b96f984a38d08c386" +dependencies = [ + "const-cstr", + "dlib", + "once_cell", + "pkg-config", +] + [[package]] name = "zeroize" version = "1.5.7" diff --git a/Cargo.toml b/Cargo.toml index e099335..3e617cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [package] name = "helios" -version = "0.1.1" +version = "0.1.2" edition = "2021" +autobenches = false [workspace] - members = [ "cli", "client", @@ -28,6 +28,15 @@ home = "0.5.4" ethers = "1.0.2" env_logger = "0.9.0" log = "0.4.17" +tracing-test = "0.2.3" +criterion = { version = "0.4", features = [ "async_tokio", "plotters" ]} +plotters = "0.3.3" +tempfile = "3.3.0" +hex = "0.4.3" + +###################################### +# Examples +###################################### [[example]] name = "checkpoints" @@ -45,3 +54,22 @@ path = "examples/client.rs" name = "config" path = "examples/config.rs" +###################################### +# Benchmarks +###################################### + +[[bench]] +name = "file_db" +harness = false + +[[bench]] +name = "get_balance" +harness = false + +[[bench]] +name = "get_code" +harness = false + +[[bench]] +name = "sync" +harness = false diff --git a/README.md b/README.md index 3d51dd1..633cef4 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Helios converts an untrusted centralized RPC endpoint into a safe unmanipulable The entire size of Helios's binary is 13Mb and should be easy to compile into WebAssembly. This makes it a perfect target to embed directly inside wallets and dapps. - ## Installing First install `heliosup`, Helios's installer: @@ -19,7 +18,6 @@ curl https://raw.githubusercontent.com/a16z/helios/master/heliosup/install | bas To install Helios, run `heliosup`. - ## Usage To run Helios, run the below command, replacing `$ETH_RPC_URL` with an RPC provider URL such as Alchemy or Infura: @@ -40,7 +38,6 @@ Helios also provides documentation of its supported RPC methods in the [rpc.md]( Helios is still experimental software. While we hope you try it out, we do not suggest adding it as your main RPC in wallets yet. Sending high-value transactions from a wallet connected to Helios is discouraged. - ### Additional Options `--consensus-rpc` or `-c` can be used to set a custom consensus layer rpc endpoint. This must be a consenus node that supports the light client beaconchain api. We recommend using Nimbus for this. If no consensus rpc is supplied, it defaults to `https://www.lightclientdata.org` which is run by us. @@ -68,7 +65,6 @@ This can be run like so: `helios --load-external-fallback` (or `helios -l` with `--help` or `-h` prints the help message. - ### Configuration Files All configuration options can be set on a per-network level in `~/.helios/helios.toml`. Here is an example config file: @@ -85,7 +81,6 @@ execution_rpc = "https://eth-goerli.g.alchemy.com/v2/XXXXX" checkpoint = "0xb5c375696913865d7c0e166d87bc7c772b6210dc9edf149f4c7ddc6da0dd4495" ``` - ### Using Helios as a Library Helios can be imported into any Rust project. Helios requires the Rust nightly toolchain to compile. @@ -148,16 +143,20 @@ async fn main() -> Result<()> { } ``` +## Benchmarks + +Benchmarks are defined in the [benches](./benches/) subdirectory. They are built using the [criterion](https://github.com/bheisler/criterion.rs) statistics-driven benchmarking library. + +To run all benchmarks, you can use `cargo bench`. To run a specific benchmark, you can use `cargo bench --bench `, where `` is one of the benchmarks defined in the [Cargo.toml](./Cargo.toml) file under a `[[bench]]` section. + ## Contributing All contributions to Helios are welcome. Before opening a PR, please submit an issue detailing the bug or feature. When opening a PR, please ensure that your contribution builds on the nightly rust toolchain, has been linted with `cargo fmt`, and contains tests when applicable. - ## Telegram If you are having trouble with Helios or are considering contributing, feel free to join our telegram [here](https://t.me/+IntDY_gZJSRkNTJj). - ## Disclaimer _This code is being provided as is. No guarantee, representation or warranty is being made, express or implied, as to the safety or correctness of the code. It has not been audited and as such there can be no assurance it will work as intended, and users may experience delays, failures, errors, omissions or loss of transmitted information. Nothing in this repo should be construed as investment advice or legal advice for any particular facts or circumstances and is not meant to replace competent counsel. It is strongly advised for you to contact a reputable attorney in your jurisdiction for any questions or concerns with respect thereto. a16z is not liable for any use of the foregoing, and users should proceed with caution and use at their own risk. See a16z.com/disclosures for more info._ diff --git a/benches/file_db.rs b/benches/file_db.rs new file mode 100644 index 0000000..6d0baec --- /dev/null +++ b/benches/file_db.rs @@ -0,0 +1,43 @@ +use client::database::Database; +use criterion::{criterion_group, criterion_main, Criterion}; +use helios::prelude::FileDB; +use tempfile::tempdir; + +mod harness; + +criterion_main!(file_db); +criterion_group! { + name = file_db; + config = Criterion::default(); + targets = save_checkpoint, load_checkpoint +} + +/// Benchmark saving/writing a checkpoint to the file db. +pub fn save_checkpoint(c: &mut Criterion) { + c.bench_function("save_checkpoint", |b| { + let checkpoint = vec![1, 2, 3]; + b.iter(|| { + let temp_dir = tempdir().unwrap().into_path(); + let db = FileDB::new(temp_dir); + db.save_checkpoint(checkpoint.clone()).unwrap(); + }) + }); +} + +/// Benchmark loading a checkpoint from the file db. +pub fn load_checkpoint(c: &mut Criterion) { + c.bench_function("load_checkpoint", |b| { + // First write to the db + let temp_dir = tempdir().unwrap().into_path(); + let db = FileDB::new(temp_dir.clone()); + let written_checkpoint = vec![1, 2, 3]; + db.save_checkpoint(written_checkpoint.clone()).unwrap(); + + // Then read from the db + b.iter(|| { + let db = FileDB::new(temp_dir.clone()); + let checkpoint = db.load_checkpoint().unwrap(); + assert_eq!(checkpoint, written_checkpoint.clone()); + }) + }); +} diff --git a/benches/get_balance.rs b/benches/get_balance.rs new file mode 100644 index 0000000..19cd314 --- /dev/null +++ b/benches/get_balance.rs @@ -0,0 +1,63 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use ethers::prelude::*; +use helios::types::BlockTag; +use std::str::FromStr; + +mod harness; + +criterion_main!(get_balance); +criterion_group! { + name = get_balance; + config = Criterion::default().sample_size(10); + targets = bench_mainnet_get_balance, bench_goerli_get_balance +} + +/// Benchmark mainnet get balance. +/// Address: 0x00000000219ab540356cbb839cbe05303d7705fa (beacon chain deposit address) +pub fn bench_mainnet_get_balance(c: &mut Criterion) { + c.bench_function("get_balance", |b| { + // Create a new multi-threaded tokio runtime. + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + + // Construct a mainnet client using our harness and tokio runtime. + let client = std::sync::Arc::new(harness::construct_mainnet_client(&rt).unwrap()); + + // Get the beacon chain deposit contract address. + let addr = Address::from_str("0x00000000219ab540356cbb839cbe05303d7705fa").unwrap(); + let block = BlockTag::Latest; + + // Execute the benchmark asynchronously. + b.to_async(rt).iter(|| async { + let inner = std::sync::Arc::clone(&client); + inner.get_balance(&addr, block).await.unwrap() + }) + }); +} + +/// Benchmark goerli get balance. +/// Address: 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6 (goerli weth) +pub fn bench_goerli_get_balance(c: &mut Criterion) { + c.bench_function("get_balance", |b| { + // Create a new multi-threaded tokio runtime. + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + + // Construct a goerli client using our harness and tokio runtime. + let client = std::sync::Arc::new(harness::construct_goerli_client(&rt).unwrap()); + + // Get the beacon chain deposit contract address. + let addr = Address::from_str("0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6").unwrap(); + let block = BlockTag::Latest; + + // Execute the benchmark asynchronously. + b.to_async(rt).iter(|| async { + let inner = std::sync::Arc::clone(&client); + inner.get_balance(&addr, block).await.unwrap() + }) + }); +} diff --git a/benches/get_code.rs b/benches/get_code.rs new file mode 100644 index 0000000..f8dd900 --- /dev/null +++ b/benches/get_code.rs @@ -0,0 +1,63 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use ethers::prelude::*; +use helios::types::BlockTag; +use std::str::FromStr; + +mod harness; + +criterion_main!(get_code); +criterion_group! { + name = get_code; + config = Criterion::default().sample_size(10); + targets = bench_mainnet_get_code, bench_goerli_get_code +} + +/// Benchmark mainnet get code call. +/// Address: 0x00000000219ab540356cbb839cbe05303d7705fa (beacon chain deposit address) +pub fn bench_mainnet_get_code(c: &mut Criterion) { + c.bench_function("get_code", |b| { + // Create a new multi-threaded tokio runtime. + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + + // Construct a mainnet client using our harness and tokio runtime. + let client = std::sync::Arc::new(harness::construct_mainnet_client(&rt).unwrap()); + + // Get the beacon chain deposit contract address. + let addr = Address::from_str("0x00000000219ab540356cbb839cbe05303d7705fa").unwrap(); + let block = BlockTag::Latest; + + // Execute the benchmark asynchronously. + b.to_async(rt).iter(|| async { + let inner = std::sync::Arc::clone(&client); + inner.get_code(&addr, block).await.unwrap() + }) + }); +} + +/// Benchmark goerli get code call. +/// Address: 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6 (goerli weth) +pub fn bench_goerli_get_code(c: &mut Criterion) { + c.bench_function("get_code", |b| { + // Create a new multi-threaded tokio runtime. + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + + // Construct a goerli client using our harness and tokio runtime. + let client = std::sync::Arc::new(harness::construct_goerli_client(&rt).unwrap()); + + // Get the beacon chain deposit contract address. + let addr = Address::from_str("0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6").unwrap(); + let block = BlockTag::Latest; + + // Execute the benchmark asynchronously. + b.to_async(rt).iter(|| async { + let inner = std::sync::Arc::clone(&client); + inner.get_code(&addr, block).await.unwrap() + }) + }); +} diff --git a/benches/harness.rs b/benches/harness.rs new file mode 100644 index 0000000..1f9b069 --- /dev/null +++ b/benches/harness.rs @@ -0,0 +1,113 @@ +#![allow(dead_code)] + +use std::{str::FromStr, sync::Arc}; + +use ::client::Client; +use ethers::{ + abi::Address, + types::{H256, U256}, +}; +use helios::{client, config::networks, prelude::FileDB, types::BlockTag}; + +/// Fetches the latest mainnet checkpoint from the fallback service. +/// +/// Uses the [CheckpointFallback](config::CheckpointFallback). +/// The `build` method will fetch a list of [CheckpointFallbackService](config::CheckpointFallbackService)s from a community-mainained list by ethPandaOps. +/// This list is NOT guaranteed to be secure, but is provided in good faith. +/// The raw list can be found here: https://github.com/ethpandaops/checkpoint-sync-health-checks/blob/master/_data/endpoints.yaml +pub async fn fetch_mainnet_checkpoint() -> eyre::Result { + let cf = config::CheckpointFallback::new().build().await.unwrap(); + cf.fetch_latest_checkpoint(&networks::Network::MAINNET) + .await +} + +/// Constructs a mainnet [Client](client::Client) for benchmark usage. +/// +/// Requires a [Runtime](tokio::runtime::Runtime) to be passed in by reference. +/// The client is parameterized with a [FileDB](client::FileDB). +/// It will also use the environment variable `MAINNET_RPC_URL` to connect to a mainnet node. +/// The client will use `https://www.lightclientdata.org` as the consensus RPC. +pub fn construct_mainnet_client( + rt: &tokio::runtime::Runtime, +) -> eyre::Result> { + rt.block_on(inner_construct_mainnet_client()) +} + +pub async fn inner_construct_mainnet_client() -> eyre::Result> { + let benchmark_rpc_url = std::env::var("MAINNET_RPC_URL")?; + let mut client = client::ClientBuilder::new() + .network(networks::Network::MAINNET) + .consensus_rpc("https://www.lightclientdata.org") + .execution_rpc(&benchmark_rpc_url) + .load_external_fallback() + .build()?; + client.start().await?; + Ok(client) +} + +pub async fn construct_mainnet_client_with_checkpoint( + checkpoint: &str, +) -> eyre::Result> { + let benchmark_rpc_url = std::env::var("MAINNET_RPC_URL")?; + let mut client = client::ClientBuilder::new() + .network(networks::Network::MAINNET) + .consensus_rpc("https://www.lightclientdata.org") + .execution_rpc(&benchmark_rpc_url) + .checkpoint(checkpoint) + .build()?; + client.start().await?; + Ok(client) +} + +/// Create a tokio multi-threaded runtime. +/// +/// # Panics +/// +/// Panics if the runtime cannot be created. +pub fn construct_runtime() -> tokio::runtime::Runtime { + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() +} + +/// Constructs a goerli client for benchmark usage. +/// +/// Requires a [Runtime](tokio::runtime::Runtime) to be passed in by reference. +/// The client is parameterized with a [FileDB](client::FileDB). +/// It will also use the environment variable `GOERLI_RPC_URL` to connect to a mainnet node. +/// The client will use `http://testing.prater.beacon-api.nimbus.team` as the consensus RPC. +pub fn construct_goerli_client( + rt: &tokio::runtime::Runtime, +) -> eyre::Result> { + rt.block_on(async { + let benchmark_rpc_url = std::env::var("GOERLI_RPC_URL")?; + let mut client = client::ClientBuilder::new() + .network(networks::Network::GOERLI) + .consensus_rpc("http://testing.prater.beacon-api.nimbus.team") + .execution_rpc(&benchmark_rpc_url) + .load_external_fallback() + .build()?; + client.start().await?; + Ok(client) + }) +} + +/// Gets the balance of the given address on mainnet. +pub fn get_balance( + rt: &tokio::runtime::Runtime, + client: Arc>, + address: &str, +) -> eyre::Result { + rt.block_on(async { + let block = BlockTag::Latest; + let address = Address::from_str(address)?; + client.get_balance(&address, block).await + }) +} + +// h/t @ https://github.com/smrpn +// rev: https://github.com/smrpn/casbin-rs/commit/7a0a75d8075440ee65acdac3ee9c0de6fcbd5c48 +pub fn await_future, T>(future: F) -> T { + tokio::runtime::Runtime::new().unwrap().block_on(future) +} diff --git a/benches/sync.rs b/benches/sync.rs new file mode 100644 index 0000000..dffe950 --- /dev/null +++ b/benches/sync.rs @@ -0,0 +1,81 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use ethers::types::Address; +use helios::types::BlockTag; + +mod harness; + +criterion_main!(sync); +criterion_group! { + name = sync; + config = Criterion::default().sample_size(10); + targets = + bench_full_sync, + bench_full_sync_with_call, + bench_full_sync_checkpoint_fallback, + bench_full_sync_with_call_checkpoint_fallback, +} + +/// Benchmark full client sync. +pub fn bench_full_sync(c: &mut Criterion) { + // Externally, let's fetch the latest checkpoint from our fallback service so as not to benchmark the checkpoint fetch. + let checkpoint = harness::await_future(harness::fetch_mainnet_checkpoint()).unwrap(); + let checkpoint = hex::encode(checkpoint); + + // On client construction, it will sync to the latest checkpoint using our fetched checkpoint. + c.bench_function("full_sync", |b| { + b.to_async(harness::construct_runtime()).iter(|| async { + let _client = std::sync::Arc::new( + harness::construct_mainnet_client_with_checkpoint(&checkpoint) + .await + .unwrap(), + ); + }) + }); +} + +/// Benchmark full client sync. +/// Address: 0x00000000219ab540356cbb839cbe05303d7705fa (beacon chain deposit address) +pub fn bench_full_sync_with_call(c: &mut Criterion) { + // Externally, let's fetch the latest checkpoint from our fallback service so as not to benchmark the checkpoint fetch. + let checkpoint = harness::await_future(harness::fetch_mainnet_checkpoint()).unwrap(); + let checkpoint = hex::encode(checkpoint); + + // On client construction, it will sync to the latest checkpoint using our fetched checkpoint. + c.bench_function("full_sync_call", |b| { + b.to_async(harness::construct_runtime()).iter(|| async { + let client = std::sync::Arc::new( + harness::construct_mainnet_client_with_checkpoint(&checkpoint) + .await + .unwrap(), + ); + let addr = "0x00000000219ab540356cbb839cbe05303d7705fa" + .parse::
() + .unwrap(); + let block = BlockTag::Latest; + client.get_balance(&addr, block).await.unwrap() + }) + }); +} + +/// Benchmark full client sync with checkpoint fallback. +pub fn bench_full_sync_checkpoint_fallback(c: &mut Criterion) { + c.bench_function("full_sync_fallback", |b| { + let rt = harness::construct_runtime(); + b.iter(|| { + let _client = std::sync::Arc::new(harness::construct_mainnet_client(&rt).unwrap()); + }) + }); +} + +/// Benchmark full client sync with a call and checkpoint fallback. +/// Address: 0x00000000219ab540356cbb839cbe05303d7705fa (beacon chain deposit address) +pub fn bench_full_sync_with_call_checkpoint_fallback(c: &mut Criterion) { + c.bench_function("full_sync_call", |b| { + let addr = "0x00000000219ab540356cbb839cbe05303d7705fa"; + let rt = harness::construct_runtime(); + b.iter(|| { + let client = std::sync::Arc::new(harness::construct_mainnet_client(&rt).unwrap()); + harness::get_balance(&rt, client, addr).unwrap(); + }) + }); +} diff --git a/client/src/database.rs b/client/src/database.rs index 48373b2..3736f93 100644 --- a/client/src/database.rs +++ b/client/src/database.rs @@ -1,9 +1,14 @@ -use std::{fs, io::Write, path::PathBuf}; +use std::{ + fs, + io::{Read, Write}, + path::PathBuf, +}; use eyre::Result; pub trait Database { fn save_checkpoint(&self, checkpoint: Vec) -> Result<()>; + fn load_checkpoint(&self) -> Result>; } pub struct FileDB { @@ -30,4 +35,15 @@ impl Database for FileDB { Ok(()) } + + fn load_checkpoint(&self) -> Result> { + let mut f = fs::OpenOptions::new() + .read(true) + .open(self.data_dir.join("checkpoint"))?; + + let mut buf = Vec::new(); + f.read_to_end(&mut buf)?; + + Ok(buf) + } } diff --git a/config/src/checkpoints.rs b/config/src/checkpoints.rs index 827cac6..65fe45a 100644 --- a/config/src/checkpoints.rs +++ b/config/src/checkpoints.rs @@ -117,10 +117,18 @@ impl CheckpointFallback { &self, network: &crate::networks::Network, ) -> eyre::Result { - let services = &self.services[network]; + let services = &self.get_healthy_fallback_services(network); Self::fetch_latest_checkpoint_from_services(&services[..]).await } + async fn query_service(endpoint: &str) -> Option { + let client = reqwest::Client::new(); + let constructed_url = Self::construct_url(endpoint); + let res = client.get(&constructed_url).send().await.ok()?; + let raw: RawSlotResponse = res.json().await.ok()?; + Some(raw) + } + /// Fetch the latest checkpoint from a list of checkpoint fallback services. pub async fn fetch_latest_checkpoint_from_services( services: &[CheckpointFallbackService], @@ -131,14 +139,15 @@ impl CheckpointFallback { .map(|service| { let service = service.clone(); tokio::spawn(async move { - let client = reqwest::Client::new(); - let constructed_url = Self::construct_url(&service.endpoint); - let res = client.get(&constructed_url).send().await?; - let raw: RawSlotResponse = res.json().await?; - if raw.data.slots.is_empty() { - return Err(eyre::eyre!("no slots")); + match Self::query_service(&service.endpoint).await { + Some(raw) => { + if raw.data.slots.is_empty() { + return Err(eyre::eyre!("no slots")); + } + Ok(raw.data.slots[0].clone()) + } + None => Err(eyre::eyre!("failed to query service")), } - Ok(raw.data.slots[0].clone()) }) }) .collect(); @@ -230,6 +239,22 @@ impl CheckpointFallback { .collect() } + /// Returns a list of healthchecked checkpoint fallback services. + /// + /// ### Warning + /// + /// These services are not trustworthy and may act with malice by returning invalid checkpoints. + pub fn get_healthy_fallback_services( + &self, + network: &networks::Network, + ) -> Vec { + self.services[network] + .iter() + .filter(|service| service.state) + .cloned() + .collect::>() + } + /// Returns the raw checkpoint fallback service objects for a given network. pub fn get_fallback_services( &self, From c26e393b7d086bd6977939dabc4ab544b5c40925 Mon Sep 17 00:00:00 2001 From: Giovanni Vignone <72773059+giovannivignone@users.noreply.github.com> Date: Tue, 13 Dec 2022 19:19:36 -0500 Subject: [PATCH 05/44] feat: add tx length rpc methods (#142) * adding documentation for rpc.md * adding rpc methods in table for rpc.md * adjusting readme to link to rpc.md * fixing grammar * grammar * adding RPC Methods according to documentation and listing column as Client Function * adding more description space * undoing description spacing * adding get block transaction count by hash to node.rs and rpc.rs * functioning getblocktransactioncountbyhash function * removing documentation * adding second rpc method and simplifying logic * adjusting example and node.rs * formatting * fixing clippy errors * adding to client and to rpc.md * formatting * integrating into client * u64 return types, rpc.md updated to get_nonce, get_transaction_count -> get_nonce revert * cargo fmt --- client/src/client.rs | 14 ++++++++++++++ client/src/node.rs | 43 +++++++++++++++++++++++++++++++------------ client/src/rpc.rs | 22 ++++++++++++++++++++++ examples/readme.rs | 2 +- rpc.md | 6 ++++-- 5 files changed, 72 insertions(+), 15 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 353cc1c..6068987 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -340,6 +340,20 @@ impl Client { self.node.read().await.get_nonce(address, block).await } + pub async fn get_block_transaction_count_by_hash(&self, hash: &Vec) -> Result { + self.node + .read() + .await + .get_block_transaction_count_by_hash(hash) + } + + pub async fn get_block_transaction_count_by_number(&self, block: BlockTag) -> Result { + self.node + .read() + .await + .get_block_transaction_count_by_number(block) + } + pub async fn get_code(&self, address: &Address, block: BlockTag) -> Result> { self.node.read().await.get_code(address, block).await } diff --git a/client/src/node.rs b/client/src/node.rs index 02d02af..7db7416 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -155,6 +155,20 @@ impl Node { Ok(account.nonce) } + pub fn get_block_transaction_count_by_hash(&self, hash: &Vec) -> Result { + let payload = self.get_payload_by_hash(hash)?; + let transaction_count = payload.1.transactions.len(); + + Ok(transaction_count as u64) + } + + pub fn get_block_transaction_count_by_number(&self, block: BlockTag) -> Result { + let payload = self.get_payload(block)?; + let transaction_count = payload.transactions.len(); + + Ok(transaction_count as u64) + } + pub async fn get_code(&self, address: &Address, block: BlockTag) -> Result> { self.check_blocktag_age(&block)?; @@ -248,19 +262,11 @@ impl Node { hash: &Vec, full_tx: bool, ) -> Result> { - let payloads = self - .payloads - .iter() - .filter(|entry| &entry.1.block_hash.to_vec() == hash) - .collect::>(); + let payload = self.get_payload_by_hash(hash); - if let Some(payload_entry) = payloads.get(0) { - self.execution - .get_block(payload_entry.1, full_tx) - .await - .map(Some) - } else { - Ok(None) + match payload { + Ok(payload) => self.execution.get_block(payload.1, full_tx).await.map(Some), + Err(_) => Ok(None), } } @@ -296,6 +302,19 @@ impl Node { } } + fn get_payload_by_hash(&self, hash: &Vec) -> Result<(&u64, &ExecutionPayload)> { + let payloads = self + .payloads + .iter() + .filter(|entry| &entry.1.block_hash.to_vec() == hash) + .collect::>(); + + payloads + .get(0) + .cloned() + .ok_or(eyre!("Block not found by hash")) + } + fn check_head_age(&self) -> Result<(), NodeError> { let synced_slot = self.consensus.get_header().slot; let expected_slot = self.consensus.expected_current_slot(); diff --git a/client/src/rpc.rs b/client/src/rpc.rs index 3f72c7b..34e9295 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -57,6 +57,11 @@ trait EthRpc { async fn get_balance(&self, address: &str, block: BlockTag) -> Result; #[method(name = "getTransactionCount")] async fn get_transaction_count(&self, address: &str, block: BlockTag) -> Result; + #[method(name = "getBlockTransactionCountByHash")] + async fn get_block_transaction_count_by_hash(&self, hash: &str) -> Result; + #[method(name = "getBlockTransactionCountByNumber")] + async fn get_block_transaction_count_by_number(&self, block: BlockTag) + -> Result; #[method(name = "getCode")] async fn get_code(&self, address: &str, block: BlockTag) -> Result; #[method(name = "call")] @@ -133,6 +138,23 @@ impl EthRpcServer for RpcInner { Ok(format!("0x{nonce:x}")) } + async fn get_block_transaction_count_by_hash(&self, hash: &str) -> Result { + let hash = convert_err(hex_str_to_bytes(hash))?; + let node = self.node.read().await; + let transaction_count = convert_err(node.get_block_transaction_count_by_hash(&hash))?; + + Ok(u64_to_hex_string(transaction_count)) + } + + async fn get_block_transaction_count_by_number( + &self, + block: BlockTag, + ) -> Result { + let node = self.node.read().await; + let transaction_count = convert_err(node.get_block_transaction_count_by_number(block))?; + Ok(u64_to_hex_string(transaction_count)) + } + async fn get_code(&self, address: &str, block: BlockTag) -> Result { let address = convert_err(Address::from_str(address))?; let node = self.node.read().await; diff --git a/examples/readme.rs b/examples/readme.rs index 24e4ddc..1c4d5ce 100644 --- a/examples/readme.rs +++ b/examples/readme.rs @@ -9,7 +9,7 @@ use helios::{client::ClientBuilder, config::networks::Network, types::BlockTag}; async fn main() -> Result<()> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); - let untrusted_rpc_url = "https://mainnet.infura.io/v3/"; + let untrusted_rpc_url = "https://eth-mainnet.g.alchemy.com/v2/"; log::info!("Using untrusted RPC URL [REDACTED]"); let consensus_rpc = "https://www.lightclientdata.org"; diff --git a/rpc.md b/rpc.md index 987a21e..07c5097 100644 --- a/rpc.md +++ b/rpc.md @@ -7,7 +7,7 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo | RPC Method | Client Function | Description | Example | | ---------- | --------------- | ----------- | ------- | | `eth_getBalance` | `get_balance` | Returns the balance of the account given an address. | `client.get_balance(&self, address: &str, block: BlockTag)` | -| `eth_getTransactionCount` | `get_transaction_count` | Returns the number of transactions sent from the given address. | `client.get_transaction_count(&self, address: &str, block: BlockTag)` | +| `eth_getTransactionCount` | `get_nonce` | Returns the number of transactions sent from the given address. | `client.get_nonce(&self, address: &str, block: BlockTag)` | | `eth_getCode` | `get_code` | Returns the code at a given address. | `client.get_code(&self, address: &str, block: BlockTag)` | | `eth_call` | `call` | Executes a new message call immediately without creating a transaction on the blockchain. | `client.call(&self, opts: CallOpts, block: BlockTag)` | | `eth_estimateGas` | `estimate_gas` | Generates and returns an estimate of how much gas is necessary to allow the transaction to complete. | `client.estimate_gas(&self, opts: CallOpts)` | @@ -20,4 +20,6 @@ Helios provides a variety of RPC methods for interacting with the Ethereum netwo | `eth_sendRawTransaction` | `send_raw_transaction` | Submits a raw transaction to the network. | `client.send_raw_transaction(&self, bytes: &str)` | | `eth_getTransactionReceipt` | `get_transaction_receipt` | Returns the receipt of a transaction by transaction hash. | `client.get_transaction_receipt(&self, hash: &str)` | | `eth_getLogs` | `get_logs` | Returns an array of logs matching the filter. | `client.get_logs(&self, filter: Filter)` | -| `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` | \ No newline at end of file +| `eth_getStorageAt` | `get_storage_at` | Returns the value from a storage position at a given address. | `client.get_storage_at(&self, address: &str, slot: H256, block: BlockTag)` | +| `eth_getBlockTransactionCountByHash` | `get_block_transaction_count_by_hash` | Returns the number of transactions in a block from a block matching the transaction hash. | `client.get_block_transaction_count_by_hash(&self, hash: &str)` | +| `eth_getBlockTransactionCountByNumber` | `get_block_transaction_count_by_number` | Returns the number of transactions in a block from a block matching the block number. | `client.get_block_transaction_count_by_number(&self, block: BlockTag)` | \ No newline at end of file From 56f9d89525692f686495a5728a133cce0390972a Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Tue, 13 Dec 2022 20:22:53 -0500 Subject: [PATCH 06/44] fix(ci): move benchmark ci to separate action (#143) --- .github/workflows/benchmarks.yml | 25 +++++++++++++++++++++++++ .github/workflows/test.yml | 19 ------------------- 2 files changed, 25 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/benchmarks.yml diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml new file mode 100644 index 0000000..4507a62 --- /dev/null +++ b/.github/workflows/benchmarks.yml @@ -0,0 +1,25 @@ +name: benchmarks + +on: + push: + branches: [ "master" ] + +env: + MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }} + GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }} + +jobs: + benches: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: nightly + override: true + components: rustfmt + - uses: Swatinem/rust-cache@v2 + - uses: actions-rs/cargo@v1 + with: + command: bench diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1066a60..9f0a89c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,10 +6,6 @@ on: pull_request: branches: [ "master" ] -env: - MAINNET_RPC_URL: ${{ secrets.MAINNET_RPC_URL }} - GOERLI_RPC_URL: ${{ secrets.GOERLI_RPC_URL }} - jobs: check: runs-on: ubuntu-latest @@ -56,21 +52,6 @@ jobs: command: fmt args: --all -- --check - benches: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: nightly - override: true - components: rustfmt - - uses: Swatinem/rust-cache@v2 - - uses: actions-rs/cargo@v1 - with: - command: bench - clippy: runs-on: ubuntu-latest steps: From 4707a0a9d4b2c8f6714d1a5ac7f000f8fcf8e8df Mon Sep 17 00:00:00 2001 From: "refcell.eth" Date: Tue, 13 Dec 2022 22:10:24 -0700 Subject: [PATCH 07/44] feat(docs): Config (#140) * :memo: comprehensive config options * :hammer: remove forks and chain parameters --- README.md | 3 +++ config.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 config.md diff --git a/README.md b/README.md index 633cef4..44bbe6a 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,9 @@ execution_rpc = "https://eth-goerli.g.alchemy.com/v2/XXXXX" checkpoint = "0xb5c375696913865d7c0e166d87bc7c772b6210dc9edf149f4c7ddc6da0dd4495" ``` +A comprehensive breakdown of config options is available in the [config.md](./config.md) file. + + ### Using Helios as a Library Helios can be imported into any Rust project. Helios requires the Rust nightly toolchain to compile. diff --git a/config.md b/config.md new file mode 100644 index 0000000..33f6ba4 --- /dev/null +++ b/config.md @@ -0,0 +1,74 @@ +## Helios Configuration + +All configuration options can be set on a per-network level in `~/.helios/helios.toml`. + +#### Comprehensive Example + +```toml +[mainnet] +# The consensus rpc to use. This should be a trusted rpc endpoint. Defaults to "https://www.lightclientdata.org". +consensus_rpc = "https://www.lightclientdata.org" +# [REQUIRED] The execution rpc to use. This should be a trusted rpc endpoint. +execution_rpc = "https://eth-mainnet.g.alchemy.com/v2/XXXXX" +# The port to run the JSON-RPC server on. By default, Helios will use port 8545. +rpc_port = 8545 +# The latest checkpoint. This should be a trusted checkpoint that is no greater than ~2 weeks old. +# If you are unsure what checkpoint to use, you can skip this option and set either `load_external_fallback` or `fallback` values (described below) to fetch a checkpoint. Though this is not recommended and less secure. +checkpoint = "0x85e6151a246e8fdba36db27a0c7678a575346272fe978c9281e13a8b26cdfa68" +# The directory to store the checkpoint database in. If not provided, Helios will use "~/.helios/data/mainnet", where `mainnet` is the network. +# It is recommended to set this directory to a persistent location mapped to a fast storage device. +data_dir = "/home/user/.helios/mainnet" +# The maximum age of a checkpoint in seconds. If the checkpoint is older than this, Helios will attempt to fetch a new checkpoint. +max_checkpoint_age = 86400 +# A checkpoint fallback is used if no checkpoint is provided or the given checkpoint is too old. +# This is expected to be a trusted checkpoint sync api (like provided in https://github.com/ethpandaops/checkpoint-sync-health-checks/blob/master/_data/endpoints.yaml). +fallback = "https://sync-mainnet.beaconcha.in" +# If no checkpoint is provided, or the checkpoint is too old, Helios will attempt to dynamically fetch a checkpoint from a maintained list of checkpoint sync apis. +# NOTE: This is an insecure feature and not recommended for production use. Checkpoint manipulation is possible. +load_external_fallback = true + +[goerli] +# The consensus rpc to use. This should be a trusted rpc endpoint. Defaults to Nimbus testnet. +consensus_rpc = "http://testing.prater.beacon-api.nimbus.team" +# [REQUIRED] The execution rpc to use. This should be a trusted rpc endpoint. +execution_rpc = "https://eth-goerli.g.alchemy.com/v2/XXXXX" +# The port to run the JSON-RPC server on. By default, Helios will use port 8545. +rpc_port = 8545 +# The latest checkpoint. This should be a trusted checkpoint that is no greater than ~2 weeks old. +# If you are unsure what checkpoint to use, you can skip this option and set either `load_external_fallback` or `fallback` values (described below) to fetch a checkpoint. Though this is not recommended and less secure. +checkpoint = "0xb5c375696913865d7c0e166d87bc7c772b6210dc9edf149f4c7ddc6da0dd4495" +# The directory to store the checkpoint database in. If not provided, Helios will use "~/.helios/data/goerli", where `goerli` is the network. +# It is recommended to set this directory to a persistent location mapped to a fast storage device. +data_dir = "/home/user/.helios/goerli" +# The maximum age of a checkpoint in seconds. If the checkpoint is older than this, Helios will attempt to fetch a new checkpoint. +max_checkpoint_age = 86400 +# A checkpoint fallback is used if no checkpoint is provided or the given checkpoint is too old. +# This is expected to be a trusted checkpoint sync api (like provided in https://github.com/ethpandaops/checkpoint-sync-health-checks/blob/master/_data/endpoints.yaml). +fallback = "https://sync-goerli.beaconcha.in" +# If no checkpoint is provided, or the checkpoint is too old, Helios will attempt to dynamically fetch a checkpoint from a maintained list of checkpoint sync apis. +# NOTE: This is an insecure feature and not recommended for production use. Checkpoint manipulation is possible. +load_external_fallback = true +``` + + +#### Options + +All configuration options below are available on a per-network level, where network is specified by a header (eg `[mainnet]` or `[goerli]`). Many of these options can be configured through cli flags as well. See [README.md](./README.md#additional-options) or run `helios --help` for more information. + + +- `consensus_rpc` - The URL of the consensus RPC endpoint used to fetch the latest beacon chain head and sync status. This must be a consenus node that supports the light client beaconchain api. We recommend using Nimbus for this. If no consensus rpc is supplied, it defaults to `https://www.lightclientdata.org` which is run by us. + +- `execution_rpc` - The URL of the execution RPC endpoint used to fetch the latest execution chain head and sync status. This must be an execution node that supports the light client execution api. We recommend using Geth for this. + +- `rpc_port` - The port to run the JSON-RPC server on. By default, Helios will use port 8545. + +- `checkpoint` - The latest checkpoint. This should be a trusted checkpoint that is no greater than ~2 weeks old. If you are unsure what checkpoint to use, you can skip this option and set either `load_external_fallback` or `fallback` values (described below) to fetch a checkpoint. Though this is not recommended and less secure. + +- `data_dir` - The directory to store the checkpoint database in. If not provided, Helios will use "~/.helios/data/", where `` is the network. It is recommended to set this directory to a persistent location mapped to a fast storage device. + +- `max_checkpoint_age` - The maximum age of a checkpoint in seconds. If the checkpoint is older than this, Helios will attempt to fetch a new checkpoint. + +- `fallback` - A checkpoint fallback is used if no checkpoint is provided or the given checkpoint is too old. This is expected to be a trusted checkpoint sync api (eg https://sync-mainnet.beaconcha.in). An extensive list of checkpoint sync apis can be found here: https://github.com/ethpandaops/checkpoint-sync-health-checks/blob/master/_data/endpoints.yaml. + +- `load_external_fallback` - If no checkpoint is provided, or the checkpoint is too old, Helios will attempt to dynamically fetch a checkpoint from a maintained list of checkpoint sync apis. NOTE: This is an insecure feature and not recommended for production use. Checkpoint manipulation is possible. + From 9f53fc9bfcda22eab7953c75c680b62e584eff88 Mon Sep 17 00:00:00 2001 From: Mathieu <60658558+msaug@users.noreply.github.com> Date: Wed, 14 Dec 2022 17:43:43 +0100 Subject: [PATCH 08/44] chore: export ExecutionBlock type (#146) * export ExecutionBlock type * fix linting error * Format with cargo fmt --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 914e9f6..b54ebc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ pub mod config { pub mod types { pub use common::types::BlockTag; - pub use execution::types::CallOpts; + pub use execution::types::{CallOpts, ExecutionBlock}; } pub mod errors { From af2a12dd577bc028456692427041fcc470e48a12 Mon Sep 17 00:00:00 2001 From: Mathieu <60658558+msaug@users.noreply.github.com> Date: Wed, 14 Dec 2022 20:37:15 +0100 Subject: [PATCH 09/44] chore: export src/execution types (#148) --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index b54ebc5..08f7356 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,7 +60,7 @@ pub mod config { pub mod types { pub use common::types::BlockTag; - pub use execution::types::{CallOpts, ExecutionBlock}; + pub use execution::types::{Account, CallOpts, ExecutionBlock, Transactions}; } pub mod errors { From aa838aeee199cc4d425e6dfc998fd97428e44779 Mon Sep 17 00:00:00 2001 From: danilowhk Date: Wed, 14 Dec 2022 18:38:19 -0300 Subject: [PATCH 10/44] chore: add checkpoints in export config mod (#149) * add checkpoints in export config mod * add checkpoints --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 08f7356..f72ef4b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,7 +55,7 @@ pub mod client { } pub mod config { - pub use config::{networks, Config}; + pub use config::{checkpoints, networks, Config}; } pub mod types { From bfe44809d87069aa9710bba7e29ef2572f56fa5b Mon Sep 17 00:00:00 2001 From: Mathieu <60658558+msaug@users.noreply.github.com> Date: Sun, 18 Dec 2022 16:27:57 +0100 Subject: [PATCH 11/44] chore: make execution types clonable (#156) --- execution/src/types.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/execution/src/types.rs b/execution/src/types.rs index 49c3cf7..16b7c63 100644 --- a/execution/src/types.rs +++ b/execution/src/types.rs @@ -19,7 +19,7 @@ pub struct Account { pub slots: HashMap, } -#[derive(Deserialize, Serialize, Debug)] +#[derive(Deserialize, Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct ExecutionBlock { #[serde(serialize_with = "serialize_u64_string")] @@ -54,13 +54,13 @@ pub struct ExecutionBlock { pub uncles: Vec, } -#[derive(Deserialize, Serialize, Debug)] +#[derive(Deserialize, Serialize, Debug, Clone)] pub enum Transactions { Hashes(Vec), Full(Vec), } -#[derive(Deserialize, Serialize)] +#[derive(Deserialize, Serialize, Clone)] #[serde(rename_all = "camelCase")] pub struct CallOpts { pub from: Option
, From f8275f054ecc9e0d3e02c82ca337e6ce0978285d Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 21 Dec 2022 19:11:43 -0500 Subject: [PATCH 12/44] fix: handle calls to eoa (#159) --- execution/src/evm.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/execution/src/evm.rs b/execution/src/evm.rs index 9113042..30ae16c 100644 --- a/execution/src/evm.rs +++ b/execution/src/evm.rs @@ -60,7 +60,7 @@ impl<'a, R: ExecutionRpc> Evm<'a, R> { TransactOut::Call(bytes) => Err(EvmError::Revert(Some(bytes))), _ => Err(EvmError::Revert(None)), }, - revm::Return::Return => { + revm::Return::Return | revm::Return::Stop => { if let Some(err) = &self.evm.db.as_ref().unwrap().error { return Err(EvmError::Generic(err.clone())); } @@ -88,7 +88,7 @@ impl<'a, R: ExecutionRpc> Evm<'a, R> { TransactOut::Call(bytes) => Err(EvmError::Revert(Some(bytes))), _ => Err(EvmError::Revert(None)), }, - revm::Return::Return => { + revm::Return::Return | revm::Return::Stop => { if let Some(err) = &self.evm.db.as_ref().unwrap().error { return Err(EvmError::Generic(err.clone())); } From ac8a145ae33e72b62e017749fd0d3e1887d3999e Mon Sep 17 00:00:00 2001 From: ControlCplusControlV <44706811+ControlCplusControlV@users.noreply.github.com> Date: Fri, 23 Dec 2022 19:14:21 -0700 Subject: [PATCH 13/44] feat: reduce binary size (#160) * reduced bin size * Update README.md --- Cargo.toml | 7 +++++++ README.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3e617cf..8601e3d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,13 @@ plotters = "0.3.3" tempfile = "3.3.0" hex = "0.4.3" +[profile.release] +strip = true +opt-level = "z" +lto = true +codegen-units = 1 +panic = "abort" + ###################################### # Examples ###################################### diff --git a/README.md b/README.md index 44bbe6a..724f833 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Helios is a fully trustless, efficient, and portable Ethereum light client writt Helios converts an untrusted centralized RPC endpoint into a safe unmanipulable local RPC for its users. It syncs in seconds, requires no storage, and is lightweight enough to run on mobile devices. -The entire size of Helios's binary is 13Mb and should be easy to compile into WebAssembly. This makes it a perfect target to embed directly inside wallets and dapps. +The entire size of Helios's binary is 5.3Mb and should be easy to compile into WebAssembly. This makes it a perfect target to embed directly inside wallets and dapps. ## Installing From ec4beb38e9f4d0d64411a4ab271da7d8dd698361 Mon Sep 17 00:00:00 2001 From: Giovanni Vignone <72773059+giovannivignone@users.noreply.github.com> Date: Fri, 30 Dec 2022 13:28:46 -0800 Subject: [PATCH 14/44] docs: architectural Diagram (#161) * adding documentation for rpc.md * adding rpc methods in table for rpc.md * adjusting readme to link to rpc.md * fixing grammar * grammar * adding RPC Methods according to documentation and listing column as Client Function * adding more description space * undoing description spacing * adding get block transaction count by hash to node.rs and rpc.rs * functioning getblocktransactioncountbyhash function * removing documentation * adding second rpc method and simplifying logic * adjusting example and node.rs * formatting * fixing clippy errors * adding to client and to rpc.md * formatting * integrating into client * u64 return types, rpc.md updated to get_nonce, get_transaction_count -> get_nonce revert * cargo fmt * readme architecture init * removing blockchain * removing complexity * updating mermaid with links from evm -> execution, renaming, and recoloring * coloring letters black * removing uncessary styling and adding untrustedexecutionrpc and untrustedconsensusrpc --- README.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/README.md b/README.md index 724f833..f3f0fbd 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,43 @@ async fn main() -> Result<()> { } ``` +## Architecture +```mermaid +graph LR + +Client ----> Rpc +Client ----> Node +Node ----> ConsensusClient +Node ----> ExecutionClient +ExecutionClient ----> ExecutionRpc +ConsensusClient ----> ConsensusRpc +Node ----> Evm +Evm ----> ExecutionClient +ExecutionRpc --> UntrustedExecutionRpc +ConsensusRpc --> UntrustedConsensusRpc + +classDef node fill:#f9f,stroke:#333,stroke-width:4px, color:black; +class Node,Client node +classDef execution fill:#f0f,stroke:#333,stroke-width:4px; +class ExecutionClient,ExecutionRpc execution +classDef consensus fill:#ff0,stroke:#333,stroke-width:4px; +class ConsensusClient,ConsensusRpc consensus +classDef evm fill:#0ff,stroke:#333,stroke-width:4px; +class Evm evm +classDef providerC fill:#ffc +class UntrustedConsensusRpc providerC +classDef providerE fill:#fbf +class UntrustedExecutionRpc providerE +classDef rpc fill:#e10 +class Rpc rpc + + +subgraph "External Network" +UntrustedExecutionRpc +UntrustedConsensusRpc +end +``` + ## Benchmarks Benchmarks are defined in the [benches](./benches/) subdirectory. They are built using the [criterion](https://github.com/bheisler/criterion.rs) statistics-driven benchmarking library. From 9d69c2b2b41c53612fb233f3a936c843e6295702 Mon Sep 17 00:00:00 2001 From: danilowhk Date: Tue, 3 Jan 2023 11:45:56 -0300 Subject: [PATCH 15/44] feat : add eth_getTransactionByBlockHashAndIndex (#157) * eth_getTransactionByBlockHashAndIndex * format * clippy changes * test check --- client/src/client.rs | 12 ++++++++++++ client/src/node.rs | 12 ++++++++++++ client/src/rpc.rs | 18 ++++++++++++++++++ execution/src/execution.rs | 16 +++++++++++++++- execution/tests/execution.rs | 20 ++++++++++++++++++++ 5 files changed, 77 insertions(+), 1 deletion(-) diff --git a/client/src/client.rs b/client/src/client.rs index 6068987..b05d6d1 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -434,6 +434,18 @@ impl Client { .await } + pub async fn get_transaction_by_block_hash_and_index( + &self, + block_hash: &Vec, + index: usize, + ) -> Result> { + self.node + .read() + .await + .get_transaction_by_block_hash_and_index(block_hash, index) + .await + } + pub async fn chain_id(&self) -> u64 { self.node.read().await.chain_id() } diff --git a/client/src/node.rs b/client/src/node.rs index 7db7416..a78c7d4 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -217,6 +217,18 @@ impl Node { .await } + pub async fn get_transaction_by_block_hash_and_index( + &self, + hash: &Vec, + index: usize, + ) -> Result> { + let payload = self.get_payload_by_hash(hash)?; + + self.execution + .get_transaction_by_block_hash_and_index(payload.1, index) + .await + } + pub async fn get_logs(&self, filter: &Filter) -> Result> { self.execution.get_logs(filter, &self.payloads).await } diff --git a/client/src/rpc.rs b/client/src/rpc.rs index 34e9295..43b867d 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -97,6 +97,12 @@ trait EthRpc { ) -> Result, Error>; #[method(name = "getTransactionByHash")] async fn get_transaction_by_hash(&self, hash: &str) -> Result, Error>; + #[method(name = "getTransactionByBlockHashAndIndex")] + async fn get_transaction_by_block_hash_and_index( + &self, + hash: &str, + index: usize, + ) -> Result, Error>; #[method(name = "getLogs")] async fn get_logs(&self, filter: Filter) -> Result, Error>; #[method(name = "getStorageAt")] @@ -252,6 +258,18 @@ impl EthRpcServer for RpcInner { convert_err(node.get_transaction_by_hash(&hash).await) } + async fn get_transaction_by_block_hash_and_index( + &self, + hash: &str, + index: usize, + ) -> Result, Error> { + let hash = convert_err(hex_str_to_bytes(hash))?; + let node = self.node.read().await; + convert_err( + node.get_transaction_by_block_hash_and_index(&hash, index) + .await, + ) + } async fn get_logs(&self, filter: Filter) -> Result, Error> { let node = self.node.read().await; convert_err(node.get_logs(&filter).await) diff --git a/execution/src/execution.rs b/execution/src/execution.rs index 400d027..07858cc 100644 --- a/execution/src/execution.rs +++ b/execution/src/execution.rs @@ -179,6 +179,21 @@ impl ExecutionClient { }) } + pub async fn get_transaction_by_block_hash_and_index( + &self, + payload: &ExecutionPayload, + index: usize, + ) -> Result> { + let tx = payload.transactions[index].clone(); + let tx_hash = H256::from_slice(&keccak256(tx)); + let mut payloads = BTreeMap::new(); + payloads.insert(payload.block_number, payload.clone()); + let tx_option = self.get_transaction(&tx_hash, &payloads).await?; + let tx = tx_option.ok_or(eyre::eyre!("not reachable"))?; + + Ok(Some(tx)) + } + pub async fn get_transaction_receipt( &self, tx_hash: &H256, @@ -260,7 +275,6 @@ impl ExecutionClient { if !txs_encoded.contains(&tx_encoded) { return Err(ExecutionError::MissingTransaction(hash.to_string()).into()); } - Ok(Some(tx)) } diff --git a/execution/tests/execution.rs b/execution/tests/execution.rs index 5c95859..0994e22 100644 --- a/execution/tests/execution.rs +++ b/execution/tests/execution.rs @@ -200,3 +200,23 @@ async fn test_get_block() { assert_eq!(block.number, 12345); } + +#[tokio::test] +async fn test_get_tx_by_block_hash_and_index() { + let execution = get_client(); + let tx_hash = + H256::from_str("2dac1b27ab58b493f902dda8b63979a112398d747f1761c0891777c0983e591f").unwrap(); + + let mut payload = ExecutionPayload { + block_number: 7530933, + ..ExecutionPayload::default() + }; + payload.transactions.push(List::from_iter(hex_str_to_bytes("0x02f8b20583623355849502f900849502f91082ea6094326c977e6efc84e512bb9c30f76e30c160ed06fb80b844a9059cbb0000000000000000000000007daccf9b3c1ae2fa5c55f1c978aeef700bc83be0000000000000000000000000000000000000000000000001158e460913d00000c080a0e1445466b058b6f883c0222f1b1f3e2ad9bee7b5f688813d86e3fa8f93aa868ca0786d6e7f3aefa8fe73857c65c32e4884d8ba38d0ecfb947fbffb82e8ee80c167").unwrap())); + + let tx = execution + .get_transaction_by_block_hash_and_index(&payload, 0) + .await + .unwrap() + .unwrap(); + assert_eq!(tx.hash(), tx_hash); +} From c7a1bad8e56961316cbd34db3076a8c4735c5756 Mon Sep 17 00:00:00 2001 From: Dimitris Apostolou Date: Tue, 10 Jan 2023 22:47:58 +0200 Subject: [PATCH 16/44] fix: typos (#164) --- README.md | 6 +++--- client/src/client.rs | 2 +- client/src/node.rs | 2 +- execution/src/evm.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f3f0fbd..da927d8 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Helios is still experimental software. While we hope you try it out, we do not s ### Additional Options -`--consensus-rpc` or `-c` can be used to set a custom consensus layer rpc endpoint. This must be a consenus node that supports the light client beaconchain api. We recommend using Nimbus for this. If no consensus rpc is supplied, it defaults to `https://www.lightclientdata.org` which is run by us. +`--consensus-rpc` or `-c` can be used to set a custom consensus layer rpc endpoint. This must be a consensus node that supports the light client beaconchain api. We recommend using Nimbus for this. If no consensus rpc is supplied, it defaults to `https://www.lightclientdata.org` which is run by us. `--checkpoint` or `-w` can be used to set a custom weak subjectivity checkpoint. This must be equal the first beacon blockhash of an epoch. Weak subjectivity checkpoints are the root of trust in the system. If this is set to a malicious value, an attacker can cause the client to sync to the wrong chain. Helios sets a default value initially, then caches the most recent finalized block it has seen for later use. @@ -58,9 +58,9 @@ For example, you can specify the fallback like so: `helios --fallback "https://s For example, say you set a checkpoint value that is too outdated and Helios cannot sync to it. If this flag is set, Helios will query all network apis in the community-maintained list at [ethpandaops/checkpoint-synz-health-checks](https://github.com/ethpandaops/checkpoint-sync-health-checks/blob/master/_data/endpoints.yaml) for their latest slots. -The list of slots is filtered for healthy apis and the most frequent checkpoint occuring in the latest epoch will be returned. +The list of slots is filtered for healthy apis and the most frequent checkpoint occurring in the latest epoch will be returned. Note: this is a community-maintained list and thus no security guarantees are provided. Use this is a last resort if your checkpoint passed into `--checkpoint` fails. -This is not recommened as malicious checkpoints can be returned from the listed apis, even if they are considered _healthy_. +This is not recommended as malicious checkpoints can be returned from the listed apis, even if they are considered _healthy_. This can be run like so: `helios --load-external-fallback` (or `helios -l` with the shorthand). `--help` or `-h` prints the help message. diff --git a/client/src/client.rs b/client/src/client.rs index b05d6d1..ea9e04f 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -210,7 +210,7 @@ impl Client { if fallback.is_err() && self.load_external_fallback { self.boot_from_external_fallbacks().await? } else if fallback.is_err() { - return Err(eyre::eyre!("Checkpoint is too old. Please update your checkpoint. Alternatively, set an explicit checkpoint fallback service url with the `-f` flag or use the configured external fallback services with `-l` (NOT RECOMMENED). See https://github.com/a16z/helios#additional-options for more information.")); + return Err(eyre::eyre!("Checkpoint is too old. Please update your checkpoint. Alternatively, set an explicit checkpoint fallback service url with the `-f` flag or use the configured external fallback services with `-l` (NOT RECOMMENDED). See https://github.com/a16z/helios#additional-options for more information.")); } } diff --git a/client/src/node.rs b/client/src/node.rs index a78c7d4..b9308f8 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -103,7 +103,7 @@ impl Node { } // only save one finalized block per epoch - // finality updates only occur on epoch boundries + // finality updates only occur on epoch boundaries while self.finalized_payloads.len() > usize::max(self.history_size / 32, 1) { self.finalized_payloads.pop_first(); } diff --git a/execution/src/evm.rs b/execution/src/evm.rs index 30ae16c..f25ce69 100644 --- a/execution/src/evm.rs +++ b/execution/src/evm.rs @@ -242,7 +242,7 @@ impl<'a, R: ExecutionRpc> Database for ProofDB<'a, R> { } trace!( - "fetch basic evm state for addess=0x{}", + "fetch basic evm state for address=0x{}", hex::encode(address.as_bytes()) ); From 819ee702e8552db88c167325c7a560b193d2ae2b Mon Sep 17 00:00:00 2001 From: danilowhk Date: Thu, 12 Jan 2023 22:30:15 -0300 Subject: [PATCH 17/44] feat : eth_coinbase implementation #157 (#167) * ethereum_get_cooinbase * change return type from CoinbaseAddress to Address * format --- client/src/client.rs | 4 ++++ client/src/node.rs | 7 +++++++ client/src/rpc.rs | 8 ++++++++ 3 files changed, 19 insertions(+) diff --git a/client/src/client.rs b/client/src/client.rs index ea9e04f..0f87a82 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -453,4 +453,8 @@ impl Client { pub async fn get_header(&self) -> Result
{ self.node.read().await.get_header() } + + pub async fn get_coinbase(&self) -> Result
{ + self.node.read().await.get_coinbase() + } } diff --git a/client/src/node.rs b/client/src/node.rs index b9308f8..9987413 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -291,6 +291,13 @@ impl Node { Ok(self.consensus.get_header().clone()) } + pub fn get_coinbase(&self) -> Result
{ + self.check_head_age()?; + let payload = self.get_payload(BlockTag::Latest)?; + let coinbase_address = Address::from_slice(&payload.fee_recipient); + Ok(coinbase_address) + } + pub fn get_last_checkpoint(&self) -> Option> { self.consensus.last_checkpoint.clone() } diff --git a/client/src/rpc.rs b/client/src/rpc.rs index 43b867d..8044da2 100644 --- a/client/src/rpc.rs +++ b/client/src/rpc.rs @@ -112,6 +112,8 @@ trait EthRpc { slot: H256, block: BlockTag, ) -> Result; + #[method(name = "getCoinbase")] + async fn get_coinbase(&self) -> Result; } #[rpc(client, server, namespace = "net")] @@ -270,6 +272,12 @@ impl EthRpcServer for RpcInner { .await, ) } + + async fn get_coinbase(&self) -> Result { + let node = self.node.read().await; + Ok(node.get_coinbase().unwrap()) + } + async fn get_logs(&self, filter: Filter) -> Result, Error> { let node = self.node.read().await; convert_err(node.get_logs(&filter).await) From 69b8108daec93181d4305411d8b9930a354e6ade Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 18 Jan 2023 19:42:56 -0500 Subject: [PATCH 18/44] fix: deserialize wrapped lc headers correctly (#169) * fix: deserialize wrapped lc headers correctly * clippy --- consensus/src/types.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/consensus/src/types.rs b/consensus/src/types.rs index 2fb7d37..44c7056 100644 --- a/consensus/src/types.rs +++ b/consensus/src/types.rs @@ -188,6 +188,7 @@ pub struct Eth1Data { #[derive(serde::Deserialize, Debug)] pub struct Bootstrap { + #[serde(deserialize_with = "header_deserialize")] pub header: Header, pub current_sync_committee: SyncCommittee, #[serde(deserialize_with = "branch_deserialize")] @@ -196,10 +197,12 @@ pub struct Bootstrap { #[derive(serde::Deserialize, Debug, Clone)] pub struct Update { + #[serde(deserialize_with = "header_deserialize")] pub attested_header: Header, pub next_sync_committee: SyncCommittee, #[serde(deserialize_with = "branch_deserialize")] pub next_sync_committee_branch: Vec, + #[serde(deserialize_with = "header_deserialize")] pub finalized_header: Header, #[serde(deserialize_with = "branch_deserialize")] pub finality_branch: Vec, @@ -210,7 +213,9 @@ pub struct Update { #[derive(serde::Deserialize, Debug)] pub struct FinalityUpdate { + #[serde(deserialize_with = "header_deserialize")] pub attested_header: Header, + #[serde(deserialize_with = "header_deserialize")] pub finalized_header: Header, #[serde(deserialize_with = "branch_deserialize")] pub finality_branch: Vec, @@ -221,6 +226,7 @@ pub struct FinalityUpdate { #[derive(serde::Deserialize, Debug)] pub struct OptimisticUpdate { + #[serde(deserialize_with = "header_deserialize")] pub attested_header: Header, pub sync_aggregate: SyncAggregate, #[serde(deserialize_with = "u64_deserialize")] @@ -453,3 +459,27 @@ where Ok(attesting_indices) } + +fn header_deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let header: LightClientHeader = serde::Deserialize::deserialize(deserializer)?; + + Ok(match header { + LightClientHeader::Unwrapped(header) => header, + LightClientHeader::Wrapped(header) => header.beacon, + }) +} + +#[derive(serde::Deserialize)] +#[serde(untagged)] +enum LightClientHeader { + Unwrapped(Header), + Wrapped(Beacon), +} + +#[derive(serde::Deserialize)] +struct Beacon { + beacon: Header, +} From cb6cf75d595920b90aac84ae2d4d76c9f8dae45c Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 18 Jan 2023 21:18:26 -0500 Subject: [PATCH 19/44] feat: make checkpoint age check optional (#170) * feat: make checkpoint age check optional * add new flag to readme * fix tests --- README.md | 2 ++ cli/src/main.rs | 3 +++ client/src/client.rs | 49 +++++++++++++++++++++++++++++--------- config/src/cli.rs | 6 +++++ config/src/config.rs | 1 + consensus/src/consensus.rs | 41 ++++++++++++++++++------------- 6 files changed, 74 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index da927d8..2d9e854 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ Note: this is a community-maintained list and thus no security guarantees are pr This is not recommended as malicious checkpoints can be returned from the listed apis, even if they are considered _healthy_. This can be run like so: `helios --load-external-fallback` (or `helios -l` with the shorthand). +`--strict-checkpoint-age` or `-s` enables strict checkpoint age checking. If the checkpoint is over two weeks old and this flag is enabled, Helios will error. Without this flag, Helios will instead surface a warning to the user and continue. If the checkpoint is greater than two weeks old, there are theoretical attacks that can cause Helios and over light clients to sync incorrectly. These attacks are complex and expensive, so Helios disables this by default. + `--help` or `-h` prints the help message. ### Configuration Files diff --git a/cli/src/main.rs b/cli/src/main.rs index d62f03e..cee757d 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -89,6 +89,8 @@ struct Cli { fallback: Option, #[clap(short = 'l', long, env)] load_external_fallback: bool, + #[clap(short = 's', long, env)] + strict_checkpoint_age: bool, } impl Cli { @@ -106,6 +108,7 @@ impl Cli { rpc_port: self.rpc_port, fallback: self.fallback.clone(), load_external_fallback: self.load_external_fallback, + strict_checkpoint_age: self.strict_checkpoint_age, } } diff --git a/client/src/client.rs b/client/src/client.rs index 0f87a82..f80e6ad 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -2,6 +2,7 @@ use std::path::PathBuf; use std::sync::Arc; use config::networks::Network; +use consensus::errors::ConsensusError; use ethers::prelude::{Address, U256}; use ethers::types::{Filter, Log, Transaction, TransactionReceipt, H256}; use eyre::{eyre, Result}; @@ -10,12 +11,13 @@ use common::types::BlockTag; use config::{CheckpointFallback, Config}; use consensus::{types::Header, ConsensusClient}; use execution::types::{CallOpts, ExecutionBlock}; -use log::{info, warn}; +use log::{error, info, warn}; use tokio::spawn; use tokio::sync::RwLock; use tokio::time::sleep; use crate::database::{Database, FileDB}; +use crate::errors::NodeError; use crate::node::Node; use crate::rpc::Rpc; @@ -30,6 +32,7 @@ pub struct ClientBuilder { config: Option, fallback: Option, load_external_fallback: bool, + strict_checkpoint_age: bool, } impl ClientBuilder { @@ -84,6 +87,11 @@ impl ClientBuilder { self } + pub fn strict_checkpoint_age(mut self) -> Self { + self.strict_checkpoint_age = true; + self + } + pub fn build(self) -> Result> { let base_config = if let Some(network) = self.network { network.to_base_config() @@ -149,6 +157,12 @@ impl ClientBuilder { self.load_external_fallback }; + let strict_checkpoint_age = if let Some(config) = &self.config { + self.strict_checkpoint_age || config.strict_checkpoint_age + } else { + self.strict_checkpoint_age + }; + let config = Config { consensus_rpc, execution_rpc, @@ -160,6 +174,7 @@ impl ClientBuilder { max_checkpoint_age: base_config.max_checkpoint_age, fallback, load_external_fallback, + strict_checkpoint_age, }; Client::new(config) @@ -201,16 +216,28 @@ impl Client { rpc.start().await?; } - if self.node.write().await.sync().await.is_err() { - warn!( - "failed to sync consensus node with checkpoint: 0x{}", - hex::encode(&self.node.read().await.config.checkpoint), - ); - let fallback = self.boot_from_fallback().await; - if fallback.is_err() && self.load_external_fallback { - self.boot_from_external_fallbacks().await? - } else if fallback.is_err() { - return Err(eyre::eyre!("Checkpoint is too old. Please update your checkpoint. Alternatively, set an explicit checkpoint fallback service url with the `-f` flag or use the configured external fallback services with `-l` (NOT RECOMMENDED). See https://github.com/a16z/helios#additional-options for more information.")); + let sync_res = self.node.write().await.sync().await; + + if let Err(err) = sync_res { + match err { + NodeError::ConsensusSyncError(err) => match err.downcast_ref().unwrap() { + ConsensusError::CheckpointTooOld => { + warn!( + "failed to sync consensus node with checkpoint: 0x{}", + hex::encode(&self.node.read().await.config.checkpoint), + ); + + let fallback = self.boot_from_fallback().await; + if fallback.is_err() && self.load_external_fallback { + self.boot_from_external_fallbacks().await? + } else if fallback.is_err() { + error!("Invalid checkpoint. Please update your checkpoint too a more recent block. Alternatively, set an explicit checkpoint fallback service url with the `-f` flag or use the configured external fallback services with `-l` (NOT RECOMMENDED). See https://github.com/a16z/helios#additional-options for more information."); + return Err(err); + } + } + _ => return Err(err), + }, + _ => return Err(err.into()), } } diff --git a/config/src/cli.rs b/config/src/cli.rs index 6c88f06..cd032ba 100644 --- a/config/src/cli.rs +++ b/config/src/cli.rs @@ -13,6 +13,7 @@ pub struct CliConfig { pub data_dir: PathBuf, pub fallback: Option, pub load_external_fallback: bool, + pub strict_checkpoint_age: bool, } impl CliConfig { @@ -46,6 +47,11 @@ impl CliConfig { Value::from(self.load_external_fallback), ); + user_dict.insert( + "strict_checkpoint_age", + Value::from(self.strict_checkpoint_age), + ); + Serialized::from(user_dict, network) } } diff --git a/config/src/config.rs b/config/src/config.rs index c2692a0..c19aee6 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -27,6 +27,7 @@ pub struct Config { pub max_checkpoint_age: u64, pub fallback: Option, pub load_external_fallback: bool, + pub strict_checkpoint_age: bool, } impl Config { diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index 8eb6258..dc1ea65 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -6,6 +6,7 @@ use blst::min_pk::PublicKey; use chrono::Duration; use eyre::eyre; use eyre::Result; +use log::warn; use log::{debug, info}; use ssz_rs::prelude::*; @@ -94,10 +95,6 @@ impl ConsensusClient { } pub async fn sync(&mut self) -> Result<()> { - info!( - "Consensus client in sync with checkpoint: 0x{}", - hex::encode(&self.initial_checkpoint) - ); self.bootstrap().await?; let current_period = calc_sync_period(self.store.finalized_header.slot); @@ -119,6 +116,11 @@ impl ConsensusClient { self.verify_optimistic_update(&optimistic_update)?; self.apply_optimistic_update(&optimistic_update); + info!( + "consensus client in sync with checkpoint: 0x{}", + hex::encode(&self.initial_checkpoint) + ); + Ok(()) } @@ -158,8 +160,13 @@ impl ConsensusClient { .map_err(|_| eyre!("could not fetch bootstrap"))?; let is_valid = self.is_valid_checkpoint(bootstrap.header.slot); + if !is_valid { - return Err(ConsensusError::CheckpointTooOld.into()); + if self.config.strict_checkpoint_age { + return Err(ConsensusError::CheckpointTooOld.into()); + } else { + warn!("checkpoint too old, consider using a more recent block"); + } } let committee_valid = is_current_committee_proof_valid( @@ -594,14 +601,14 @@ mod tests { }; use config::{networks, Config}; - async fn get_client(large_checkpoint_age: bool) -> ConsensusClient { + async fn get_client(strict_checkpoint_age: bool) -> ConsensusClient { let base_config = networks::goerli(); let config = Config { consensus_rpc: String::new(), execution_rpc: String::new(), chain: base_config.chain, forks: base_config.forks, - max_checkpoint_age: if large_checkpoint_age { 123123123 } else { 123 }, + strict_checkpoint_age, ..Default::default() }; @@ -616,7 +623,7 @@ mod tests { #[tokio::test] async fn test_verify_update() { - let client = get_client(true).await; + let client = get_client(false).await; let period = calc_sync_period(client.store.finalized_header.slot); let updates = client .rpc @@ -630,7 +637,7 @@ mod tests { #[tokio::test] async fn test_verify_update_invalid_committee() { - let client = get_client(true).await; + let client = get_client(false).await; let period = calc_sync_period(client.store.finalized_header.slot); let updates = client .rpc @@ -650,7 +657,7 @@ mod tests { #[tokio::test] async fn test_verify_update_invalid_finality() { - let client = get_client(true).await; + let client = get_client(false).await; let period = calc_sync_period(client.store.finalized_header.slot); let updates = client .rpc @@ -670,7 +677,7 @@ mod tests { #[tokio::test] async fn test_verify_update_invalid_sig() { - let client = get_client(true).await; + let client = get_client(false).await; let period = calc_sync_period(client.store.finalized_header.slot); let updates = client .rpc @@ -690,7 +697,7 @@ mod tests { #[tokio::test] async fn test_verify_finality() { - let mut client = get_client(true).await; + let mut client = get_client(false).await; client.sync().await.unwrap(); let update = client.rpc.get_finality_update().await.unwrap(); @@ -700,7 +707,7 @@ mod tests { #[tokio::test] async fn test_verify_finality_invalid_finality() { - let mut client = get_client(true).await; + let mut client = get_client(false).await; client.sync().await.unwrap(); let mut update = client.rpc.get_finality_update().await.unwrap(); @@ -715,7 +722,7 @@ mod tests { #[tokio::test] async fn test_verify_finality_invalid_sig() { - let mut client = get_client(true).await; + let mut client = get_client(false).await; client.sync().await.unwrap(); let mut update = client.rpc.get_finality_update().await.unwrap(); @@ -730,7 +737,7 @@ mod tests { #[tokio::test] async fn test_verify_optimistic() { - let mut client = get_client(true).await; + let mut client = get_client(false).await; client.sync().await.unwrap(); let update = client.rpc.get_optimistic_update().await.unwrap(); @@ -739,7 +746,7 @@ mod tests { #[tokio::test] async fn test_verify_optimistic_invalid_sig() { - let mut client = get_client(true).await; + let mut client = get_client(false).await; client.sync().await.unwrap(); let mut update = client.rpc.get_optimistic_update().await.unwrap(); @@ -755,6 +762,6 @@ mod tests { #[tokio::test] #[should_panic] async fn test_verify_checkpoint_age_invalid() { - get_client(false).await; + get_client(true).await; } } From 4d1ca1d6edb16f1fc64a7117d4ec0261e7d5cc25 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 18 Jan 2023 21:23:47 -0500 Subject: [PATCH 20/44] chore: rename examples (#171) --- examples/{readme.rs => basic.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{readme.rs => basic.rs} (100%) diff --git a/examples/readme.rs b/examples/basic.rs similarity index 100% rename from examples/readme.rs rename to examples/basic.rs From 4d6568a8a57d7ecb2a01aab9137ecd69d1471b8f Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 18 Jan 2023 21:45:29 -0500 Subject: [PATCH 21/44] fix: correct example names in cargo (#172) --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8601e3d..5c4f7b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,8 +50,8 @@ name = "checkpoints" path = "examples/checkpoints.rs" [[example]] -name = "readme" -path = "examples/readme.rs" +name = "basic" +path = "examples/basic.rs" [[example]] name = "client" From 10e39eb35ade1e4c7312c04aa5c6640be7924baa Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Thu, 19 Jan 2023 19:23:06 -0500 Subject: [PATCH 22/44] chore: bump version to 0.1.3 (#173) --- Cargo.toml | 2 +- cli/Cargo.toml | 2 +- client/Cargo.toml | 2 +- common/Cargo.toml | 2 +- config/Cargo.toml | 2 +- consensus/Cargo.toml | 2 +- execution/Cargo.toml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5c4f7b0..5d8db37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helios" -version = "0.1.2" +version = "0.1.3" edition = "2021" autobenches = false diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 9462629..3159f7a 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["different-binary-name"] [package] name = "cli" -version = "0.1.0" +version = "0.1.3" edition = "2021" [[bin]] diff --git a/client/Cargo.toml b/client/Cargo.toml index 59bec83..95e91fd 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "client" -version = "0.1.1" +version = "0.1.3" edition = "2021" [dependencies] diff --git a/common/Cargo.toml b/common/Cargo.toml index 7edc1db..82f5a5f 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "common" -version = "0.1.0" +version = "0.1.3" edition = "2021" [dependencies] diff --git a/config/Cargo.toml b/config/Cargo.toml index 120885b..ba17647 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "config" -version = "0.1.0" +version = "0.1.3" edition = "2021" [dependencies] diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 5f3fa4c..2c8b700 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "consensus" -version = "0.1.0" +version = "0.1.3" edition = "2021" [dependencies] diff --git a/execution/Cargo.toml b/execution/Cargo.toml index 012c271..b0c46e5 100644 --- a/execution/Cargo.toml +++ b/execution/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "execution" -version = "0.1.0" +version = "0.1.3" edition = "2021" [dependencies] From de90eb91584be096e4a87ec35db5ca9daa60622e Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Sun, 22 Jan 2023 11:58:55 -0500 Subject: [PATCH 23/44] feat: check execution rpc network (#176) * feat: check execution rpc network * clippy --- Cargo.lock | 14 +++++++------- cli/src/main.rs | 15 ++++++++++++--- client/src/errors.rs | 9 ++++++--- client/src/node.rs | 11 +++++++++-- execution/src/errors.rs | 4 ++++ execution/src/execution.rs | 16 +++++++++++++++- execution/src/rpc/http_rpc.rs | 9 +++++++++ execution/src/rpc/mock_rpc.rs | 4 ++++ execution/src/rpc/mod.rs | 1 + 9 files changed, 67 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 88ad67b..0818a8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -526,7 +526,7 @@ dependencies = [ [[package]] name = "cli" -version = "0.1.0" +version = "0.1.3" dependencies = [ "clap", "client", @@ -543,7 +543,7 @@ dependencies = [ [[package]] name = "client" -version = "0.1.1" +version = "0.1.3" dependencies = [ "common", "config", @@ -645,7 +645,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "common" -version = "0.1.0" +version = "0.1.3" dependencies = [ "ethers", "eyre", @@ -657,7 +657,7 @@ dependencies = [ [[package]] name = "config" -version = "0.1.0" +version = "0.1.3" dependencies = [ "common", "ethers", @@ -677,7 +677,7 @@ dependencies = [ [[package]] name = "consensus" -version = "0.1.0" +version = "0.1.3" dependencies = [ "async-trait", "blst", @@ -1461,7 +1461,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "execution" -version = "0.1.0" +version = "0.1.3" dependencies = [ "async-trait", "bytes", @@ -1979,7 +1979,7 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "helios" -version = "0.1.2" +version = "0.1.3" dependencies = [ "client", "common", diff --git a/cli/src/main.rs b/cli/src/main.rs index cee757d..270f777 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -15,16 +15,25 @@ use eyre::Result; use client::{database::FileDB, Client, ClientBuilder}; use config::{CliConfig, Config}; use futures::executor::block_on; -use log::info; +use log::{error, info}; #[tokio::main] async fn main() -> Result<()> { env_logger::Builder::from_env(Env::default().default_filter_or("info")).init(); let config = get_config(); - let mut client = ClientBuilder::new().config(config).build()?; + let mut client = match ClientBuilder::new().config(config).build() { + Ok(client) => client, + Err(err) => { + error!("{}", err); + exit(1); + } + }; - client.start().await?; + if let Err(err) = client.start().await { + error!("{}", err); + exit(1); + } register_shutdown_handler(client); std::future::pending().await diff --git a/client/src/errors.rs b/client/src/errors.rs index b0b0018..84959fd 100644 --- a/client/src/errors.rs +++ b/client/src/errors.rs @@ -1,5 +1,5 @@ use common::errors::BlockNotFoundError; -use execution::errors::EvmError; +use execution::errors::{EvmError, ExecutionError}; use eyre::Report; use thiserror::Error; @@ -7,7 +7,10 @@ use thiserror::Error; #[derive(Debug, Error)] pub enum NodeError { #[error(transparent)] - ExecutionError(#[from] EvmError), + ExecutionEvmError(#[from] EvmError), + + #[error(transparent)] + ExecutionError(#[from] ExecutionError), #[error("out of sync: {0} slots behind")] OutOfSync(u64), @@ -37,7 +40,7 @@ pub enum NodeError { impl NodeError { pub fn to_json_rpsee_error(self) -> jsonrpsee::core::Error { match self { - NodeError::ExecutionError(evm_err) => match evm_err { + NodeError::ExecutionEvmError(evm_err) => match evm_err { EvmError::Revert(data) => { let mut msg = "execution reverted".to_string(); if let Some(reason) = data.as_ref().and_then(EvmError::decode_revert_reason) { diff --git a/client/src/node.rs b/client/src/node.rs index 9987413..48bc0dc 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -54,10 +54,17 @@ impl Node { } pub async fn sync(&mut self) -> Result<(), NodeError> { + let chain_id = self.config.chain.chain_id; + self.execution + .check_rpc(chain_id) + .await + .map_err(NodeError::ExecutionError)?; + self.consensus .sync() .await .map_err(NodeError::ConsensusSyncError)?; + self.update_payloads().await } @@ -121,7 +128,7 @@ impl Node { &self.payloads, self.chain_id(), ); - evm.call(opts).await.map_err(NodeError::ExecutionError) + evm.call(opts).await.map_err(NodeError::ExecutionEvmError) } pub async fn estimate_gas(&self, opts: &CallOpts) -> Result { @@ -136,7 +143,7 @@ impl Node { ); evm.estimate_gas(opts) .await - .map_err(NodeError::ExecutionError) + .map_err(NodeError::ExecutionEvmError) } pub async fn get_balance(&self, address: &Address, block: BlockTag) -> Result { diff --git a/execution/src/errors.rs b/execution/src/errors.rs index 415fe91..0512d10 100644 --- a/execution/src/errors.rs +++ b/execution/src/errors.rs @@ -24,6 +24,10 @@ pub enum ExecutionError { MissingLog(String, U256), #[error("too many logs to prove: {0}, current limit is: {1}")] TooManyLogsToProve(usize, usize), + #[error("rpc error: {0:?}")] + RpcError(Report), + #[error("execution rpc is for the incorect network")] + IncorrectRpcNetwork(), } /// Errors that can occur during evm.rs calls diff --git a/execution/src/execution.rs b/execution/src/execution.rs index 07858cc..0f310f8 100644 --- a/execution/src/execution.rs +++ b/execution/src/execution.rs @@ -32,10 +32,24 @@ pub struct ExecutionClient { impl ExecutionClient { pub fn new(rpc: &str) -> Result { - let rpc = ExecutionRpc::new(rpc)?; + let rpc: R = ExecutionRpc::new(rpc)?; Ok(ExecutionClient { rpc }) } + pub async fn check_rpc(&self, chain_id: u64) -> Result<(), ExecutionError> { + if self + .rpc + .chain_id() + .await + .map_err(ExecutionError::RpcError)? + != chain_id + { + Err(ExecutionError::IncorrectRpcNetwork()) + } else { + Ok(()) + } + } + pub async fn get_account( &self, address: &Address, diff --git a/execution/src/rpc/http_rpc.rs b/execution/src/rpc/http_rpc.rs index 4b02ee4..d395b4b 100644 --- a/execution/src/rpc/http_rpc.rs +++ b/execution/src/rpc/http_rpc.rs @@ -128,4 +128,13 @@ impl ExecutionRpc for HttpRpc { .await .map_err(|e| RpcError::new("get_logs", e))?) } + + async fn chain_id(&self) -> Result { + Ok(self + .provider + .get_chainid() + .await + .map_err(|e| RpcError::new("chain_id", e))? + .as_u64()) + } } diff --git a/execution/src/rpc/mock_rpc.rs b/execution/src/rpc/mock_rpc.rs index 4527c68..3a4fd1e 100644 --- a/execution/src/rpc/mock_rpc.rs +++ b/execution/src/rpc/mock_rpc.rs @@ -61,4 +61,8 @@ impl ExecutionRpc for MockRpc { let logs = read_to_string(self.path.join("logs.json"))?; Ok(serde_json::from_str(&logs)?) } + + async fn chain_id(&self) -> Result { + Err(eyre!("not implemented")) + } } diff --git a/execution/src/rpc/mod.rs b/execution/src/rpc/mod.rs index 1a47c16..0c1b799 100644 --- a/execution/src/rpc/mod.rs +++ b/execution/src/rpc/mod.rs @@ -29,4 +29,5 @@ pub trait ExecutionRpc: Send + Clone + Sync + 'static { async fn get_transaction_receipt(&self, tx_hash: &H256) -> Result>; async fn get_transaction(&self, tx_hash: &H256) -> Result>; async fn get_logs(&self, filter: &Filter) -> Result>; + async fn chain_id(&self) -> Result; } From 2c5c318529181a8d5dad1eb3184d898c4ee500a3 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Mon, 23 Jan 2023 10:07:11 -0500 Subject: [PATCH 24/44] feat: check consensus rpc network (#177) * feat: check consensus rpc network * cleanup --- client/src/errors.rs | 6 +++--- client/src/node.rs | 5 +++++ consensus/src/consensus.rs | 10 ++++++++++ consensus/src/errors.rs | 2 ++ consensus/src/rpc/mock_rpc.rs | 10 ++++++---- consensus/src/rpc/mod.rs | 1 + consensus/src/rpc/nimbus_rpc.rs | 28 +++++++++++++++++++++++++++- consensus/src/types.rs | 2 +- execution/src/errors.rs | 2 -- execution/src/execution.rs | 12 +++--------- execution/src/rpc/http_rpc.rs | 2 +- 11 files changed, 59 insertions(+), 21 deletions(-) diff --git a/client/src/errors.rs b/client/src/errors.rs index 84959fd..39a6679 100644 --- a/client/src/errors.rs +++ b/client/src/errors.rs @@ -1,5 +1,5 @@ use common::errors::BlockNotFoundError; -use execution::errors::{EvmError, ExecutionError}; +use execution::errors::EvmError; use eyre::Report; use thiserror::Error; @@ -9,8 +9,8 @@ pub enum NodeError { #[error(transparent)] ExecutionEvmError(#[from] EvmError), - #[error(transparent)] - ExecutionError(#[from] ExecutionError), + #[error("execution error: {0}")] + ExecutionError(Report), #[error("out of sync: {0} slots behind")] OutOfSync(u64), diff --git a/client/src/node.rs b/client/src/node.rs index 48bc0dc..5b1dd3b 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -60,6 +60,11 @@ impl Node { .await .map_err(NodeError::ExecutionError)?; + self.consensus + .check_rpc() + .await + .map_err(NodeError::ConsensusSyncError)?; + self.consensus .sync() .await diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index dc1ea65..b29905b 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -59,6 +59,16 @@ impl ConsensusClient { }) } + pub async fn check_rpc(&self) -> Result<()> { + let chain_id = self.rpc.chain_id().await?; + + if chain_id != self.config.chain.chain_id { + Err(ConsensusError::IncorrectRpcNetwork.into()) + } else { + Ok(()) + } + } + pub async fn get_execution_payload(&self, slot: &Option) -> Result { let slot = slot.unwrap_or(self.store.optimistic_header.slot); let mut block = self.rpc.get_block(slot).await?; diff --git a/consensus/src/errors.rs b/consensus/src/errors.rs index 41c5558..98a5424 100644 --- a/consensus/src/errors.rs +++ b/consensus/src/errors.rs @@ -24,4 +24,6 @@ pub enum ConsensusError { PayloadNotFound(u64), #[error("checkpoint is too old")] CheckpointTooOld, + #[error("consensus rpc is for the incorrect network")] + IncorrectRpcNetwork, } diff --git a/consensus/src/rpc/mock_rpc.rs b/consensus/src/rpc/mock_rpc.rs index 97a4b90..f4ac130 100644 --- a/consensus/src/rpc/mock_rpc.rs +++ b/consensus/src/rpc/mock_rpc.rs @@ -1,11 +1,9 @@ use std::{fs::read_to_string, path::PathBuf}; -use async_trait::async_trait; -use eyre::Result; - use super::ConsensusRpc; use crate::types::{BeaconBlock, Bootstrap, FinalityUpdate, OptimisticUpdate, Update}; - +use async_trait::async_trait; +use eyre::Result; pub struct MockRpc { testdata: PathBuf, } @@ -42,4 +40,8 @@ impl ConsensusRpc for MockRpc { let block = read_to_string(self.testdata.join("blocks.json"))?; Ok(serde_json::from_str(&block)?) } + + async fn chain_id(&self) -> Result { + eyre::bail!("not implemented") + } } diff --git a/consensus/src/rpc/mod.rs b/consensus/src/rpc/mod.rs index cba8bf1..9dc8874 100644 --- a/consensus/src/rpc/mod.rs +++ b/consensus/src/rpc/mod.rs @@ -15,4 +15,5 @@ pub trait ConsensusRpc { async fn get_finality_update(&self) -> Result; async fn get_optimistic_update(&self) -> Result; async fn get_block(&self, slot: u64) -> Result; + async fn chain_id(&self) -> Result; } diff --git a/consensus/src/rpc/nimbus_rpc.rs b/consensus/src/rpc/nimbus_rpc.rs index ca6c478..e4006fa 100644 --- a/consensus/src/rpc/nimbus_rpc.rs +++ b/consensus/src/rpc/nimbus_rpc.rs @@ -1,5 +1,4 @@ use async_trait::async_trait; -use common::errors::RpcError; use eyre::Result; use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware}; @@ -8,6 +7,7 @@ use std::cmp; use super::ConsensusRpc; use crate::constants::MAX_REQUEST_LIGHT_CLIENT_UPDATES; use crate::types::*; +use common::errors::RpcError; pub struct NimbusRpc { rpc: String, @@ -115,6 +115,21 @@ impl ConsensusRpc for NimbusRpc { Ok(res.data.message) } + + async fn chain_id(&self) -> Result { + let req = format!("{}/eth/v1/config/spec", self.rpc); + let res = self + .client + .get(req) + .send() + .await + .map_err(|e| RpcError::new("spec", e))? + .json::() + .await + .map_err(|e| RpcError::new("spec", e))?; + + Ok(res.data.chain_id) + } } #[derive(serde::Deserialize, Debug)] @@ -148,3 +163,14 @@ struct OptimisticUpdateResponse { struct BootstrapResponse { data: Bootstrap, } + +#[derive(serde::Deserialize, Debug)] +struct SpecResponse { + data: Spec, +} + +#[derive(serde::Deserialize, Debug)] +struct Spec { + #[serde(rename = "DEPOSIT_NETWORK_ID", deserialize_with = "u64_deserialize")] + chain_id: u64, +} diff --git a/consensus/src/types.rs b/consensus/src/types.rs index 44c7056..b341ef2 100644 --- a/consensus/src/types.rs +++ b/consensus/src/types.rs @@ -376,7 +376,7 @@ where .map_err(D::Error::custom) } -fn u64_deserialize<'de, D>(deserializer: D) -> Result +pub fn u64_deserialize<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de>, { diff --git a/execution/src/errors.rs b/execution/src/errors.rs index 0512d10..12b52b1 100644 --- a/execution/src/errors.rs +++ b/execution/src/errors.rs @@ -24,8 +24,6 @@ pub enum ExecutionError { MissingLog(String, U256), #[error("too many logs to prove: {0}, current limit is: {1}")] TooManyLogsToProve(usize, usize), - #[error("rpc error: {0:?}")] - RpcError(Report), #[error("execution rpc is for the incorect network")] IncorrectRpcNetwork(), } diff --git a/execution/src/execution.rs b/execution/src/execution.rs index 0f310f8..3a16028 100644 --- a/execution/src/execution.rs +++ b/execution/src/execution.rs @@ -36,15 +36,9 @@ impl ExecutionClient { Ok(ExecutionClient { rpc }) } - pub async fn check_rpc(&self, chain_id: u64) -> Result<(), ExecutionError> { - if self - .rpc - .chain_id() - .await - .map_err(ExecutionError::RpcError)? - != chain_id - { - Err(ExecutionError::IncorrectRpcNetwork()) + pub async fn check_rpc(&self, chain_id: u64) -> Result<()> { + if self.rpc.chain_id().await? != chain_id { + Err(ExecutionError::IncorrectRpcNetwork().into()) } else { Ok(()) } diff --git a/execution/src/rpc/http_rpc.rs b/execution/src/rpc/http_rpc.rs index d395b4b..05e4342 100644 --- a/execution/src/rpc/http_rpc.rs +++ b/execution/src/rpc/http_rpc.rs @@ -1,7 +1,6 @@ use std::str::FromStr; use async_trait::async_trait; -use common::errors::RpcError; use ethers::prelude::{Address, Http}; use ethers::providers::{HttpRateLimitRetryPolicy, Middleware, Provider, RetryClient}; use ethers::types::transaction::eip2718::TypedTransaction; @@ -13,6 +12,7 @@ use ethers::types::{ use eyre::Result; use crate::types::CallOpts; +use common::errors::RpcError; use super::ExecutionRpc; From 604b32598357b5296ad8578697c347c28b759596 Mon Sep 17 00:00:00 2001 From: James Prestwich <10149425+prestwich@users.noreply.github.com> Date: Tue, 24 Jan 2023 17:30:03 -0500 Subject: [PATCH 25/44] fix: specify precise nightly version (#179) --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index 07ade69..fe03a4d 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -nightly \ No newline at end of file +nightly-2023-01-23 From 72267b456366ea68ea054001402a262a62c93ca1 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Mon, 30 Jan 2023 21:38:46 -0500 Subject: [PATCH 26/44] feat: wasm support (#182) * basic consensus setup * basic execution setup * patch for wasm * basic wasm client * proxy cors for testing * migrate to webpack * use typescript * track chain head * rename to helios-ts * better build instructions * add getCode * builds everywhere * add wasm-pack to dependencies * compile for both wasm and non-wasm * fix deps * fix deps * remove ds store * add blocktags * add getNonce * use BTreeMap to store payloads * add getTransaction * switch to proper ethers provider * post merge fixes * compile client to wasm * fix tests * fmt * use milagro for bls * handle node advance in rust * faster bls deserialization * clippy * add ConfigDB * remove ts bindings * fix gitignore * remove ts workspace member * remove unused mut * uncomment old deletions * bump to 0.2.0 --- .gitignore | 4 +- Cargo.lock | 683 +++++++++++++------------------- Cargo.toml | 9 +- cli/Cargo.toml | 2 +- cli/src/main.rs | 24 +- client/Cargo.toml | 18 +- client/src/client.rs | 77 +++- client/src/database.rs | 51 ++- client/src/errors.rs | 1 + client/src/lib.rs | 4 +- common/Cargo.toml | 6 +- config/Cargo.toml | 12 +- config/src/checkpoints.rs | 21 +- config/src/networks.rs | 2 +- consensus/Cargo.toml | 22 +- consensus/src/consensus.rs | 27 +- consensus/src/rpc/mock_rpc.rs | 3 +- consensus/src/rpc/mod.rs | 3 +- consensus/src/rpc/nimbus_rpc.rs | 44 +- consensus/src/utils.rs | 10 +- examples/basic.rs | 5 +- examples/client.rs | 2 +- execution/Cargo.toml | 14 +- execution/src/evm.rs | 10 +- execution/src/rpc/http_rpc.rs | 5 +- execution/src/rpc/mock_rpc.rs | 3 +- execution/src/rpc/mod.rs | 3 +- 27 files changed, 499 insertions(+), 566 deletions(-) diff --git a/.gitignore b/.gitignore index 5868362..a82f9f3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/target - +.DS_Store +target *.env diff --git a/Cargo.lock b/Cargo.lock index 0818a8a..999c748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,9 +31,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", "once_cell", @@ -49,6 +49,11 @@ dependencies = [ "memchr", ] +[[package]] +name = "amcl" +version = "0.3.0" +source = "git+https://github.com/Snowfork/milagro_bls#2c9e8b383981308a8b4cbbc19e0b897dcf14534b" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -66,9 +71,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" [[package]] name = "arrayref" @@ -100,9 +105,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.59" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +checksum = "eff18d764974428cf3a9328e23fc5c986f5fbed46e6cd4cdf42544df5d297ec1" dependencies = [ "proc-macro2", "quote", @@ -135,7 +140,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -204,6 +209,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" + [[package]] name = "base64ct" version = "1.5.3" @@ -264,9 +275,9 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b12e5fd123190ce1c2e559308a94c9bacad77907d4c6005d9e58fe1a0689e55e" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ "digest 0.10.6", ] @@ -310,19 +321,6 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "blst" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a30d0edd9dd1c60ddb42b80341c7852f6f985279a5c1a83659dcb65899dec99" -dependencies = [ - "cc", - "glob", - "threadpool", - "which", - "zeroize", -] - [[package]] name = "bs58" version = "0.4.0" @@ -331,18 +329,19 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bstr" -version = "0.2.17" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "b45ea9b00a7b3f2988e9a65ad3917e62123c38dba709b666506207be96d1790b" dependencies = [ "memchr", + "serde", ] [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "byte-slice-cast" @@ -364,9 +363,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.12.3" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" +checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" [[package]] name = "byteorder" @@ -385,9 +384,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c77df041dc383319cc661b428b6961a005db4d6808d5e12536931b1ca9556055" dependencies = [ "serde", ] @@ -409,7 +408,7 @@ checksum = "982a0cf6a99c350d7246035613882e376d58cebe571785abc5da4f648d53ac0a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.14", + "semver 1.0.16", "serde", "serde_json", "thiserror", @@ -423,9 +422,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.77" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" [[package]] name = "cfg-if" @@ -552,6 +551,7 @@ dependencies = [ "execution", "eyre", "futures", + "gloo-timers", "hex", "jsonrpsee", "log", @@ -559,6 +559,7 @@ dependencies = [ "ssz-rs", "thiserror", "tokio", + "wasm-bindgen-futures", ] [[package]] @@ -680,7 +681,6 @@ name = "consensus" version = "0.1.3" dependencies = [ "async-trait", - "blst", "bytes", "chrono", "common", @@ -689,16 +689,16 @@ dependencies = [ "eyre", "hex", "log", + "milagro_bls", "openssl", "reqwest", - "reqwest-middleware", - "reqwest-retry", "serde", "serde_json", "ssz-rs", "thiserror", "tokio", "toml", + "wasm-timer", ] [[package]] @@ -913,19 +913,19 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.2.3" +version = "3.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d91974fbbe88ec1df0c24a4f00f99583667a7e2e6272b2b92d294d81e462173" +checksum = "1631ca6e3c59112501a9d87fd86f21591ff77acd31331e8a73f8d80a65bbdd71" dependencies = [ "nix", - "winapi", + "windows-sys", ] [[package]] name = "cxx" -version = "1.0.83" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e" dependencies = [ "cc", "cxxbridge-flags", @@ -935,9 +935,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.83" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200" dependencies = [ "cc", "codespan-reporting", @@ -950,15 +950,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.83" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" +checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea" [[package]] name = "cxxbridge-macro" -version = "1.0.83" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e" dependencies = [ "proc-macro2", "quote", @@ -967,9 +967,9 @@ dependencies = [ [[package]] name = "der" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ "const-oid", "zeroize", @@ -1242,9 +1242,8 @@ dependencies = [ [[package]] name = "ethers" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f26f9d8d80da18ca72aca51804c65eb2153093af3bec74fd5ce32aa0c1f665" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1257,9 +1256,8 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4be54dd2260945d784e06ccdeb5ad573e8f1541838cee13a1ab885485eaa0b" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "ethers-core", "once_cell", @@ -1269,9 +1267,8 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c3c3e119a89f0a9a1e539e7faecea815f74ddcf7c90d0b00d1f524db2fdc9c" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", @@ -1288,9 +1285,8 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4e5ad46aede34901f71afdb7bb555710ed9613d88d644245c657dc371aa228" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "Inflector", "cfg-if", @@ -1313,9 +1309,8 @@ dependencies = [ [[package]] name = "ethers-contract-derive" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f192e8e4cf2b038318aae01e94e7644e0659a76219e94bcd3203df744341d61f" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "ethers-contract-abigen", "ethers-core", @@ -1328,9 +1323,8 @@ dependencies = [ [[package]] name = "ethers-core" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "arrayvec 0.7.2", "bytes", @@ -1359,14 +1353,13 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9713f525348e5dde025d09b0a4217429f8074e8ff22c886263cc191e87d8216" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "ethers-core", "getrandom 0.2.8", "reqwest", - "semver 1.0.14", + "semver 1.0.16", "serde", "serde-aux", "serde_json", @@ -1376,9 +1369,8 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e71df7391b0a9a51208ffb5c7f2d068900e99d6b3128d3a4849d138f194778b7" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "async-trait", "auto_impl 0.5.0", @@ -1402,9 +1394,8 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "async-trait", "auto_impl 1.0.1", @@ -1437,9 +1428,8 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f41ced186867f64773db2e55ffdd92959e094072a1d09a5e5e831d443204f98" +version = "1.0.0" +source = "git+https://github.com/gakonst/ethers-rs?rev=c17c0c3c956f12d205a5ede3176599d8a30ca739#c17c0c3c956f12d205a5ede3176599d8a30ca739" dependencies = [ "async-trait", "coins-bip32", @@ -1720,9 +1710,9 @@ dependencies = [ [[package]] name = "futures-locks" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb42d4fb72227be5778429f9ef5240a38a358925a49f05b5cf702ce7c7e558a" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" dependencies = [ "futures-channel", "futures-task", @@ -1841,17 +1831,11 @@ dependencies = [ "weezl", ] -[[package]] -name = "glob" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" - [[package]] name = "globset" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" dependencies = [ "aho-corasick", "bstr", @@ -1862,9 +1846,9 @@ dependencies = [ [[package]] name = "gloo-net" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9050ff8617e950288d7bf7f300707639fdeda5ca0d0ecf380cff448cfd52f4a6" +checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" dependencies = [ "futures-channel", "futures-core", @@ -1882,9 +1866,9 @@ dependencies = [ [[package]] name = "gloo-timers" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c4a8d6391675c6b2ee1a6c8d06e8e2d03605c44cec1270675985a4c2a5500b" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ "futures-channel", "futures-core", @@ -1955,11 +1939,12 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ "ahash", + "serde", ] [[package]] @@ -2008,11 +1993,23 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + [[package]] name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "hmac" @@ -2098,9 +2095,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.23.1" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59df7c4e19c950e6e0e868dcc0a300b09a9b88e9ec55bd879ca819087a77355d" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" dependencies = [ "http", "hyper", @@ -2189,7 +2186,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.2.1", + "parity-scale-codec 3.2.2", ] [[package]] @@ -2293,9 +2290,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.1" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" +checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" [[package]] name = "itertools" @@ -2308,9 +2305,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" [[package]] name = "jpeg-decoder" @@ -2554,9 +2551,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.138" +version = "0.2.139" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libloading" @@ -2570,9 +2567,9 @@ dependencies = [ [[package]] name = "link-cplusplus" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" dependencies = [ "cc", ] @@ -2620,22 +2617,24 @@ dependencies = [ "autocfg", ] +[[package]] +name = "milagro_bls" +version = "1.5.0" +source = "git+https://github.com/Snowfork/milagro_bls#2c9e8b383981308a8b4cbbc19e0b897dcf14534b" +dependencies = [ + "amcl", + "hex", + "lazy_static", + "rand 0.8.5", + "zeroize", +] + [[package]] name = "mime" version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "miniz_oxide" version = "0.6.2" @@ -2654,7 +2653,7 @@ dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -2677,14 +2676,23 @@ dependencies = [ [[package]] name = "nix" -version = "0.25.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "autocfg", "bitflags", "cfg-if", "libc", + "static_assertions", +] + +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", ] [[package]] @@ -2724,9 +2732,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" dependencies = [ "num-traits", ] @@ -2775,11 +2783,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -2806,9 +2814,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "oorandom" @@ -2855,9 +2863,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.43" +version = "0.10.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376" +checksum = "b102428fd03bc5edf97f62620f7298614c45cedf287c271e7ed450bbaf83f2e1" dependencies = [ "bitflags", "cfg-if", @@ -2896,9 +2904,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.78" +version = "0.9.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132" +checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" dependencies = [ "autocfg", "cc", @@ -2934,9 +2942,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.2.1" +version = "3.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "366e44391a8af4cfd6002ef6ba072bae071a96aafca98d7d448a34c5dca38b6a" +checksum = "e7ab01d0f889e957861bc65888d5ccbe82c158d0270136ba46820d43837cdf72" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -2948,9 +2956,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.1.3" +version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9299338969a3d2f491d65f140b00ddec470858402f888af98e8642fb5e8965cd" +checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -2972,7 +2980,7 @@ checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.5", + "parking_lot_core 0.8.6", ] [[package]] @@ -2982,14 +2990,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.5", + "parking_lot_core 0.9.6", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ "cfg-if", "instant", @@ -3001,15 +3009,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.42.0", + "windows-sys", ] [[package]] @@ -3085,9 +3093,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.5.1" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc8bed3549e0f9b0a2a78bf7c0018237a2cdf085eecbbc048e52612438e4e9d0" +checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" dependencies = [ "thiserror", "ucd-trie", @@ -3253,13 +3261,12 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" +checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" dependencies = [ "once_cell", - "thiserror", - "toml", + "toml_edit", ] [[package]] @@ -3288,9 +3295,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -3310,9 +3317,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -3402,20 +3409,19 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" dependencies = [ - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -3445,9 +3451,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", @@ -3480,11 +3486,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.13" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" +checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9" dependencies = [ - "base64 0.13.1", + "base64 0.21.0", "bytes", "encoding_rs", "futures-core", @@ -3499,7 +3505,6 @@ dependencies = [ "js-sys", "log", "mime", - "mime_guess", "native-tls", "once_cell", "percent-encoding", @@ -3521,53 +3526,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "reqwest-middleware" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69539cea4148dce683bec9dc95be3f0397a9bb2c248a49c8296a9d21659a8cdd" -dependencies = [ - "anyhow", - "async-trait", - "futures", - "http", - "reqwest", - "serde", - "task-local-extensions", - "thiserror", -] - -[[package]] -name = "reqwest-retry" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce246a729eaa6aff5e215aee42845bf5fed9893cc6cd51aeeb712f34e04dd9f3" -dependencies = [ - "anyhow", - "async-trait", - "chrono", - "futures", - "http", - "hyper", - "reqwest", - "reqwest-middleware", - "retry-policies", - "task-local-extensions", - "tokio", - "tracing", -] - -[[package]] -name = "retry-policies" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e09bbcb5003282bcb688f0bae741b278e9c7e8f378f561522c9806c58e075d9b" -dependencies = [ - "anyhow", - "chrono", - "rand 0.8.5", -] - [[package]] name = "revm" version = "2.3.1" @@ -3577,11 +3535,13 @@ dependencies = [ "arrayref", "auto_impl 1.0.1", "bytes", - "hashbrown 0.13.1", + "hashbrown 0.13.2", + "hex", "num_enum", "primitive-types 0.12.1", "revm_precompiles", "rlp 0.5.2", + "serde", "sha3", ] @@ -3592,12 +3552,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0353d456ef3e989dc9190f42c6020f09bc2025930c37895826029304413204b5" dependencies = [ "bytes", - "hashbrown 0.13.1", + "hashbrown 0.13.2", + "k256", "num", "once_cell", "primitive-types 0.12.1", "ripemd", - "secp256k1", "sha2 0.10.6", "sha3", "substrate-bn", @@ -3695,14 +3655,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver 1.0.16", ] [[package]] name = "rustls" -version = "0.20.7" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", "ring", @@ -3724,24 +3684,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64 0.13.1", + "base64 0.21.0", ] [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" [[package]] name = "salsa20" @@ -3763,21 +3723,21 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d8a765117b237ef233705cc2cc4c6a27fccd46eea6ef0c8c6dae5f3ef407f8" +checksum = "001cf62ece89779fd16105b5f515ad0e5cedcd5440d3dd806bb067978e7c3608" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.2.1", + "parity-scale-codec 3.2.2", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcd47b380d8c4541044e341dcd9475f55ba37ddc50c908d945fc036a8642496" +checksum = "303959cf613a6f6efd19ed4b4ad5bf79966a13352716299ad532cfb115f4205c" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -3787,12 +3747,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys", ] [[package]] @@ -3803,9 +3762,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "scratch" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" +checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" [[package]] name = "scrypt" @@ -3843,29 +3802,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "secp256k1" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff55dc09d460954e9ef2fa8a7ced735a964be9981fd50e870b2b3b0705e14964" -dependencies = [ - "secp256k1-sys", -] - -[[package]] -name = "secp256k1-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" -dependencies = [ - "cc", -] - [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "7c4437699b6d34972de58652c68b98cb5b53a4199ab126db8e20ec8ded29a721" dependencies = [ "bitflags", "core-foundation", @@ -3876,9 +3817,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -3895,9 +3836,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" dependencies = [ "serde", ] @@ -3925,9 +3866,9 @@ checksum = "930c0acf610d3fdb5e2ab6213019aaa04e227ebe9547b0649ba599b16d788bd7" [[package]] name = "serde" -version = "1.0.148" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] @@ -3944,9 +3885,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.148" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -3955,9 +3896,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" dependencies = [ "itoa", "ryu", @@ -3978,9 +3919,9 @@ dependencies = [ [[package]] name = "serde_yaml" -version = "0.9.14" +version = "0.9.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da" +checksum = "8fb06d4b6cdaef0e0c51fa881acb721bed3c924cfaa71d9c94a3b771dfdf6567" dependencies = [ "indexmap", "itoa", @@ -4135,7 +4076,7 @@ dependencies = [ [[package]] name = "ssz-rs" version = "0.8.0" -source = "git+https://github.com/ralexstokes/ssz-rs?rev=cb08f18ca919cc1b685b861d0fa9e2daabe89737#cb08f18ca919cc1b685b861d0fa9e2daabe89737" +source = "git+https://github.com/ralexstokes/ssz-rs?rev=d09f55b4f8554491e3431e01af1c32347a8781cd#d09f55b4f8554491e3431e01af1c32347a8781cd" dependencies = [ "bitvec 1.0.1", "hex", @@ -4150,7 +4091,7 @@ dependencies = [ [[package]] name = "ssz-rs-derive" version = "0.8.0" -source = "git+https://github.com/ralexstokes/ssz-rs?rev=cb08f18ca919cc1b685b861d0fa9e2daabe89737#cb08f18ca919cc1b685b861d0fa9e2daabe89737" +source = "git+https://github.com/ralexstokes/ssz-rs?rev=d09f55b4f8554491e3431e01af1c32347a8781cd#d09f55b4f8554491e3431e01af1c32347a8781cd" dependencies = [ "proc-macro2", "quote", @@ -4212,42 +4153,21 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "unicode-xid", -] - [[package]] name = "tap" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "task-local-extensions" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4167afbec18ae012de40f8cf1b9bf48420abb390678c34821caa07d924941cc4" -dependencies = [ - "tokio", -] - [[package]] name = "tempfile" version = "3.3.0" @@ -4264,9 +4184,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] @@ -4279,18 +4199,18 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", @@ -4306,15 +4226,6 @@ 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.1.45" @@ -4371,9 +4282,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.22.0" +version = "1.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" +checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" dependencies = [ "autocfg", "bytes", @@ -4386,7 +4297,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys", ] [[package]] @@ -4449,13 +4360,30 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" + +[[package]] +name = "toml_edit" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729bfd096e40da9c001f778f5cdecbd2957929a24e10e5883d9392220a751581" +dependencies = [ + "indexmap", + "nom8", + "toml_datetime", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -4579,9 +4507,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "ttf-parser" @@ -4591,9 +4519,9 @@ checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -4645,15 +4573,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" @@ -4684,9 +4612,9 @@ checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" [[package]] name = "unsafe-libyaml" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e5fa573d8ac5f1a856f8d7be41d390ee973daf97c806b2c1a465e4e1406e68" +checksum = "bc7ed8ba44ca06be78ea1ad2c3682a43349126c8818054231ee6f4748012aed2" [[package]] name = "untrusted" @@ -4881,9 +4809,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.22.5" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ "webpki", ] @@ -4894,17 +4822,6 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" -[[package]] -name = "which" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" -dependencies = [ - "either", - "libc", - "once_cell", -] - [[package]] name = "winapi" version = "0.3.9" @@ -4936,19 +4853,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -4956,85 +4860,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" [[package]] name = "winreg" @@ -5104,18 +4978,3 @@ name = "zeroize" version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] diff --git a/Cargo.toml b/Cargo.toml index 5d8db37..e578d2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "helios" -version = "0.1.3" +version = "0.2.0" edition = "2021" autobenches = false @@ -21,11 +21,11 @@ common = { path = "./common" } consensus = { path = "./consensus" } execution = { path = "./execution" } -[dev-dependencies] +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] tokio = { version = "1", features = ["full"] } eyre = "0.6.8" home = "0.5.4" -ethers = "1.0.2" +ethers = "1.0.0" env_logger = "0.9.0" log = "0.4.17" tracing-test = "0.2.3" @@ -34,6 +34,9 @@ plotters = "0.3.3" tempfile = "3.3.0" hex = "0.4.3" +[patch.crates-io] +ethers = { git = "https://github.com/gakonst/ethers-rs", rev = "c17c0c3c956f12d205a5ede3176599d8a30ca739" } + [profile.release] strip = true opt-level = "z" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 3159f7a..478a40c 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -2,7 +2,7 @@ cargo-features = ["different-binary-name"] [package] name = "cli" -version = "0.1.3" +version = "0.2.0" edition = "2021" [[bin]] diff --git a/cli/src/main.rs b/cli/src/main.rs index 270f777..bc8d09d 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -1,5 +1,4 @@ use std::{ - fs, path::PathBuf, process::exit, str::FromStr, @@ -104,10 +103,10 @@ struct Cli { impl Cli { fn as_cli_config(&self) -> CliConfig { - let checkpoint = match &self.checkpoint { - Some(checkpoint) => Some(hex_str_to_bytes(checkpoint).expect("invalid checkpoint")), - None => self.get_cached_checkpoint(), - }; + let checkpoint = self + .checkpoint + .as_ref() + .map(|c| hex_str_to_bytes(c).expect("invalid checkpoint")); CliConfig { checkpoint, @@ -121,21 +120,6 @@ impl Cli { } } - fn get_cached_checkpoint(&self) -> Option> { - let data_dir = self.get_data_dir(); - let checkpoint_file = data_dir.join("checkpoint"); - - if checkpoint_file.exists() { - let checkpoint_res = fs::read(checkpoint_file); - match checkpoint_res { - Ok(checkpoint) => Some(checkpoint), - Err(_) => None, - } - } else { - None - } - } - fn get_data_dir(&self) -> PathBuf { if let Some(dir) = &self.data_dir { PathBuf::from_str(dir).expect("cannot find data dir") diff --git a/client/Cargo.toml b/client/Cargo.toml index 95e91fd..4378611 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,16 +1,14 @@ [package] name = "client" -version = "0.1.3" +version = "0.2.0" edition = "2021" [dependencies] -tokio = { version = "1", features = ["full"] } eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } hex = "0.4.3" -ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.2" -jsonrpsee = { version = "0.15.1", features = ["full"] } +ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "d09f55b4f8554491e3431e01af1c32347a8781cd" } +ethers = "1.0.0" futures = "0.3.23" log = "0.4.17" thiserror = "1.0.37" @@ -19,3 +17,13 @@ common = { path = "../common" } consensus = { path = "../consensus" } execution = { path = "../execution" } config = { path = "../config" } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +jsonrpsee = { version = "0.15.1", features = ["full"] } +tokio = { version = "1", features = ["full"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +gloo-timers = "0.2.6" +wasm-bindgen-futures = "0.4.33" +tokio = { version = "1", features = ["sync"] } + diff --git a/client/src/client.rs b/client/src/client.rs index f80e6ad..4cc7d45 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1,4 +1,3 @@ -use std::path::PathBuf; use std::sync::Arc; use config::networks::Network; @@ -12,13 +11,25 @@ use config::{CheckpointFallback, Config}; use consensus::{types::Header, ConsensusClient}; use execution::types::{CallOpts, ExecutionBlock}; use log::{error, info, warn}; -use tokio::spawn; use tokio::sync::RwLock; + +#[cfg(not(target_arch = "wasm32"))] +use std::path::PathBuf; +#[cfg(not(target_arch = "wasm32"))] +use tokio::spawn; +#[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; -use crate::database::{Database, FileDB}; +#[cfg(target_arch = "wasm32")] +use gloo_timers::callback::Interval; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_futures::spawn_local; + +use crate::database::Database; use crate::errors::NodeError; use crate::node::Node; + +#[cfg(not(target_arch = "wasm32"))] use crate::rpc::Rpc; #[derive(Default)] @@ -27,7 +38,9 @@ pub struct ClientBuilder { consensus_rpc: Option, execution_rpc: Option, checkpoint: Option>, + #[cfg(not(target_arch = "wasm32"))] rpc_port: Option, + #[cfg(not(target_arch = "wasm32"))] data_dir: Option, config: Option, fallback: Option, @@ -62,11 +75,13 @@ impl ClientBuilder { self } + #[cfg(not(target_arch = "wasm32"))] pub fn rpc_port(mut self, port: u16) -> Self { self.rpc_port = Some(port); self } + #[cfg(not(target_arch = "wasm32"))] pub fn data_dir(mut self, data_dir: PathBuf) -> Self { self.data_dir = Some(data_dir); self @@ -92,7 +107,7 @@ impl ClientBuilder { self } - pub fn build(self) -> Result> { + pub fn build(self) -> Result> { let base_config = if let Some(network) = self.network { network.to_base_config() } else { @@ -127,6 +142,7 @@ impl ClientBuilder { base_config.checkpoint }; + #[cfg(not(target_arch = "wasm32"))] let rpc_port = if self.rpc_port.is_some() { self.rpc_port } else if let Some(config) = &self.config { @@ -135,6 +151,7 @@ impl ClientBuilder { None }; + #[cfg(not(target_arch = "wasm32"))] let data_dir = if self.data_dir.is_some() { self.data_dir } else if let Some(config) = &self.config { @@ -167,8 +184,14 @@ impl ClientBuilder { consensus_rpc, execution_rpc, checkpoint, + #[cfg(not(target_arch = "wasm32"))] rpc_port, + #[cfg(target_arch = "wasm32")] + rpc_port: None, + #[cfg(not(target_arch = "wasm32"))] data_dir, + #[cfg(target_arch = "wasm32")] + data_dir: None, chain: base_config.chain, forks: base_config.forks, max_checkpoint_age: base_config.max_checkpoint_age, @@ -183,35 +206,38 @@ impl ClientBuilder { pub struct Client { node: Arc>, + #[cfg(not(target_arch = "wasm32"))] rpc: Option, - db: Option, + db: DB, fallback: Option, load_external_fallback: bool, } -impl Client { - fn new(config: Config) -> Result { +impl Client { + fn new(mut config: Config) -> Result { + let db = DB::new(&config)?; + let checkpoint = db.load_checkpoint()?; + config.checkpoint = checkpoint; + let config = Arc::new(config); let node = Node::new(config.clone())?; let node = Arc::new(RwLock::new(node)); + #[cfg(not(target_arch = "wasm32"))] let rpc = config.rpc_port.map(|port| Rpc::new(node.clone(), port)); - let data_dir = config.data_dir.clone(); - let db = data_dir.map(FileDB::new); - Ok(Client { node, + #[cfg(not(target_arch = "wasm32"))] rpc, db, fallback: config.fallback.clone(), load_external_fallback: config.load_external_fallback, }) } -} -impl Client { pub async fn start(&mut self) -> Result<()> { + #[cfg(not(target_arch = "wasm32"))] if let Some(rpc) = &mut self.rpc { rpc.start().await?; } @@ -241,6 +267,13 @@ impl Client { } } + self.start_advance_thread(); + + Ok(()) + } + + #[cfg(not(target_arch = "wasm32"))] + fn start_advance_thread(&self) { let node = self.node.clone(); spawn(async move { loop { @@ -250,11 +283,25 @@ impl Client { } let next_update = node.read().await.duration_until_next_update(); + sleep(next_update).await; } }); + } - Ok(()) + #[cfg(target_arch = "wasm32")] + fn start_advance_thread(&self) { + let node = self.node.clone(); + Interval::new(12000, move || { + let node = node.clone(); + spawn_local(async move { + let res = node.write().await.advance().await; + if let Err(err) = res { + warn!("consensus error: {}", err); + } + }); + }) + .forget(); } async fn boot_from_fallback(&self) -> eyre::Result<()> { @@ -335,8 +382,8 @@ impl Client { }; info!("saving last checkpoint hash"); - let res = self.db.as_ref().map(|db| db.save_checkpoint(checkpoint)); - if res.is_some() && res.unwrap().is_err() { + let res = self.db.save_checkpoint(checkpoint); + if res.is_err() { warn!("checkpoint save failed"); } } diff --git a/client/src/database.rs b/client/src/database.rs index 3736f93..864cff8 100644 --- a/client/src/database.rs +++ b/client/src/database.rs @@ -1,27 +1,40 @@ +#[cfg(not(target_arch = "wasm32"))] use std::{ fs, io::{Read, Write}, path::PathBuf, }; +use config::Config; use eyre::Result; pub trait Database { + fn new(config: &Config) -> Result + where + Self: Sized; fn save_checkpoint(&self, checkpoint: Vec) -> Result<()>; fn load_checkpoint(&self) -> Result>; } +#[cfg(not(target_arch = "wasm32"))] pub struct FileDB { data_dir: PathBuf, + default_checkpoint: Vec, } -impl FileDB { - pub fn new(data_dir: PathBuf) -> Self { - FileDB { data_dir } - } -} - +#[cfg(not(target_arch = "wasm32"))] impl Database for FileDB { + fn new(config: &Config) -> Result { + if let Some(data_dir) = &config.data_dir { + return Ok(FileDB { + data_dir: data_dir.to_path_buf(), + default_checkpoint: config.checkpoint.clone(), + }); + } + + eyre::bail!("data dir not in config") + } + fn save_checkpoint(&self, checkpoint: Vec) -> Result<()> { fs::create_dir_all(&self.data_dir)?; @@ -44,6 +57,30 @@ impl Database for FileDB { let mut buf = Vec::new(); f.read_to_end(&mut buf)?; - Ok(buf) + if buf.len() == 32 { + Ok(buf) + } else { + Ok(self.default_checkpoint.clone()) + } + } +} + +pub struct ConfigDB { + checkpoint: Vec, +} + +impl Database for ConfigDB { + fn new(config: &Config) -> Result { + Ok(Self { + checkpoint: config.checkpoint.clone(), + }) + } + + fn load_checkpoint(&self) -> Result> { + Ok(self.checkpoint.clone()) + } + + fn save_checkpoint(&self, _checkpoint: Vec) -> Result<()> { + Ok(()) } } diff --git a/client/src/errors.rs b/client/src/errors.rs index 39a6679..f3226cc 100644 --- a/client/src/errors.rs +++ b/client/src/errors.rs @@ -37,6 +37,7 @@ pub enum NodeError { BlockNotFoundError(#[from] BlockNotFoundError), } +#[cfg(not(target_arch = "wasm32"))] impl NodeError { pub fn to_json_rpsee_error(self) -> jsonrpsee::core::Error { match self { diff --git a/client/src/lib.rs b/client/src/lib.rs index 99729fc..5aa1bf2 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -3,6 +3,8 @@ pub use crate::client::*; pub mod database; pub mod errors; + +#[cfg(not(target_arch = "wasm32"))] pub mod rpc; -mod node; +pub mod node; diff --git a/common/Cargo.toml b/common/Cargo.toml index 82f5a5f..deacb9b 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "common" -version = "0.1.3" +version = "0.2.0" edition = "2021" [dependencies] eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } hex = "0.4.3" -ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.2" +ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "d09f55b4f8554491e3431e01af1c32347a8781cd" } +ethers = "1.0.0" thiserror = "1.0.37" diff --git a/config/Cargo.toml b/config/Cargo.toml index ba17647..eee5ef3 100644 --- a/config/Cargo.toml +++ b/config/Cargo.toml @@ -1,24 +1,24 @@ [package] name = "config" -version = "0.1.3" +version = "0.2.0" edition = "2021" [dependencies] -tokio = { version = "1", features = ["full"] } eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } hex = "0.4.3" -ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.2" +ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "d09f55b4f8554491e3431e01af1c32347a8781cd" } +ethers = "1.0.0" figment = { version = "0.10.7", features = ["toml", "env"] } thiserror = "1.0.37" log = "0.4.17" - -common = { path = "../common" } reqwest = "0.11.13" serde_yaml = "0.9.14" strum = "0.24.1" futures = "0.3.25" +common = { path = "../common" } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio = { version = "1", features = ["full"] } diff --git a/config/src/checkpoints.rs b/config/src/checkpoints.rs index 65fe45a..35a73be 100644 --- a/config/src/checkpoints.rs +++ b/config/src/checkpoints.rs @@ -136,26 +136,25 @@ impl CheckpointFallback { // Iterate over all mainnet checkpoint sync services and get the latest checkpoint slot for each. let tasks: Vec<_> = services .iter() - .map(|service| { + .map(|service| async move { let service = service.clone(); - tokio::spawn(async move { - match Self::query_service(&service.endpoint).await { - Some(raw) => { - if raw.data.slots.is_empty() { - return Err(eyre::eyre!("no slots")); - } - Ok(raw.data.slots[0].clone()) + match Self::query_service(&service.endpoint).await { + Some(raw) => { + if raw.data.slots.is_empty() { + return Err(eyre::eyre!("no slots")); } - None => Err(eyre::eyre!("failed to query service")), + Ok(raw.data.slots[0].clone()) } - }) + None => Err(eyre::eyre!("failed to query service")), + } }) .collect(); + let slots = futures::future::join_all(tasks) .await .iter() .filter_map(|slot| match &slot { - Ok(Ok(s)) => Some(s.clone()), + Ok(s) => Some(s.clone()), _ => None, }) .collect::>(); diff --git a/config/src/networks.rs b/config/src/networks.rs index 752a0ee..72d8bde 100644 --- a/config/src/networks.rs +++ b/config/src/networks.rs @@ -36,7 +36,7 @@ impl Network { pub fn mainnet() -> BaseConfig { BaseConfig { checkpoint: hex_str_to_bytes( - "0x428ce0b5f5bbed1fc2b3feb5d4152ae0fe98a80b1bfa8de36681868e81e9222a", + "0x766647f3c4e1fc91c0db9a9374032ae038778411fbff222974e11f2e3ce7dadf", ) .unwrap(), rpc_port: 8545, diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 2c8b700..41e1a1c 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -1,27 +1,31 @@ [package] name = "consensus" -version = "0.1.3" +version = "0.2.0" edition = "2021" [dependencies] -tokio = { version = "1", features = ["full"] } eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.85" hex = "0.4.3" -ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -blst = "0.3.10" -ethers = "1.0.2" +ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "d09f55b4f8554491e3431e01af1c32347a8781cd" } +milagro_bls = { git = "https://github.com/Snowfork/milagro_bls" } +ethers = "1.0.0" bytes = "1.2.1" toml = "0.5.9" async-trait = "0.1.57" log = "0.4.17" chrono = "0.4.22" thiserror = "1.0.37" -openssl = { version = "0.10", features = ["vendored"] } -reqwest = { version = "0.11.12", features = ["json"] } -reqwest-middleware = "0.1.6" -reqwest-retry = "0.1.5" +reqwest = { version = "0.11.13", features = ["json"] } common = { path = "../common" } config = { path = "../config" } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +openssl = { version = "0.10", features = ["vendored"] } +tokio = { version = "1", features = ["full"] } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-timer = "0.2.5" + diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index b29905b..86c60a1 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -1,13 +1,12 @@ use std::cmp; use std::sync::Arc; -use std::time::UNIX_EPOCH; -use blst::min_pk::PublicKey; use chrono::Duration; use eyre::eyre; use eyre::Result; use log::warn; use log::{debug, info}; +use milagro_bls::PublicKey; use ssz_rs::prelude::*; use common::types::*; @@ -21,9 +20,20 @@ use super::rpc::ConsensusRpc; use super::types::*; use super::utils::*; +#[cfg(not(target_arch = "wasm32"))] +use std::time::SystemTime; +#[cfg(not(target_arch = "wasm32"))] +use std::time::UNIX_EPOCH; + +#[cfg(target_arch = "wasm32")] +use wasm_timer::SystemTime; +#[cfg(target_arch = "wasm32")] +use wasm_timer::UNIX_EPOCH; + // https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md // does not implement force updates +#[derive(Debug)] pub struct ConsensusClient { rpc: R, store: LightClientStore, @@ -480,18 +490,13 @@ impl ConsensusClient { fn age(&self, slot: u64) -> Duration { let expected_time = self.slot_timestamp(slot); - let now = std::time::SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap(); + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); let delay = now - std::time::Duration::from_secs(expected_time); chrono::Duration::from_std(delay).unwrap() } pub fn expected_current_slot(&self) -> u64 { - let now = std::time::SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap(); - + let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); let genesis_time = self.config.chain.genesis_time; let since_genesis = now - std::time::Duration::from_secs(genesis_time); @@ -509,7 +514,7 @@ impl ConsensusClient { let next_slot = current_slot + 1; let next_slot_timestamp = self.slot_timestamp(next_slot); - let now = std::time::SystemTime::now() + let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(); @@ -540,7 +545,7 @@ fn get_participating_keys( bitfield.iter().enumerate().for_each(|(i, bit)| { if bit == true { let pk = &committee.pubkeys[i]; - let pk = PublicKey::from_bytes(pk).unwrap(); + let pk = PublicKey::from_bytes_unchecked(pk).unwrap(); pks.push(pk); } }); diff --git a/consensus/src/rpc/mock_rpc.rs b/consensus/src/rpc/mock_rpc.rs index f4ac130..a887410 100644 --- a/consensus/src/rpc/mock_rpc.rs +++ b/consensus/src/rpc/mock_rpc.rs @@ -8,7 +8,8 @@ pub struct MockRpc { testdata: PathBuf, } -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl ConsensusRpc for MockRpc { fn new(path: &str) -> Self { MockRpc { diff --git a/consensus/src/rpc/mod.rs b/consensus/src/rpc/mod.rs index 9dc8874..03f46dd 100644 --- a/consensus/src/rpc/mod.rs +++ b/consensus/src/rpc/mod.rs @@ -7,7 +7,8 @@ use eyre::Result; use crate::types::{BeaconBlock, Bootstrap, FinalityUpdate, OptimisticUpdate, Update}; // implements https://github.com/ethereum/beacon-APIs/tree/master/apis/beacon/light_client -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] pub trait ConsensusRpc { fn new(path: &str) -> Self; async fn get_bootstrap(&self, block_root: &'_ [u8]) -> Result; diff --git a/consensus/src/rpc/nimbus_rpc.rs b/consensus/src/rpc/nimbus_rpc.rs index e4006fa..e0548fb 100644 --- a/consensus/src/rpc/nimbus_rpc.rs +++ b/consensus/src/rpc/nimbus_rpc.rs @@ -1,7 +1,5 @@ use async_trait::async_trait; use eyre::Result; -use reqwest_middleware::{ClientBuilder, ClientWithMiddleware}; -use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware}; use std::cmp; use super::ConsensusRpc; @@ -9,25 +7,17 @@ use crate::constants::MAX_REQUEST_LIGHT_CLIENT_UPDATES; use crate::types::*; use common::errors::RpcError; +#[derive(Debug)] pub struct NimbusRpc { rpc: String, - client: ClientWithMiddleware, } -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl ConsensusRpc for NimbusRpc { fn new(rpc: &str) -> Self { - let retry_policy = ExponentialBackoff::builder() - .backoff_exponent(1) - .build_with_max_retries(3); - - let client = ClientBuilder::new(reqwest::Client::new()) - .with(RetryTransientMiddleware::new_with_policy(retry_policy)) - .build(); - NimbusRpc { rpc: rpc.to_string(), - client, } } @@ -38,8 +28,8 @@ impl ConsensusRpc for NimbusRpc { self.rpc, root_hex ); - let res = self - .client + let client = reqwest::Client::new(); + let res = client .get(req) .send() .await @@ -58,8 +48,8 @@ impl ConsensusRpc for NimbusRpc { self.rpc, period, count ); - let res = self - .client + let client = reqwest::Client::new(); + let res = client .get(req) .send() .await @@ -73,10 +63,7 @@ impl ConsensusRpc for NimbusRpc { async fn get_finality_update(&self) -> Result { let req = format!("{}/eth/v1/beacon/light_client/finality_update", self.rpc); - let res = self - .client - .get(req) - .send() + let res = reqwest::get(req) .await .map_err(|e| RpcError::new("finality_update", e))? .json::() @@ -88,10 +75,7 @@ impl ConsensusRpc for NimbusRpc { async fn get_optimistic_update(&self) -> Result { let req = format!("{}/eth/v1/beacon/light_client/optimistic_update", self.rpc); - let res = self - .client - .get(req) - .send() + let res = reqwest::get(req) .await .map_err(|e| RpcError::new("optimistic_update", e))? .json::() @@ -103,10 +87,7 @@ impl ConsensusRpc for NimbusRpc { async fn get_block(&self, slot: u64) -> Result { let req = format!("{}/eth/v2/beacon/blocks/{}", self.rpc, slot); - let res = self - .client - .get(req) - .send() + let res = reqwest::get(req) .await .map_err(|e| RpcError::new("blocks", e))? .json::() @@ -118,10 +99,7 @@ impl ConsensusRpc for NimbusRpc { async fn chain_id(&self) -> Result { let req = format!("{}/eth/v1/config/spec", self.rpc); - let res = self - .client - .get(req) - .send() + let res = reqwest::get(req) .await .map_err(|e| RpcError::new("spec", e))? .json::() diff --git a/consensus/src/utils.rs b/consensus/src/utils.rs index 92dffed..2369fe2 100644 --- a/consensus/src/utils.rs +++ b/consensus/src/utils.rs @@ -1,9 +1,6 @@ -use blst::{ - min_pk::{PublicKey, Signature}, - BLST_ERROR, -}; use common::{types::Bytes32, utils::bytes32_to_node}; use eyre::Result; +use milagro_bls::{AggregateSignature, PublicKey}; use ssz_rs::prelude::*; use crate::types::{Header, SignatureBytes}; @@ -14,10 +11,9 @@ pub fn calc_sync_period(slot: u64) -> u64 { } pub fn is_aggregate_valid(sig_bytes: &SignatureBytes, msg: &[u8], pks: &[&PublicKey]) -> bool { - let dst: &[u8] = b"BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_"; - let sig_res = Signature::from_bytes(sig_bytes); + let sig_res = AggregateSignature::from_bytes(sig_bytes); match sig_res { - Ok(sig) => sig.fast_aggregate_verify(true, msg, dst, pks) == BLST_ERROR::BLST_SUCCESS, + Ok(sig) => sig.fast_aggregate_verify(msg, pks), Err(_) => false, } } diff --git a/examples/basic.rs b/examples/basic.rs index 1c4d5ce..8958f00 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use env_logger::Env; use ethers::{types::Address, utils}; use eyre::Result; -use helios::{client::ClientBuilder, config::networks::Network, types::BlockTag}; +use helios::{config::networks::Network, prelude::*}; #[tokio::main] async fn main() -> Result<()> { @@ -15,12 +15,13 @@ async fn main() -> Result<()> { let consensus_rpc = "https://www.lightclientdata.org"; log::info!("Using consensus RPC URL: {}", consensus_rpc); - let mut client = ClientBuilder::new() + let mut client: Client = ClientBuilder::new() .network(Network::MAINNET) .consensus_rpc(consensus_rpc) .execution_rpc(untrusted_rpc_url) .load_external_fallback() .build()?; + log::info!( "Built client on network \"{}\" with external checkpoint fallbacks", Network::MAINNET diff --git a/examples/client.rs b/examples/client.rs index cbd3013..3914408 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -35,7 +35,7 @@ async fn main() -> Result<()> { builder = builder.load_external_fallback(); // Build the client - let _client = builder.build().unwrap(); + let _client: Client = builder.build().unwrap(); println!("Constructed client!"); Ok(()) diff --git a/execution/Cargo.toml b/execution/Cargo.toml index b0c46e5..cbe6eb8 100644 --- a/execution/Cargo.toml +++ b/execution/Cargo.toml @@ -1,18 +1,17 @@ [package] name = "execution" -version = "0.1.3" +version = "0.2.0" edition = "2021" [dependencies] reqwest = { version = "0.11", features = ["json"] } -tokio = { version = "1", features = ["full"] } eyre = "0.6.8" serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.85" hex = "0.4.3" -ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "cb08f18ca919cc1b685b861d0fa9e2daabe89737" } -ethers = "1.0.2" -revm = "2.1.0" +ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", rev = "d09f55b4f8554491e3431e01af1c32347a8781cd" } +revm = { version = "2.3", default-features = false, features = ["std", "k256", "with-serde"] } +ethers = "1.0.0" bytes = "1.2.1" futures = "0.3.23" toml = "0.5.9" @@ -20,7 +19,10 @@ triehash-ethereum = { git = "https://github.com/openethereum/parity-ethereum", r async-trait = "0.1.57" log = "0.4.17" thiserror = "1.0.37" -openssl = { version = "0.10", features = ["vendored"] } common = { path = "../common" } consensus = { path = "../consensus" } + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +openssl = { version = "0.10", features = ["vendored"] } +tokio = { version = "1", features = ["full"] } diff --git a/execution/src/evm.rs b/execution/src/evm.rs index f25ce69..33095fa 100644 --- a/execution/src/evm.rs +++ b/execution/src/evm.rs @@ -9,14 +9,13 @@ use bytes::Bytes; use common::{errors::BlockNotFoundError, types::BlockTag}; use ethers::{ abi::ethereum_types::BigEndianHash, - prelude::{Address, H160, H256, U256}, types::transaction::eip2930::AccessListItem, + types::{Address, H160, H256, U256}, }; use eyre::{Report, Result}; -use futures::future::join_all; +use futures::{executor::block_on, future::join_all}; use log::trace; use revm::{AccountInfo, Bytecode, Database, Env, TransactOut, TransactTo, EVM}; -use tokio::runtime::Runtime; use consensus::types::ExecutionPayload; @@ -225,8 +224,9 @@ impl<'a, R: ExecutionRpc> ProofDB<'a, R> { let handle = thread::spawn(move || { let account_fut = execution.get_account(&address, Some(&slots), &payload); - let runtime = Runtime::new()?; - runtime.block_on(account_fut) + // let runtime = Runtime::new()?; + // runtime.block_on(account_fut) + block_on(account_fut) }); handle.join().unwrap() diff --git a/execution/src/rpc/http_rpc.rs b/execution/src/rpc/http_rpc.rs index 05e4342..cc48953 100644 --- a/execution/src/rpc/http_rpc.rs +++ b/execution/src/rpc/http_rpc.rs @@ -27,13 +27,16 @@ impl Clone for HttpRpc { } } -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl ExecutionRpc for HttpRpc { fn new(rpc: &str) -> Result { let http = Http::from_str(rpc)?; let mut client = RetryClient::new(http, Box::new(HttpRateLimitRetryPolicy), 100, 50); client.set_compute_units(300); + let provider = Provider::new(client); + Ok(HttpRpc { url: rpc.to_string(), provider, diff --git a/execution/src/rpc/mock_rpc.rs b/execution/src/rpc/mock_rpc.rs index 3a4fd1e..e7ede3c 100644 --- a/execution/src/rpc/mock_rpc.rs +++ b/execution/src/rpc/mock_rpc.rs @@ -17,7 +17,8 @@ pub struct MockRpc { path: PathBuf, } -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] impl ExecutionRpc for MockRpc { fn new(rpc: &str) -> Result { let path = PathBuf::from(rpc); diff --git a/execution/src/rpc/mod.rs b/execution/src/rpc/mod.rs index 0c1b799..f2157a8 100644 --- a/execution/src/rpc/mod.rs +++ b/execution/src/rpc/mod.rs @@ -10,7 +10,8 @@ use crate::types::CallOpts; pub mod http_rpc; pub mod mock_rpc; -#[async_trait] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] pub trait ExecutionRpc: Send + Clone + Sync + 'static { fn new(rpc: &str) -> Result where From 5b9e90436ab808dcde4fabd91186a4985a3e2bfd Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Tue, 31 Jan 2023 14:18:51 -0500 Subject: [PATCH 27/44] fix: check checkpoint file exists (#183) --- Cargo.lock | 14 +++++++------- client/src/database.rs | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 999c748..2f4c8dc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -525,7 +525,7 @@ dependencies = [ [[package]] name = "cli" -version = "0.1.3" +version = "0.2.0" dependencies = [ "clap", "client", @@ -542,7 +542,7 @@ dependencies = [ [[package]] name = "client" -version = "0.1.3" +version = "0.2.0" dependencies = [ "common", "config", @@ -646,7 +646,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "common" -version = "0.1.3" +version = "0.2.0" dependencies = [ "ethers", "eyre", @@ -658,7 +658,7 @@ dependencies = [ [[package]] name = "config" -version = "0.1.3" +version = "0.2.0" dependencies = [ "common", "ethers", @@ -678,7 +678,7 @@ dependencies = [ [[package]] name = "consensus" -version = "0.1.3" +version = "0.2.0" dependencies = [ "async-trait", "bytes", @@ -1451,7 +1451,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "execution" -version = "0.1.3" +version = "0.2.0" dependencies = [ "async-trait", "bytes", @@ -1964,7 +1964,7 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "helios" -version = "0.1.3" +version = "0.2.0" dependencies = [ "client", "common", diff --git a/client/src/database.rs b/client/src/database.rs index 864cff8..43186c9 100644 --- a/client/src/database.rs +++ b/client/src/database.rs @@ -50,14 +50,14 @@ impl Database for FileDB { } fn load_checkpoint(&self) -> Result> { - let mut f = fs::OpenOptions::new() - .read(true) - .open(self.data_dir.join("checkpoint"))?; - let mut buf = Vec::new(); - f.read_to_end(&mut buf)?; - if buf.len() == 32 { + let res = fs::OpenOptions::new() + .read(true) + .open(self.data_dir.join("checkpoint")) + .map(|mut f| f.read_to_end(&mut buf)); + + if buf.len() == 32 && res.is_ok() { Ok(buf) } else { Ok(self.default_checkpoint.clone()) From 6b662f903bbb09c153a7b5a99b50d77a9d4afe00 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Tue, 31 Jan 2023 18:23:55 -0500 Subject: [PATCH 28/44] fix: benches (#184) --- benches/file_db.rs | 20 ++++++++++++++------ benches/harness.rs | 14 +++++++------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/benches/file_db.rs b/benches/file_db.rs index 6d0baec..6f5e65a 100644 --- a/benches/file_db.rs +++ b/benches/file_db.rs @@ -1,4 +1,5 @@ use client::database::Database; +use config::Config; use criterion::{criterion_group, criterion_main, Criterion}; use helios::prelude::FileDB; use tempfile::tempdir; @@ -17,8 +18,12 @@ pub fn save_checkpoint(c: &mut Criterion) { c.bench_function("save_checkpoint", |b| { let checkpoint = vec![1, 2, 3]; b.iter(|| { - let temp_dir = tempdir().unwrap().into_path(); - let db = FileDB::new(temp_dir); + let data_dir = Some(tempdir().unwrap().into_path()); + let config = Config { + data_dir, + ..Default::default() + }; + let db = FileDB::new(&config).unwrap(); db.save_checkpoint(checkpoint.clone()).unwrap(); }) }); @@ -28,14 +33,17 @@ pub fn save_checkpoint(c: &mut Criterion) { pub fn load_checkpoint(c: &mut Criterion) { c.bench_function("load_checkpoint", |b| { // First write to the db - let temp_dir = tempdir().unwrap().into_path(); - let db = FileDB::new(temp_dir.clone()); - let written_checkpoint = vec![1, 2, 3]; + let data_dir = Some(tempdir().unwrap().into_path()); + let config = Config { + data_dir, + ..Default::default() + }; + let db = FileDB::new(&config).unwrap(); + let written_checkpoint = vec![1; 32]; db.save_checkpoint(written_checkpoint.clone()).unwrap(); // Then read from the db b.iter(|| { - let db = FileDB::new(temp_dir.clone()); let checkpoint = db.load_checkpoint().unwrap(); assert_eq!(checkpoint, written_checkpoint.clone()); }) diff --git a/benches/harness.rs b/benches/harness.rs index 1f9b069..4fb463b 100644 --- a/benches/harness.rs +++ b/benches/harness.rs @@ -2,12 +2,12 @@ use std::{str::FromStr, sync::Arc}; -use ::client::Client; +use ::client::{database::ConfigDB, Client}; use ethers::{ abi::Address, types::{H256, U256}, }; -use helios::{client, config::networks, prelude::FileDB, types::BlockTag}; +use helios::{client, config::networks, types::BlockTag}; /// Fetches the latest mainnet checkpoint from the fallback service. /// @@ -29,11 +29,11 @@ pub async fn fetch_mainnet_checkpoint() -> eyre::Result { /// The client will use `https://www.lightclientdata.org` as the consensus RPC. pub fn construct_mainnet_client( rt: &tokio::runtime::Runtime, -) -> eyre::Result> { +) -> eyre::Result> { rt.block_on(inner_construct_mainnet_client()) } -pub async fn inner_construct_mainnet_client() -> eyre::Result> { +pub async fn inner_construct_mainnet_client() -> eyre::Result> { let benchmark_rpc_url = std::env::var("MAINNET_RPC_URL")?; let mut client = client::ClientBuilder::new() .network(networks::Network::MAINNET) @@ -47,7 +47,7 @@ pub async fn inner_construct_mainnet_client() -> eyre::Result eyre::Result> { +) -> eyre::Result> { let benchmark_rpc_url = std::env::var("MAINNET_RPC_URL")?; let mut client = client::ClientBuilder::new() .network(networks::Network::MAINNET) @@ -79,7 +79,7 @@ pub fn construct_runtime() -> tokio::runtime::Runtime { /// The client will use `http://testing.prater.beacon-api.nimbus.team` as the consensus RPC. pub fn construct_goerli_client( rt: &tokio::runtime::Runtime, -) -> eyre::Result> { +) -> eyre::Result> { rt.block_on(async { let benchmark_rpc_url = std::env::var("GOERLI_RPC_URL")?; let mut client = client::ClientBuilder::new() @@ -96,7 +96,7 @@ pub fn construct_goerli_client( /// Gets the balance of the given address on mainnet. pub fn get_balance( rt: &tokio::runtime::Runtime, - client: Arc>, + client: Arc>, address: &str, ) -> eyre::Result { rt.block_on(async { From 7b7dc708f8c3f9bac43ae415387cb7bc78642dea Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Tue, 31 Jan 2023 18:40:53 -0500 Subject: [PATCH 29/44] fix: check checkpoint block root exists (#185) * fix: check checkpoint block root is some * remove print * check block root earlier --- config/src/checkpoints.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/config/src/checkpoints.rs b/config/src/checkpoints.rs index 35a73be..210838a 100644 --- a/config/src/checkpoints.rs +++ b/config/src/checkpoints.rs @@ -157,6 +157,7 @@ impl CheckpointFallback { Ok(s) => Some(s.clone()), _ => None, }) + .filter(|s| s.block_root.is_some()) .collect::>(); // Get the max epoch From 1fa2dede25e4cae8b4f6d80285b06743ef721ee9 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 1 Feb 2023 13:40:11 -0500 Subject: [PATCH 30/44] fix: add data dir to basic example (#186) --- examples/basic.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/basic.rs b/examples/basic.rs index 8958f00..2b076b2 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,4 +1,4 @@ -use std::str::FromStr; +use std::{path::PathBuf, str::FromStr}; use env_logger::Env; use ethers::{types::Address, utils}; @@ -20,6 +20,7 @@ async fn main() -> Result<()> { .consensus_rpc(consensus_rpc) .execution_rpc(untrusted_rpc_url) .load_external_fallback() + .data_dir(PathBuf::from("/tmp/helios")) .build()?; log::info!( From 4a84ecabedd30a4a36398609a4a5d9d49f398a9c Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 1 Feb 2023 17:10:26 -0500 Subject: [PATCH 31/44] fix: handle checkpoint overrides correctly (#187) * fix: handle checkpoint overrides correctly * fix optional deserialize * clippy * fmt --- client/src/client.rs | 27 ++++++++++++++++++++++----- client/src/database.rs | 7 +++++-- client/src/node.rs | 2 +- config/src/base.rs | 2 +- config/src/config.rs | 18 +++++++++--------- config/src/networks.rs | 4 ++-- config/src/utils.rs | 12 ++++++++++++ 7 files changed, 52 insertions(+), 20 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 4cc7d45..1095dda 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -135,11 +135,17 @@ impl ClientBuilder { }); let checkpoint = if let Some(checkpoint) = self.checkpoint { - checkpoint + Some(checkpoint) } else if let Some(config) = &self.config { config.checkpoint.clone() } else { - base_config.checkpoint + None + }; + + let default_checkpoint = if let Some(config) = &self.config { + config.default_checkpoint.clone() + } else { + base_config.default_checkpoint.clone() }; #[cfg(not(target_arch = "wasm32"))] @@ -184,6 +190,7 @@ impl ClientBuilder { consensus_rpc, execution_rpc, checkpoint, + default_checkpoint, #[cfg(not(target_arch = "wasm32"))] rpc_port, #[cfg(target_arch = "wasm32")] @@ -216,8 +223,10 @@ pub struct Client { impl Client { fn new(mut config: Config) -> Result { let db = DB::new(&config)?; - let checkpoint = db.load_checkpoint()?; - config.checkpoint = checkpoint; + if config.checkpoint.is_none() { + let checkpoint = db.load_checkpoint()?; + config.checkpoint = Some(checkpoint); + } let config = Arc::new(config); let node = Node::new(config.clone())?; @@ -250,7 +259,15 @@ impl Client { ConsensusError::CheckpointTooOld => { warn!( "failed to sync consensus node with checkpoint: 0x{}", - hex::encode(&self.node.read().await.config.checkpoint), + hex::encode( + self.node + .read() + .await + .config + .checkpoint + .clone() + .unwrap_or_default() + ), ); let fallback = self.boot_from_fallback().await; diff --git a/client/src/database.rs b/client/src/database.rs index 43186c9..335ebc8 100644 --- a/client/src/database.rs +++ b/client/src/database.rs @@ -28,7 +28,7 @@ impl Database for FileDB { if let Some(data_dir) = &config.data_dir { return Ok(FileDB { data_dir: data_dir.to_path_buf(), - default_checkpoint: config.checkpoint.clone(), + default_checkpoint: config.default_checkpoint.clone(), }); } @@ -72,7 +72,10 @@ pub struct ConfigDB { impl Database for ConfigDB { fn new(config: &Config) -> Result { Ok(Self { - checkpoint: config.checkpoint.clone(), + checkpoint: config + .checkpoint + .clone() + .unwrap_or(config.default_checkpoint.clone()), }) } diff --git a/client/src/node.rs b/client/src/node.rs index 5b1dd3b..93d6b41 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -31,7 +31,7 @@ pub struct Node { impl Node { pub fn new(config: Arc) -> Result { let consensus_rpc = &config.consensus_rpc; - let checkpoint_hash = &config.checkpoint; + let checkpoint_hash = &config.checkpoint.as_ref().unwrap(); let execution_rpc = &config.execution_rpc; let consensus = ConsensusClient::new(consensus_rpc, checkpoint_hash, config.clone()) diff --git a/config/src/base.rs b/config/src/base.rs index e89f08a..2ab2c32 100644 --- a/config/src/base.rs +++ b/config/src/base.rs @@ -12,7 +12,7 @@ pub struct BaseConfig { deserialize_with = "bytes_deserialize", serialize_with = "bytes_serialize" )] - pub checkpoint: Vec, + pub default_checkpoint: Vec, pub chain: ChainConfig, pub forks: Forks, pub max_checkpoint_age: u64, diff --git a/config/src/config.rs b/config/src/config.rs index c19aee6..990cbf4 100644 --- a/config/src/config.rs +++ b/config/src/config.rs @@ -2,25 +2,25 @@ use figment::{ providers::{Format, Serialized, Toml}, Figment, }; -use serde::{Deserialize, Serialize}; +use serde::Deserialize; use std::{path::PathBuf, process::exit}; use crate::base::BaseConfig; use crate::cli::CliConfig; use crate::networks; use crate::types::{ChainConfig, Forks}; -use crate::utils::{bytes_deserialize, bytes_serialize}; +use crate::utils::{bytes_deserialize, bytes_opt_deserialize}; -#[derive(Serialize, Deserialize, Debug, Default)] +#[derive(Deserialize, Debug, Default)] pub struct Config { pub consensus_rpc: String, pub execution_rpc: String, pub rpc_port: Option, - #[serde( - deserialize_with = "bytes_deserialize", - serialize_with = "bytes_serialize" - )] - pub checkpoint: Vec, + #[serde(deserialize_with = "bytes_deserialize")] + pub default_checkpoint: Vec, + #[serde(default)] + #[serde(deserialize_with = "bytes_opt_deserialize")] + pub checkpoint: Option>, pub data_dir: Option, pub chain: ChainConfig, pub forks: Forks, @@ -86,7 +86,7 @@ impl Config { BaseConfig { rpc_port: self.rpc_port.unwrap_or(8545), consensus_rpc: Some(self.consensus_rpc.clone()), - checkpoint: self.checkpoint.clone(), + default_checkpoint: self.default_checkpoint.clone(), chain: self.chain.clone(), forks: self.forks.clone(), max_checkpoint_age: self.max_checkpoint_age, diff --git a/config/src/networks.rs b/config/src/networks.rs index 72d8bde..ebe4f9e 100644 --- a/config/src/networks.rs +++ b/config/src/networks.rs @@ -35,7 +35,7 @@ impl Network { pub fn mainnet() -> BaseConfig { BaseConfig { - checkpoint: hex_str_to_bytes( + default_checkpoint: hex_str_to_bytes( "0x766647f3c4e1fc91c0db9a9374032ae038778411fbff222974e11f2e3ce7dadf", ) .unwrap(), @@ -69,7 +69,7 @@ pub fn mainnet() -> BaseConfig { pub fn goerli() -> BaseConfig { BaseConfig { - checkpoint: hex_str_to_bytes( + default_checkpoint: hex_str_to_bytes( "0xd4344682866dbede543395ecf5adf9443a27f423a4b00f270458e7932686ced1", ) .unwrap(), diff --git a/config/src/utils.rs b/config/src/utils.rs index 24e680f..b12773b 100644 --- a/config/src/utils.rs +++ b/config/src/utils.rs @@ -15,3 +15,15 @@ where let bytes_string = hex::encode(bytes); serializer.serialize_str(&bytes_string) } + +pub fn bytes_opt_deserialize<'de, D>(deserializer: D) -> Result>, D::Error> +where + D: serde::Deserializer<'de>, +{ + let bytes_opt: Option = serde::Deserialize::deserialize(deserializer)?; + if let Some(bytes) = bytes_opt { + Ok(Some(hex_str_to_bytes(&bytes).unwrap())) + } else { + Ok(None) + } +} From a0032835f36cf6317f707d78c109847869d76ace Mon Sep 17 00:00:00 2001 From: danilowhk Date: Fri, 3 Feb 2023 16:35:10 -0400 Subject: [PATCH 32/44] feat: make ConfigDB public (#190) * Update lib.rs * format --- src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index f72ef4b..1ec191c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,7 +51,10 @@ //! Errors used across helios. pub mod client { - pub use client::{database::FileDB, Client, ClientBuilder}; + pub use client::{ + database::{ConfigDB, FileDB}, + Client, ClientBuilder, + }; } pub mod config { From 1b1a54034077d06af945e579282c5a243a333d98 Mon Sep 17 00:00:00 2001 From: christn Date: Wed, 8 Feb 2023 06:36:29 +0800 Subject: [PATCH 33/44] feat: backfill payloads (#189) * Loop over all missing slots since last update * Adjust get_block_header function to allow getting headers of past blocks * Compare parent hashes when backfilling blocks * Backfill blocks concurrently * Do not rehash backfilled blocks * Revert "Adjust get_block_header function to allow getting headers of past blocks" This reverts commit 5895118046a0778a973f034f86757997d596ef35. * Move get_payloads to consensus module * Continue with the next block instead of request failure to recover from skipped blocks * clippy and rustfmt * clippy * Remove redundant get_block_from_rpc method --- Cargo.lock | 1 + client/src/node.rs | 17 +++++++++++++++++ consensus/Cargo.toml | 1 + consensus/src/consensus.rs | 38 ++++++++++++++++++++++++++++++++++++++ execution/src/evm.rs | 2 +- 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 2f4c8dc..733b499 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -687,6 +687,7 @@ dependencies = [ "config", "ethers", "eyre", + "futures", "hex", "log", "milagro_bls", diff --git a/client/src/node.rs b/client/src/node.rs index 93d6b41..cb4e35d 100644 --- a/client/src/node.rs +++ b/client/src/node.rs @@ -9,6 +9,7 @@ use eyre::{eyre, Result}; use common::errors::BlockNotFoundError; use common::types::BlockTag; use config::Config; + use consensus::rpc::nimbus_rpc::NimbusRpc; use consensus::types::{ExecutionPayload, Header}; use consensus::ConsensusClient; @@ -25,6 +26,7 @@ pub struct Node { pub config: Arc, payloads: BTreeMap, finalized_payloads: BTreeMap, + current_slot: Option, pub history_size: usize, } @@ -49,6 +51,7 @@ impl Node { config, payloads, finalized_payloads, + current_slot: None, history_size: 64, }) } @@ -110,6 +113,20 @@ impl Node { self.finalized_payloads .insert(finalized_payload.block_number, finalized_payload); + let start_slot = self + .current_slot + .unwrap_or(latest_header.slot - self.history_size as u64); + let backfill_payloads = self + .consensus + .get_payloads(start_slot, latest_header.slot) + .await + .map_err(NodeError::ConsensusPayloadError)?; + for payload in backfill_payloads { + self.payloads.insert(payload.block_number, payload); + } + + self.current_slot = Some(latest_header.slot); + while self.payloads.len() > self.history_size { self.payloads.pop_first(); } diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 41e1a1c..c261ff4 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] eyre = "0.6.8" +futures = "0.3.23" serde = { version = "1.0.143", features = ["derive"] } serde_json = "1.0.85" hex = "0.4.3" diff --git a/consensus/src/consensus.rs b/consensus/src/consensus.rs index 86c60a1..ea0051e 100644 --- a/consensus/src/consensus.rs +++ b/consensus/src/consensus.rs @@ -4,6 +4,7 @@ use std::sync::Arc; use chrono::Duration; use eyre::eyre; use eyre::Result; +use futures::future::join_all; use log::warn; use log::{debug, info}; use milagro_bls::PublicKey; @@ -106,6 +107,43 @@ impl ConsensusClient { } } + pub async fn get_payloads( + &self, + start_slot: u64, + end_slot: u64, + ) -> Result> { + let payloads_fut = (start_slot..end_slot) + .rev() + .map(|slot| self.rpc.get_block(slot)); + let mut prev_parent_hash: Bytes32 = self + .rpc + .get_block(end_slot) + .await? + .body + .execution_payload + .parent_hash; + let mut payloads: Vec = Vec::new(); + for result in join_all(payloads_fut).await { + if result.is_err() { + continue; + } + let payload = result.unwrap().body.execution_payload; + if payload.block_hash != prev_parent_hash { + warn!( + "error while backfilling blocks: {}", + ConsensusError::InvalidHeaderHash( + format!("{prev_parent_hash:02X?}"), + format!("{:02X?}", payload.parent_hash), + ) + ); + break; + } + prev_parent_hash = payload.parent_hash.clone(); + payloads.push(payload); + } + Ok(payloads) + } + pub fn get_header(&self) -> &Header { &self.store.optimistic_header } diff --git a/execution/src/evm.rs b/execution/src/evm.rs index 33095fa..223b330 100644 --- a/execution/src/evm.rs +++ b/execution/src/evm.rs @@ -175,7 +175,7 @@ impl<'a, R: ExecutionRpc> Evm<'a, R> { env.tx.transact_to = TransactTo::Call(opts.to); env.tx.caller = opts.from.unwrap_or(Address::zero()); env.tx.value = opts.value.unwrap_or(U256::from(0)); - env.tx.data = Bytes::from(opts.data.clone().unwrap_or(vec![])); + env.tx.data = Bytes::from(opts.data.clone().unwrap_or_default()); env.tx.gas_limit = opts.gas.map(|v| v.as_u64()).unwrap_or(u64::MAX); env.tx.gas_price = opts.gas_price.unwrap_or(U256::zero()); From 40668283876048dea2e7d24bc5de87ed631a6b4e Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Wed, 8 Feb 2023 18:12:41 -0500 Subject: [PATCH 34/44] fix: prevent logs for unseen blocks (#192) --- execution/src/execution.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/execution/src/execution.rs b/execution/src/execution.rs index 3a16028..c103437 100644 --- a/execution/src/execution.rs +++ b/execution/src/execution.rs @@ -291,7 +291,22 @@ impl ExecutionClient { filter: &Filter, payloads: &BTreeMap, ) -> Result> { - let logs = self.rpc.get_logs(filter).await?; + let filter = filter.clone(); + + // avoid fetching logs for a block helios hasn't seen yet + let filter = if filter.get_to_block().is_none() && filter.get_block_hash().is_none() { + let block = *payloads.last_key_value().unwrap().0; + let filter = filter.to_block(block); + if filter.get_from_block().is_none() { + filter.from_block(block) + } else { + filter + } + } else { + filter + }; + + let logs = self.rpc.get_logs(&filter).await?; if logs.len() > MAX_SUPPORTED_LOGS_NUMBER { return Err( ExecutionError::TooManyLogsToProve(logs.len(), MAX_SUPPORTED_LOGS_NUMBER).into(), From 8e006d623beee959eac622178fece1ab1974fb41 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Thu, 9 Feb 2023 14:32:17 -0500 Subject: [PATCH 35/44] feat: typescript bindings (#191) * basic ethers provider setup * add getCode * add call * add estimateGas * add gas pricing methods * add sendRawTransaction * add getTransactionReceipt * add getLogs * add net_version * decouple ethers from lib * add config options * fmt --- .gitignore | 3 + Cargo.lock | 41 + Cargo.toml | 1 + helios-ts/Cargo.toml | 32 + helios-ts/index.html | 26 + helios-ts/lib.ts | 103 + helios-ts/package-lock.json | 3951 +++++++++++++++++++++++++++++++++++ helios-ts/package.json | 20 + helios-ts/run.sh | 8 + helios-ts/src/lib.rs | 185 ++ helios-ts/tsconfig.json | 11 + helios-ts/webpack.config.js | 28 + 12 files changed, 4409 insertions(+) create mode 100644 helios-ts/Cargo.toml create mode 100644 helios-ts/index.html create mode 100644 helios-ts/lib.ts create mode 100644 helios-ts/package-lock.json create mode 100644 helios-ts/package.json create mode 100755 helios-ts/run.sh create mode 100644 helios-ts/src/lib.rs create mode 100644 helios-ts/tsconfig.json create mode 100644 helios-ts/webpack.config.js diff --git a/.gitignore b/.gitignore index a82f9f3..665475b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ .DS_Store target *.env + +helios-ts/node_modules +helios-ts/dist diff --git a/Cargo.lock b/Cargo.lock index 733b499..262c553 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,6 +702,16 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "const-cstr" version = "0.3.0" @@ -1985,6 +1995,26 @@ dependencies = [ "tracing-test", ] +[[package]] +name = "helios-ts" +version = "0.1.0" +dependencies = [ + "client", + "common", + "config", + "consensus", + "console_error_panic_hook", + "ethers", + "execution", + "hex", + "serde", + "serde-wasm-bindgen", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -3884,6 +3914,17 @@ dependencies = [ "serde_json", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde_derive" version = "1.0.152" diff --git a/Cargo.toml b/Cargo.toml index e578d2f..ce58362 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "config", "consensus", "execution", + "helios-ts", ] [dependencies] diff --git a/helios-ts/Cargo.toml b/helios-ts/Cargo.toml new file mode 100644 index 0000000..2ccef9f --- /dev/null +++ b/helios-ts/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "helios-ts" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib"] + +[dependencies] +wasm-bindgen = "0.2.83" +wasm-bindgen-futures = "0.4.33" +serde-wasm-bindgen = "0.4.5" +console_error_panic_hook = "0.1.7" + +ethers = "1.0.0" +hex = "0.4.3" +serde = { version = "1.0.143", features = ["derive"] } +serde_json = "1.0.85" + +client = { path = "../client" } +common = { path = "../common" } +consensus = { path = "../consensus" } +execution = { path = "../execution" } +config = { path = "../config" } + +[dependencies.web-sys] +version = "0.3" +features = [ + "console", +] diff --git a/helios-ts/index.html b/helios-ts/index.html new file mode 100644 index 0000000..48e0229 --- /dev/null +++ b/helios-ts/index.html @@ -0,0 +1,26 @@ + + + + + hello-wasm example + + + + + + + diff --git a/helios-ts/lib.ts b/helios-ts/lib.ts new file mode 100644 index 0000000..59f5938 --- /dev/null +++ b/helios-ts/lib.ts @@ -0,0 +1,103 @@ +import { Client } from "./pkg"; + +/// An EIP-1193 compliant Ethereum provider. Treat this the same as you +/// would window.ethereum when constructing an ethers or web3 provider. +export class HeliosProvider { + #client; + #chainId; + + constructor(config: Config) { + const executionRpc = config.executionRpc; + const consensusRpc = config.consensusRpc; + const checkpoint = config.checkpoint; + const network = config.network ?? Network.MAINNET; + + this.#client = new Client(executionRpc, consensusRpc, network, checkpoint); + this.#chainId = this.#client.chain_id(); + } + + async sync() { + await this.#client.sync(); + } + + async request(req: Request): Promise { + switch(req.method) { + case "eth_getBalance": { + return this.#client.get_balance(req.params[0], req.params[1]); + }; + case "eth_chainId": { + return this.#chainId; + }; + case "eth_blockNumber": { + return this.#client.get_block_number(); + }; + case "eth_getTransactionByHash": { + let tx = await this.#client.get_transaction_by_hash(req.params[0]); + return mapToObj(tx); + }; + case "eth_getTransactionCount": { + return this.#client.get_transaction_count(req.params[0], req.params[1]); + }; + case "eth_getBlockTransactionCountByHash": { + return this.#client.get_block_transaction_count_by_hash(req.params[0]); + }; + case "eth_getBlockTransactionCountByNumber": { + return this.#client.get_block_transaction_count_by_number(req.params[0]); + }; + case "eth_getCode": { + return this.#client.get_code(req.params[0], req.params[1]); + }; + case "eth_call": { + return this.#client.call(req.params[0], req.params[1]); + }; + case "eth_estimateGas": { + return this.#client.estimate_gas(req.params[0]); + }; + case "eth_gasPrice": { + return this.#client.gas_price(); + }; + case "eth_maxPriorityFeePerGas": { + return this.#client.max_priority_fee_per_gas(); + }; + case "eth_sendRawTransaction": { + return this.#client.send_raw_transaction(req.params[0]); + }; + case "eth_getTransactionReceipt": { + return this.#client.get_transaction_receipt(req.params[0]); + }; + case "eth_getLogs": { + return this.#client.get_logs(req.params[0]); + }; + case "net_version": { + return this.#chainId; + }; + } + } +} + +export type Config = { + executionRpc: string, + consensusRpc?: string, + checkpoint?: string, + network?: Network, +} + +export enum Network { + MAINNET = "mainnet", + GOERLI = "goerli", +} + +type Request = { + method: string, + params: any[], +} + +function mapToObj(map: Map | undefined): Object | undefined { + if(!map) return undefined; + + return Array.from(map).reduce((obj: any, [key, value]) => { + obj[key] = value; + return obj; + }, {}); +} + diff --git a/helios-ts/package-lock.json b/helios-ts/package-lock.json new file mode 100644 index 0000000..fcf7598 --- /dev/null +++ b/helios-ts/package-lock.json @@ -0,0 +1,3951 @@ +{ + "name": "helios", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "helios", + "version": "0.1.0", + "license": "ISC", + "dependencies": { + "ethers": "^5.7.2" + }, + "devDependencies": { + "ts-loader": "^9.4.1", + "typescript": "^4.9.3", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.0" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "node_modules/@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@types/eslint": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz", + "integrity": "sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", + "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", + "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", + "dev": true, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001450", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz", + "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.286.tgz", + "integrity": "sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, + "node_modules/enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz", + "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==", + "dev": true + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.16.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", + "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", + "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-loader": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", + "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.0.1", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.1", + "colorette": "^2.0.14", + "commander": "^9.4.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + }, + "dependencies": { + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@ethersproject/abi": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", + "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "requires": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/abstract-provider": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", + "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0" + } + }, + "@ethersproject/abstract-signer": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", + "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "@ethersproject/address": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", + "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/rlp": "^5.7.0" + } + }, + "@ethersproject/base64": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", + "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "requires": { + "@ethersproject/bytes": "^5.7.0" + } + }, + "@ethersproject/basex": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", + "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/properties": "^5.7.0" + } + }, + "@ethersproject/bignumber": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", + "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "bn.js": "^5.2.1" + } + }, + "@ethersproject/bytes": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", + "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/constants": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", + "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "requires": { + "@ethersproject/bignumber": "^5.7.0" + } + }, + "@ethersproject/contracts": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", + "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "requires": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/transactions": "^5.7.0" + } + }, + "@ethersproject/hash": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", + "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/hdnode": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", + "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "@ethersproject/json-wallets": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", + "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "requires": { + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/pbkdf2": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "@ethersproject/keccak256": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", + "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "js-sha3": "0.8.0" + } + }, + "@ethersproject/logger": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", + "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==" + }, + "@ethersproject/networks": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", + "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/pbkdf2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", + "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/sha2": "^5.7.0" + } + }, + "@ethersproject/properties": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", + "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "requires": { + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/providers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", + "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/base64": "^5.7.0", + "@ethersproject/basex": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/networks": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bech32": "1.1.4", + "ws": "7.4.6" + } + }, + "@ethersproject/random": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", + "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/rlp": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", + "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/sha2": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", + "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "hash.js": "1.1.7" + } + }, + "@ethersproject/signing-key": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", + "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "bn.js": "^5.2.1", + "elliptic": "6.5.4", + "hash.js": "1.1.7" + } + }, + "@ethersproject/solidity": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", + "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/sha2": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/strings": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", + "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/transactions": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", + "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "requires": { + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0" + } + }, + "@ethersproject/units": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", + "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "requires": { + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/logger": "^5.7.0" + } + }, + "@ethersproject/wallet": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", + "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "requires": { + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/hdnode": "^5.7.0", + "@ethersproject/json-wallets": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/random": "^5.7.0", + "@ethersproject/signing-key": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/wordlists": "^5.7.0" + } + }, + "@ethersproject/web": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", + "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "requires": { + "@ethersproject/base64": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@ethersproject/wordlists": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", + "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "requires": { + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/logger": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/strings": "^5.7.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@types/eslint": { + "version": "8.21.0", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.21.0.tgz", + "integrity": "sha512-35EhHNOXgxnUgh4XCJsGhE7zdlDhYDN/aMG6UbkByCFFNgQ7b3U+uVoqBpicFydR8JEfgdjCF7SJ7MiJfzuiTA==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", + "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "0.0.51", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", + "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", + "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", + "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", + "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", + "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", + "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", + "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", + "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", + "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", + "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", + "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", + "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/helper-wasm-section": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-opt": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "@webassemblyjs/wast-printer": "1.11.1" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", + "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", + "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-buffer": "1.11.1", + "@webassemblyjs/wasm-gen": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", + "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.1", + "@webassemblyjs/ieee754": "1.11.1", + "@webassemblyjs/leb128": "1.11.1", + "@webassemblyjs/utf8": "1.11.1" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", + "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.1", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.0.1.tgz", + "integrity": "sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.1.tgz", + "integrity": "sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==", + "dev": true, + "requires": {} + }, + "@webpack-cli/serve": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.1.tgz", + "integrity": "sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-import-assertions": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", + "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "dev": true, + "requires": {} + }, + "aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==" + }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==" + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==" + }, + "browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001450", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001450.tgz", + "integrity": "sha512-qMBmvmQmFXaSxexkjjfMvD5rnDL0+m+dUMZKoDYsGG8iZN29RuYh9eRoMvKsT6uMAWlyUUGDEQGJJYjzCIO9ew==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "electron-to-chromium": { + "version": "1.4.286", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.286.tgz", + "integrity": "sha512-Vp3CVhmYpgf4iXNKAucoQUDcCrBQX3XLBtwgFqP9BUXuucgvAV9zWp1kYU7LL9j4++s9O+12cb3wMtN4SJy6UQ==", + "dev": true + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + } + } + }, + "enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "es-module-lexer": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", + "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "ethers": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", + "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "requires": { + "@ethersproject/abi": "5.7.0", + "@ethersproject/abstract-provider": "5.7.0", + "@ethersproject/abstract-signer": "5.7.0", + "@ethersproject/address": "5.7.0", + "@ethersproject/base64": "5.7.0", + "@ethersproject/basex": "5.7.0", + "@ethersproject/bignumber": "5.7.0", + "@ethersproject/bytes": "5.7.0", + "@ethersproject/constants": "5.7.0", + "@ethersproject/contracts": "5.7.0", + "@ethersproject/hash": "5.7.0", + "@ethersproject/hdnode": "5.7.0", + "@ethersproject/json-wallets": "5.7.0", + "@ethersproject/keccak256": "5.7.0", + "@ethersproject/logger": "5.7.0", + "@ethersproject/networks": "5.7.1", + "@ethersproject/pbkdf2": "5.7.0", + "@ethersproject/properties": "5.7.0", + "@ethersproject/providers": "5.7.2", + "@ethersproject/random": "5.7.0", + "@ethersproject/rlp": "5.7.0", + "@ethersproject/sha2": "5.7.0", + "@ethersproject/signing-key": "5.7.0", + "@ethersproject/solidity": "5.7.0", + "@ethersproject/strings": "5.7.0", + "@ethersproject/transactions": "5.7.0", + "@ethersproject/units": "5.7.0", + "@ethersproject/wallet": "5.7.0", + "@ethersproject/web": "5.7.1", + "@ethersproject/wordlists": "5.7.0" + } + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true + }, + "mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "requires": { + "mime-db": "1.52.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node-releases": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.9.tgz", + "integrity": "sha512-2xfmOrRkGogbTK9R6Leda0DGiXeY3p2NJpy4+gNCffdUvV6mdEJnaDEic1i3Ec2djAo8jWYoJMR5PB0MSMpxUA==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "requires": { + "resolve": "^1.20.0" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "schema-utils": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", + "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + }, + "scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "terser": { + "version": "5.16.3", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.16.3.tgz", + "integrity": "sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.2", + "acorn": "^8.5.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + } + }, + "terser-webpack-plugin": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", + "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.14", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.0", + "terser": "^5.14.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "ts-loader": { + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.4.2.tgz", + "integrity": "sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "webpack": { + "version": "5.75.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.75.0.tgz", + "integrity": "sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^0.0.51", + "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/wasm-edit": "1.11.1", + "@webassemblyjs/wasm-parser": "1.11.1", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.7.6", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.10.0", + "es-module-lexer": "^0.9.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.1.3", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + } + }, + "webpack-cli": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.0.1.tgz", + "integrity": "sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.0.1", + "@webpack-cli/info": "^2.0.1", + "@webpack-cli/serve": "^2.0.1", + "colorette": "^2.0.14", + "commander": "^9.4.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", + "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "requires": {} + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } +} diff --git a/helios-ts/package.json b/helios-ts/package.json new file mode 100644 index 0000000..9701ebc --- /dev/null +++ b/helios-ts/package.json @@ -0,0 +1,20 @@ +{ + "name": "helios", + "version": "0.1.0", + "main": "lib.js", + "scripts": { + "build": "webpack" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "ts-loader": "^9.4.1", + "typescript": "^4.9.3", + "webpack": "^5.75.0", + "webpack-cli": "^5.0.0" + }, + "dependencies": { + "ethers": "^5.7.2" + } +} diff --git a/helios-ts/run.sh b/helios-ts/run.sh new file mode 100755 index 0000000..81ad11f --- /dev/null +++ b/helios-ts/run.sh @@ -0,0 +1,8 @@ +set -e + +(&>/dev/null lcp --proxyUrl https://eth-mainnet.g.alchemy.com/v2/23IavJytUwkTtBMpzt_TZKwgwAarocdT --port 9001 &) +(&>/dev/null lcp --proxyUrl https://www.lightclientdata.org --port 9002 &) + +wasm-pack build +npm run build +simple-http-server diff --git a/helios-ts/src/lib.rs b/helios-ts/src/lib.rs new file mode 100644 index 0000000..b9cb5a5 --- /dev/null +++ b/helios-ts/src/lib.rs @@ -0,0 +1,185 @@ +extern crate console_error_panic_hook; +extern crate web_sys; + +use std::str::FromStr; + +use common::types::BlockTag; +use ethers::types::{Address, Filter, H256}; +use execution::types::CallOpts; +use wasm_bindgen::prelude::*; + +use client::database::ConfigDB; +use config::{networks, Config}; + +#[allow(unused_macros)] +macro_rules! log { + ( $( $t:tt )* ) => { + web_sys::console::log_1(&format!( $( $t )* ).into()); + } +} + +#[wasm_bindgen] +pub struct Client { + inner: client::Client, + chain_id: u64, +} + +#[wasm_bindgen] +impl Client { + #[wasm_bindgen(constructor)] + pub fn new( + execution_rpc: String, + consensus_rpc: Option, + network: String, + checkpoint: Option, + ) -> Self { + console_error_panic_hook::set_once(); + + let base = match network.as_str() { + "mainnet" => networks::mainnet(), + "goerli" => networks::goerli(), + _ => panic!("invalid network"), + }; + + let chain_id = base.chain.chain_id; + + let checkpoint = Some( + checkpoint + .as_ref() + .map(|c| c.strip_prefix("0x").unwrap_or(c.as_str())) + .map(|c| hex::decode(c).unwrap()) + .unwrap_or(base.default_checkpoint), + ); + + let consensus_rpc = consensus_rpc.unwrap_or(base.consensus_rpc.unwrap()); + + let config = Config { + execution_rpc, + consensus_rpc, + checkpoint, + + chain: base.chain, + forks: base.forks, + + ..Default::default() + }; + + let inner: client::Client = + client::ClientBuilder::new().config(config).build().unwrap(); + + Self { inner, chain_id } + } + + #[wasm_bindgen] + pub async fn sync(&mut self) { + self.inner.start().await.unwrap() + } + + #[wasm_bindgen] + pub fn chain_id(&self) -> u32 { + self.chain_id as u32 + } + + #[wasm_bindgen] + pub async fn get_block_number(&self) -> u32 { + self.inner.get_block_number().await.unwrap() as u32 + } + + #[wasm_bindgen] + pub async fn get_balance(&self, addr: JsValue, block: JsValue) -> String { + let addr: Address = serde_wasm_bindgen::from_value(addr).unwrap(); + let block: BlockTag = serde_wasm_bindgen::from_value(block).unwrap(); + self.inner + .get_balance(&addr, block) + .await + .unwrap() + .to_string() + } + + #[wasm_bindgen] + pub async fn get_transaction_by_hash(&self, hash: String) -> JsValue { + let hash = H256::from_str(&hash).unwrap(); + let tx = self.inner.get_transaction_by_hash(&hash).await.unwrap(); + serde_wasm_bindgen::to_value(&tx).unwrap() + } + + #[wasm_bindgen] + pub async fn get_transaction_count(&self, addr: JsValue, block: JsValue) -> u32 { + let addr: Address = serde_wasm_bindgen::from_value(addr).unwrap(); + let block: BlockTag = serde_wasm_bindgen::from_value(block).unwrap(); + self.inner.get_nonce(&addr, block).await.unwrap() as u32 + } + + #[wasm_bindgen] + pub async fn get_block_transaction_count_by_hash(&self, hash: JsValue) -> u32 { + let hash: H256 = serde_wasm_bindgen::from_value(hash).unwrap(); + self.inner + .get_block_transaction_count_by_hash(&hash.as_bytes().to_vec()) + .await + .unwrap() as u32 + } + + #[wasm_bindgen] + pub async fn get_block_transaction_count_by_number(&self, block: JsValue) -> u32 { + let block: BlockTag = serde_wasm_bindgen::from_value(block).unwrap(); + self.inner + .get_block_transaction_count_by_number(block) + .await + .unwrap() as u32 + } + + #[wasm_bindgen] + pub async fn get_code(&self, addr: JsValue, block: JsValue) -> String { + let addr: Address = serde_wasm_bindgen::from_value(addr).unwrap(); + let block: BlockTag = serde_wasm_bindgen::from_value(block).unwrap(); + let code = self.inner.get_code(&addr, block).await.unwrap(); + format!("0x{}", hex::encode(code)) + } + + #[wasm_bindgen] + pub async fn call(&self, opts: JsValue, block: JsValue) -> String { + let opts: CallOpts = serde_wasm_bindgen::from_value(opts).unwrap(); + let block: BlockTag = serde_wasm_bindgen::from_value(block).unwrap(); + let res = self.inner.call(&opts, block).await.unwrap(); + format!("0x{}", hex::encode(res)) + } + + #[wasm_bindgen] + pub async fn estimate_gas(&self, opts: JsValue) -> u32 { + let opts: CallOpts = serde_wasm_bindgen::from_value(opts).unwrap(); + self.inner.estimate_gas(&opts).await.unwrap() as u32 + } + + #[wasm_bindgen] + pub async fn gas_price(&self) -> JsValue { + let price = self.inner.get_gas_price().await.unwrap(); + serde_wasm_bindgen::to_value(&price).unwrap() + } + + #[wasm_bindgen] + pub async fn max_priority_fee_per_gas(&self) -> JsValue { + let price = self.inner.get_priority_fee().await.unwrap(); + serde_wasm_bindgen::to_value(&price).unwrap() + } + + #[wasm_bindgen] + pub async fn send_raw_transaction(&self, tx: String) -> JsValue { + let tx = hex::decode(tx).unwrap(); + let hash = self.inner.send_raw_transaction(&tx).await.unwrap(); + serde_wasm_bindgen::to_value(&hash).unwrap() + } + + #[wasm_bindgen] + pub async fn get_transaction_receipt(&self, tx: JsValue) -> JsValue { + let tx: H256 = serde_wasm_bindgen::from_value(tx).unwrap(); + let receipt = self.inner.get_transaction_receipt(&tx).await.unwrap(); + serde_wasm_bindgen::to_value(&receipt).unwrap() + } + + #[wasm_bindgen] + pub async fn get_logs(&self, filter: JsValue) -> JsValue { + let filter: Filter = serde_wasm_bindgen::from_value(filter).unwrap(); + let logs = self.inner.get_logs(&filter).await.unwrap(); + serde_wasm_bindgen::to_value(&logs).unwrap() + } +} diff --git a/helios-ts/tsconfig.json b/helios-ts/tsconfig.json new file mode 100644 index 0000000..b4b6f0d --- /dev/null +++ b/helios-ts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "outDir": "./dist/", + "noImplicitAny": true, + "module": "es6", + "target": "es6", + "jsx": "react", + "allowJs": true, + "moduleResolution": "node" + } +} diff --git a/helios-ts/webpack.config.js b/helios-ts/webpack.config.js new file mode 100644 index 0000000..e496a5e --- /dev/null +++ b/helios-ts/webpack.config.js @@ -0,0 +1,28 @@ +const path = require("path"); + +module.exports = { + entry: "./lib.ts", + module: { + rules: [ + { + test: /\.ts?$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.ts', '.js'], + }, + output: { + filename: "bundle.js", + path: path.resolve(__dirname, "dist"), + library: { + name: "helios", + type: "umd", + } + }, + experiments: { + asyncWebAssembly: true, + } +}; From da520290ce4ec82ccc48d8fc2dcda2a2fada9810 Mon Sep 17 00:00:00 2001 From: Noah Citron Date: Fri, 10 Feb 2023 12:47:57 -0500 Subject: [PATCH 36/44] fix: embedded wasm binary (#193) * fix: embedded wasm binary * remove public path * remove unused comments from run.sh --- .gitignore | 1 + Cargo.lock | 20 ++--- helios-ts/Cargo.toml | 2 +- helios-ts/index.html | 16 ++-- helios-ts/lib.ts | 10 ++- helios-ts/package-lock.json | 166 ++++++++++++++++++++++++++++++++++++ helios-ts/package.json | 4 +- helios-ts/run.sh | 1 - helios-ts/tsconfig.json | 4 +- helios-ts/webpack.config.js | 16 +++- 10 files changed, 214 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 665475b..6273129 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ target helios-ts/node_modules helios-ts/dist +helios-ts/helios-*.tgz diff --git a/Cargo.lock b/Cargo.lock index 262c553..0a47e9b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4750,9 +4750,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -4760,9 +4760,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" dependencies = [ "bumpalo", "log", @@ -4787,9 +4787,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4797,9 +4797,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", @@ -4810,9 +4810,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" [[package]] name = "wasm-timer" diff --git a/helios-ts/Cargo.toml b/helios-ts/Cargo.toml index 2ccef9f..bd9fe42 100644 --- a/helios-ts/Cargo.toml +++ b/helios-ts/Cargo.toml @@ -9,7 +9,7 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -wasm-bindgen = "0.2.83" +wasm-bindgen = "0.2.84" wasm-bindgen-futures = "0.4.33" serde-wasm-bindgen = "0.4.5" console_error_panic_hook = "0.1.7" diff --git a/helios-ts/index.html b/helios-ts/index.html index 48e0229..0e02a2a 100644 --- a/helios-ts/index.html +++ b/helios-ts/index.html @@ -5,18 +5,16 @@ hello-wasm example - + Flame Graph Reset ZoomSearch dyld`start (1 samples, 25.00%)dyld`startclient`main (1 samples, 25.00%)client`mainclient`std::rt::lang_start_internal (1 samples, 25.00%)client`std::rt::lang_start_internalclient`std::rt::lang_start::_{{closure}} (1 samples, 25.00%)client`std::rt::lang_start::_{{closure}}client`std::sys_common::backtrace::__rust_begin_short_backtrace (1 samples, 25.00%)client`std::sys_common::backtrace::__rus..client`client::main (1 samples, 25.00%)client`client::mainclient`tokio::runtime::builder::Builder::build (1 samples, 25.00%)client`tokio::runtime::builder::Builder:..client`tokio::runtime::scheduler::multi_thread::worker::Launch::launch (1 samples, 25.00%)client`tokio::runtime::scheduler::multi_..client`tokio::runtime::blocking::pool::spawn_blocking (1 samples, 25.00%)client`tokio::runtime::blocking::pool::s..client`tokio::runtime::blocking::pool::Spawner::spawn_blocking (1 samples, 25.00%)client`tokio::runtime::blocking::pool::S..client`tokio::runtime::blocking::pool::Spawner::spawn_task (1 samples, 25.00%)client`tokio::runtime::blocking::pool::S..client`std::thread::Builder::spawn (1 samples, 25.00%)client`std::thread::Builder::spawnclient`std::sys::unix::thread::Thread::new (1 samples, 25.00%)client`std::sys::unix::thread::Thread::n..libsystem_kernel.dylib`__bsdthread_create (1 samples, 25.00%)libsystem_kernel.dylib`__bsdthread_createclient`__rdl_alloc (1 samples, 25.00%)client`__rdl_alloclibsystem_malloc.dylib`posix_memalign (1 samples, 25.00%)libsystem_malloc.dylib`posix_memalignlibsystem_malloc.dylib`_malloc_zone_memalign (1 samples, 25.00%)libsystem_malloc.dylib`_malloc_zone_mema..libsystem_malloc.dylib`szone_malloc_should_clear (1 samples, 25.00%)libsystem_malloc.dylib`szone_malloc_shou..libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 25.00%)libsystem_malloc.dylib`small_malloc_shou..client`core::ops::function::FnOnce::call_once{{vtable.shim}} (2 samples, 50.00%)client`core::ops::function::FnOnce::call_once{{vtable.shim}}client`std::sys_common::backtrace::__rust_begin_short_backtrace (2 samples, 50.00%)client`std::sys_common::backtrace::__rust_begin_short_backtraceclient`tokio::runtime::blocking::pool::Inner::run (2 samples, 50.00%)client`tokio::runtime::blocking::pool::Inner::runclient`parking_lot::raw_mutex::RawMutex::lock_slow (2 samples, 50.00%)client`parking_lot::raw_mutex::RawMutex::lock_slowclient`std::thread::local::lazy::LazyKeyInner<T>::initialize (2 samples, 50.00%)client`std::thread::local::lazy::LazyKeyInner<T>::initializeclient`parking_lot_core::parking_lot::ThreadData::new (2 samples, 50.00%)client`parking_lot_core::parking_lot::ThreadData::newclient`parking_lot_core::parking_lot::create_hashtable (2 samples, 50.00%)client`parking_lot_core::parking_lot::create_hashtableclient`parking_lot_core::parking_lot::HashTable::new (2 samples, 50.00%)client`parking_lot_core::parking_lot::HashTable::newlibsystem_malloc.dylib`nanov2_allocate_outlined (1 samples, 25.00%)libsystem_malloc.dylib`nanov2_allocate_o..all (4 samples, 100%)libsystem_pthread.dylib`thread_start (3 samples, 75.00%)libsystem_pthread.dylib`thread_startlibsystem_pthread.dylib`_pthread_start (3 samples, 75.00%)libsystem_pthread.dylib`_pthread_startclient`std::sys::unix::thread::Thread::new::thread_start (3 samples, 75.00%)client`std::sys::unix::thread::Thread::new::thread_startclient`std::sys::unix::stack_overflow::imp::make_handler (1 samples, 25.00%)client`std::sys::unix::stack_overflow::i..libsystem_kernel.dylib`__mmap (1 samples, 25.00%)libsystem_kernel.dylib`__mmap \ No newline at end of file