From 0391977ccc5d362fa895d404a9079c15dcb9dc0e Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Thu, 27 Jul 2023 14:37:17 +0100 Subject: [PATCH 1/3] Issue-141: Fix astar and ethereum unit tests (#145) * Fix astar and ethereum unit tests * Bump subxt version --- .github/workflows/ci.yaml | 3 +- Cargo.lock | 1308 ++++++++++++----- chains/astar/config/Cargo.toml | 1 + chains/astar/config/res/astar-dev.scale | Bin 0 -> 171371 bytes chains/astar/config/src/lib.rs | 12 +- chains/astar/server/Cargo.toml | 8 +- chains/astar/server/src/lib.rs | 148 +- chains/ethereum/config/src/lib.rs | 1 + chains/ethereum/server/src/lib.rs | 7 +- chains/polkadot/config/Cargo.toml | 1 + .../polkadot/config/res/polkadot-v9430.scale | Bin 0 -> 386413 bytes chains/polkadot/config/src/lib.rs | 21 +- chains/polkadot/server/Cargo.toml | 4 +- chains/polkadot/server/src/block.rs | 25 +- chains/polkadot/server/src/call.rs | 27 +- chains/polkadot/server/src/lib.rs | 118 +- docker-compose.yml | 6 +- pull_nodes.sh | 7 +- rosetta-crypto/Cargo.toml | 3 + rosetta-crypto/src/address/mod.rs | 43 + rosetta-crypto/src/error.rs | 11 + rosetta-crypto/src/lib.rs | 1 + rosetta-server/Cargo.toml | 1 + rosetta-server/src/lib.rs | 29 +- 24 files changed, 1236 insertions(+), 549 deletions(-) create mode 100644 chains/astar/config/res/astar-dev.scale create mode 100644 chains/polkadot/config/res/polkadot-v9430.scale create mode 100644 rosetta-crypto/src/error.rs diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c7a82c62..de684ff7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -69,6 +69,5 @@ jobs: - name: Pull nodes run: ./pull_nodes.sh - # TODO: Remove the `--no-fail-fast` flag once #141 is fixed - name: cargo test - run: cargo test --locked --all-features --workspace --no-fail-fast + run: cargo test --locked --all-features --workspace diff --git a/Cargo.lock b/Cargo.lock index 08fb713a..59d3a527 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,11 +14,11 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.26.2", + "gimli", ] [[package]] @@ -27,7 +27,7 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ - "gimli 0.27.3", + "gimli", ] [[package]] @@ -45,6 +45,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "aes" version = "0.6.0" @@ -56,6 +65,18 @@ dependencies = [ "cipher 0.2.5", ] +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug 0.3.0", +] + [[package]] name = "aes" version = "0.8.3" @@ -73,11 +94,25 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" dependencies = [ - "aead", + "aead 0.3.2", "aes 0.6.0", "cipher 0.2.5", "ctr 0.6.0", - "ghash", + "ghash 0.3.1", + "subtle", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead 0.4.3", + "aes 0.7.5", + "cipher 0.3.0", + "ctr 0.8.0", + "ghash 0.4.4", "subtle", ] @@ -208,9 +243,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" [[package]] name = "array-bytes" @@ -266,9 +301,9 @@ dependencies = [ [[package]] name = "async-channel" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", "event-listener", @@ -294,11 +329,23 @@ dependencies = [ "async-lock", "async-task", "concurrent-queue", - "fastrand", + "fastrand 1.9.0", "futures-lite", "slab", ] +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock", + "autocfg", + "blocking", + "futures-lite", +] + [[package]] name = "async-global-executor" version = "2.3.1" @@ -360,6 +407,18 @@ dependencies = [ "event-listener", ] +[[package]] +name = "async-net" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" +dependencies = [ + "async-io", + "autocfg", + "blocking", + "futures-lite", +] + [[package]] name = "async-process" version = "1.7.0" @@ -441,13 +500,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.71" +version = "0.1.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -463,9 +522,9 @@ dependencies = [ [[package]] name = "asynchronous-codec" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182" +checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" dependencies = [ "bytes", "futures-sink", @@ -474,6 +533,12 @@ dependencies = [ "pin-project-lite 0.2.10", ] +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + [[package]] name = "atomic-waker" version = "1.1.1" @@ -594,6 +659,15 @@ dependencies = [ "serde", ] +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes 0.11.0", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -700,7 +774,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400" dependencies = [ "arrayvec 0.4.12", - "constant_time_eq", + "constant_time_eq 0.1.5", +] + +[[package]] +name = "blake2b_simd" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "constant_time_eq 0.2.6", ] [[package]] @@ -752,7 +837,7 @@ dependencies = [ "async-lock", "async-task", "atomic-waker", - "fastrand", + "fastrand 1.9.0", "futures-lite", "log", ] @@ -778,6 +863,15 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -834,18 +928,18 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.4" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" dependencies = [ "serde", ] @@ -858,7 +952,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.17", + "semver 1.0.18", "serde", "serde_json", "thiserror", @@ -879,6 +973,31 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +dependencies = [ + "aead 0.4.3", + "chacha20", + "cipher 0.3.0", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.26" @@ -904,6 +1023,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "cipher" version = "0.4.4" @@ -916,9 +1044,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.11" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1640e5cc7fb47dbb8338fd471b105e7ed6c3cb2aeb00c2e067127ffd3764a05d" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -927,9 +1055,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.11" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98c59138d527eeaf9b53f35a77fcc1fad9d883116070c63d5de1c7dc7b00c72b" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", @@ -939,14 +1067,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -962,7 +1090,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b30a84aab436fcb256a2ab3c80663d8aec686e6bae12827bb05fef3e1e439c9f" dependencies = [ "bincode", - "bs58", + "bs58 0.4.0", "coins-core", "digest 0.10.7", "getrandom 0.2.10", @@ -985,7 +1113,7 @@ dependencies = [ "getrandom 0.2.10", "hmac 0.12.1", "once_cell", - "pbkdf2 0.12.1", + "pbkdf2 0.12.2", "rand 0.8.5", "sha2 0.10.7", "thiserror", @@ -999,7 +1127,7 @@ checksum = "9b949a1c63fb7eb591eb7ba438746326aedf0ae843e51ec92ba6bec5bb382c4f" dependencies = [ "base64 0.21.2", "bech32 0.7.3", - "bs58", + "bs58 0.4.0", "digest 0.10.7", "generic-array 0.14.7", "hex 0.4.3", @@ -1033,15 +1161,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" dependencies = [ "lazy_static", - "nom", + "nom 5.1.3", "serde", ] [[package]] name = "const-oid" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6340df57935414636969091153f35f68d9f00bbc8fb4a9c6054706c213e6c6bc" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" [[package]] name = "const_fn" @@ -1055,6 +1183,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a53c0a4d288377e7415b53dcfc3c04da5cdc2cc95c8d5ac178b58f0b861ad6" + [[package]] name = "containers-api" version = "0.8.0" @@ -1079,13 +1213,19 @@ dependencies = [ "url", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "cookie" version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" dependencies = [ - "aes-gcm", + "aes-gcm 0.8.0", "base64 0.13.1", "hkdf", "hmac 0.10.1", @@ -1138,9 +1278,9 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" [[package]] name = "cranelift-entity" -version = "0.92.1" +version = "0.95.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e39cfc857e7e539aa623e03bb6bec11f54aef3dfdef41adcfa7b594af3b54" +checksum = "40099d38061b37e505e63f89bab52199037a72b931ad4868d9089ff7268660b0" dependencies = [ "serde", ] @@ -1274,6 +1414,15 @@ dependencies = [ "cipher 0.2.5", ] +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + [[package]] name = "ctr" version = "0.9.2" @@ -1309,6 +1458,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "curve25519-dalek" +version = "4.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d4ba9852b42210c7538b75484f9daa0655e9a3ac04f693747bb0f02cf3cfe16" +dependencies = [ + "cfg-if", + "fiat-crypto", + "packed_simd_2", + "platforms", + "subtle", + "zeroize", +] + [[package]] name = "curve25519-dalek-ng" version = "4.1.1" @@ -1334,12 +1497,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core 0.20.1", - "darling_macro 0.20.1", + "darling_core 0.20.3", + "darling_macro 0.20.3", ] [[package]] @@ -1358,16 +1521,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -1383,23 +1546,23 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.1" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core 0.20.1", + "darling_core 0.20.3", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "6943ae99c34386c84a470c499d3414f66502a41340aa895406e0d2e4a207b91d" dependencies = [ "cfg-if", - "hashbrown 0.12.3", + "hashbrown 0.14.0", "lock_api", "once_cell", "parking_lot_core 0.9.8", @@ -1453,8 +1616,10 @@ version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ + "convert_case", "proc-macro2", "quote", + "rustc_version 0.4.0", "syn 1.0.109", ] @@ -1593,15 +1758,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" +checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", "digest 0.10.7", @@ -1650,9 +1815,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" @@ -1731,15 +1896,15 @@ checksum = "e48c92028aaa870e83d51c64e5d4e0b6981b360c522198c23959f219a4e1b15b" [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f94c0e13118e7d7533271f754a168ae8400e6a1cc043f2bfd53cc7290f1a1de3" +checksum = "da96524cc884f6558f1769b6c46686af2fe8e8b4cd253bd5a3cdba8181b8e070" dependencies = [ "serde", ] @@ -1837,9 +2002,9 @@ dependencies = [ [[package]] name = "ethers" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a58ce802c65cf3d0756dee5a61094a92cde53c1583b246e9ee5b37226c7fc15" +checksum = "96b4026b97da8281276744741fac7eb385da905f6093c583331fa2953fdd4253" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -1853,9 +2018,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b856b7b8ff5c961093cb8efe151fbcce724b451941ce20781de11a531ccd578" +checksum = "edcb6ffefc230d8c42874c51b28dc11dbb8de50b27a8fdf92648439d6baa68dc" dependencies = [ "ethers-core", "once_cell", @@ -1865,14 +2030,15 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e066a0d9cfc70c454672bf16bb433b0243427420076dc5b2f49c448fb5a10628" +checksum = "0d4719a44c3d37ab07c6dea99ab174068d8c35e441b60b6c20ce4e48357273e8" dependencies = [ "ethers-contract-abigen", "ethers-contract-derive", "ethers-core", "ethers-providers", + "ethers-signers", "futures-util", "hex 0.4.3", "once_cell", @@ -1884,9 +2050,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c113e3e86b6bc16d98484b2c3bb2d01d6fed9f489fe2e592e5cc87c3024d616b" +checksum = "155ea1b84d169d231317ed86e307af6f2bed6b40dd17e5e94bc84da21cadb21c" dependencies = [ "Inflector", "dunce", @@ -1901,16 +2067,16 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.23", + "syn 2.0.27", "toml", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3fb5adee25701c79ec58fcf2c63594cd8829bc9ad6037ff862d5a111101ed2" +checksum = "8567ff196c4a37c1a8c90ec73bda0ad2062e191e4f0a6dc4d943e2ec4830fc88" dependencies = [ "Inflector", "ethers-contract-abigen", @@ -1919,14 +2085,14 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] name = "ethers-core" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6da5fa198af0d3be20c19192df2bd9590b92ce09a8421e793bec8851270f1b05" +checksum = "60ca2514feb98918a0a31de7e1983c29f2267ebf61b2dc5d4294f91e5b866623" dependencies = [ "arrayvec 0.7.4", "bytes", @@ -1944,8 +2110,8 @@ dependencies = [ "rlp", "serde", "serde_json", - "strum", - "syn 2.0.23", + "strum 0.25.0", + "syn 2.0.27", "tempfile", "thiserror", "tiny-keccak", @@ -1954,13 +2120,13 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84ebb401ba97c6f5af278c2c9936c4546cad75dec464b439ae6df249906f4caa" +checksum = "22b3a8269d3df0ed6364bc05b4735b95f4bf830ce3aef87d5e760fb0e93e5b91" dependencies = [ "ethers-core", "reqwest", - "semver 1.0.17", + "semver 1.0.18", "serde", "serde_json", "thiserror", @@ -1969,9 +2135,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740f4a773c19dd6d6a68c8c2e0996c096488d38997d524e21dc612c55da3bd24" +checksum = "e0c339aad74ae5c451d27e0e49c7a3c7d22620b119b4f9291d7aa21f72d7f366" dependencies = [ "async-trait", "auto_impl", @@ -1996,9 +2162,9 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b498fd2a6c019d023e43e83488cd1fb0721f299055975aa6bac8dbf1e95f2c" +checksum = "b411b119f1cf0efb69e2190883dee731251882bb21270f893ee9513b3a697c48" dependencies = [ "async-trait", "auto_impl", @@ -2032,9 +2198,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c4b7e15f212fa7cc2e1251868320221d4ff77a3d48068e69f47ce1c491df2d" +checksum = "4864d387456a9c09a1157fa10e1528b29d90f1d859443acf06a1b23365fb518c" dependencies = [ "async-trait", "coins-bip32", @@ -2051,9 +2217,9 @@ dependencies = [ [[package]] name = "ethers-solc" -version = "2.0.7" +version = "2.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a81c89f121595cf8959e746045bb8b25a6a38d72588561e1a3b7992fc213f674" +checksum = "7a6c2b9625a2c639d46625f88acc2092a3cb35786c37f7c2128b3ca20f639b3c" dependencies = [ "cfg-if", "dunce", @@ -2067,7 +2233,7 @@ dependencies = [ "path-slash", "rayon", "regex", - "semver 1.0.17", + "semver 1.0.18", "serde", "serde_json", "solang-parser", @@ -2117,6 +2283,12 @@ dependencies = [ "instant", ] +[[package]] +name = "fastrand" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" + [[package]] name = "femme" version = "2.2.1" @@ -2143,6 +2315,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" + [[package]] name = "filetime" version = "0.2.21" @@ -2222,6 +2400,17 @@ name = "frame-metadata" version = "15.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "878babb0b136e731cc77ec2fd883ff02745ff21e6fb662729953d44923df009c" +dependencies = [ + "cfg-if", + "parity-scale-codec", + "scale-info", +] + +[[package]] +name = "frame-metadata" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692" dependencies = [ "cfg-if", "parity-scale-codec", @@ -2300,7 +2489,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand", + "fastrand 1.9.0", "futures-core", "futures-io", "memchr", @@ -2327,7 +2516,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -2430,17 +2619,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" dependencies = [ "opaque-debug 0.3.0", - "polyval", + "polyval 0.4.5", ] [[package]] -name = "gimli" -version = "0.26.2" +name = "ghash" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" dependencies = [ - "fallible-iterator", - "stable_deref_trait", + "opaque-debug 0.3.0", + "polyval 0.5.3", ] [[package]] @@ -2448,6 +2637,11 @@ name = "gimli" version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +dependencies = [ + "fallible-iterator", + "indexmap 1.9.3", + "stable_deref_trait", +] [[package]] name = "glob" @@ -2499,9 +2693,9 @@ dependencies = [ [[package]] name = "hash-db" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d23bd4e7b5eda0d0f3a307e8b381fdc8ba9000f26fbe912250c0a4cc3956364a" +checksum = "8e7d7786361d7425ae2fe4f9e407eb0efaa0840f5212d109cc018c40c35c6ab4" [[package]] name = "hash256-std-hasher" @@ -2526,12 +2720,18 @@ name = "hashbrown" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] [[package]] name = "hashbrown" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +dependencies = [ + "serde", +] [[package]] name = "hashers" @@ -2765,7 +2965,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.3", + "rustls 0.21.5", "tokio", "tokio-rustls 0.24.1", ] @@ -2887,6 +3087,12 @@ dependencies = [ "hashbrown 0.14.0", ] +[[package]] +name = "indexmap-nostd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" + [[package]] name = "infer" version = "0.2.3" @@ -2920,6 +3126,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "intx" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f38a50a899dc47a6d0ed5508e7f601a2e34c3a85303514b5d137f3c10a0c75" + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -2944,7 +3156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.3", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -2959,9 +3171,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "jobserver" @@ -3118,9 +3330,9 @@ dependencies = [ [[package]] name = "lalrpop" -version = "0.19.12" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" dependencies = [ "ascii-canvas", "bit-set", @@ -3131,7 +3343,7 @@ dependencies = [ "lalrpop-util", "petgraph", "regex", - "regex-syntax 0.6.29", + "regex-syntax 0.7.4", "string_cache", "term", "tiny-keccak", @@ -3140,9 +3352,9 @@ dependencies = [ [[package]] name = "lalrpop-util" -version = "0.19.12" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" [[package]] name = "lazy_static" @@ -3169,6 +3381,12 @@ version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "libm" version = "0.2.7" @@ -3261,6 +3479,12 @@ dependencies = [ "value-bag", ] +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" + [[package]] name = "mach" version = "0.3.2" @@ -3305,9 +3529,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -3323,20 +3547,13 @@ dependencies = [ [[package]] name = "memory-db" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e0c7cba9ce19ac7ffd2053ac9f49843bbd3f4318feedfd74e85c19d5fb0ba66" +checksum = "808b50db46293432a45e63bc15ea51e0ab4c0a1647b8eb114e31a3e698dd6fbe" dependencies = [ "hash-db", - "hashbrown 0.12.3", ] -[[package]] -name = "memory_units" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8452105ba047068f40ff7093dd1d9da90898e63dd61736462e9cdda6a90ad3c3" - [[package]] name = "merlin" version = "2.0.1" @@ -3377,6 +3594,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -3397,12 +3620,27 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nanoid" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" +dependencies = [ + "rand 0.8.5", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + [[package]] name = "nodrop" version = "0.1.14" @@ -3426,6 +3664,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -3438,9 +3686,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ "num-bigint", "num-complex", @@ -3515,9 +3763,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg", ] @@ -3550,7 +3798,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -3564,12 +3812,12 @@ dependencies = [ [[package]] name = "object" -version = "0.29.0" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "crc32fast", - "hashbrown 0.12.3", + "hashbrown 0.13.2", "indexmap 1.9.3", "memchr", ] @@ -3650,11 +3898,21 @@ dependencies = [ "sha2 0.10.7", ] +[[package]] +name = "packed_simd_2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" +dependencies = [ + "cfg-if", + "libm 0.1.4", +] + [[package]] name = "parity-scale-codec" -version = "3.6.3" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756d439303e94fae44f288ba881ad29670c65b0c4b0e05674ca81061bb65f2c5" +checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" dependencies = [ "arrayvec 0.7.4", "bitvec 1.0.1", @@ -3667,9 +3925,9 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.3" +version = "3.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d884d78fcf214d70b1e239fcd1c6e5e95aa3be1881918da2e488cc946c7a476" +checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -3677,12 +3935,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "parity-wasm" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" - [[package]] name = "parking" version = "2.1.0" @@ -3750,9 +4002,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4b27ab7be369122c218afc2079489cdcb4b517c0a3fc386ff11e1fedfcc2b35" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "path-slash" @@ -3783,9 +4035,9 @@ dependencies = [ [[package]] name = "pbkdf2" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", "hmac 0.12.1", @@ -3856,7 +4108,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -3894,7 +4146,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -3931,6 +4183,12 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "platforms" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" + [[package]] name = "polling" version = "2.8.0" @@ -3948,12 +4206,35 @@ dependencies = [ ] [[package]] -name = "polyval" -version = "0.4.5" +name = "poly1305" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ - "cpuid-bool", + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +dependencies = [ + "cpuid-bool", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if", + "cpufeatures", "opaque-debug 0.3.0", "universal-hash", ] @@ -3972,12 +4253,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387" +checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" dependencies = [ "proc-macro2", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -4045,9 +4326,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -4063,9 +4344,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.29" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "573015e8ab27661678357f27dc26460738fd2b6c86e46f386fde94cb5d913105" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -4206,34 +4487,34 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1641819477c319ef452a075ac34a4be92eb9ba09f6841f62d594d50fdcf0bf6b" +checksum = "61ef7e18e8841942ddb1cf845054f8008410030a3997875d9e49b7a363063df1" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bf53dad9b6086826722cdc99140793afd9f62faa14a1ad07eb4f955e7a7216" +checksum = "2dfaf0c85b766276c797f3791f5bc6d5bd116b41d53049af2789666b0c0bc9fa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] name = "regex" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89089e897c013b3deb627116ae56a6955a72b8bed395c9526af31c9fe528b484" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.0", - "regex-syntax 0.7.3", + "regex-automata 0.3.3", + "regex-syntax 0.7.4", ] [[package]] @@ -4247,13 +4528,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa250384981ea14565685dea16a9ccc4d1c541a13f82b9c168572264d1df8c56" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.3", + "regex-syntax 0.7.4", ] [[package]] @@ -4264,9 +4545,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab07dc67230e4a4718e70fd5c20055a4334b121f1f9db8fe63ef39ce9b8c846" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" @@ -4291,7 +4572,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.10", - "rustls 0.21.3", + "rustls 0.21.5", "rustls-pemfile", "serde", "serde_json", @@ -4326,7 +4607,7 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", + "spin 0.5.2", "untrusted", "web-sys", "winapi", @@ -4409,6 +4690,7 @@ version = "0.4.0" dependencies = [ "anyhow", "rosetta-core", + "subxt", ] [[package]] @@ -4435,6 +4717,7 @@ dependencies = [ "anyhow", "rosetta-core", "serde", + "subxt", ] [[package]] @@ -4458,9 +4741,10 @@ dependencies = [ "anyhow", "bech32 0.9.1", "blake2-rfc", - "bs58", + "bs58 0.4.0", "ecdsa", "ed25519-dalek", + "ethers", "hex 0.4.3", "hmac 0.12.1", "k256", @@ -4471,8 +4755,10 @@ dependencies = [ "schnorrkel 0.10.2", "sha2 0.10.7", "sha3", + "sp-core", "ss58-registry", "substrate-bip39", + "thiserror", ] [[package]] @@ -4503,6 +4789,7 @@ dependencies = [ "futures", "hex 0.4.3", "log", + "nanoid", "rosetta-core", "rosetta-docker", "serde", @@ -4613,7 +4900,7 @@ version = "0.4.0" dependencies = [ "anyhow", "blake2-rfc", - "bs58", + "bs58 0.4.0", "parity-scale-codec", "rosetta-config-polkadot", "rosetta-core", @@ -4692,7 +4979,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.17", + "semver 1.0.18", ] [[package]] @@ -4725,9 +5012,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.3" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac5ffa1efe7548069688cd7028f32591853cd7b5b756d41bcffd2353e4fc75b4" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ "bitflags 2.3.3", "errno", @@ -4763,13 +5050,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.3" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b19faa85ecb5197342b54f987b142fb3e30d0c90da40f80ef4fa9a726e6676ed" +checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" dependencies = [ "log", "ring", - "rustls-webpki 0.101.1", + "rustls-webpki 0.101.2", "sct 0.7.0", ] @@ -4806,9 +5093,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.1" +version = "0.101.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" +checksum = "513722fd73ad80a71f72b61009ea1b584bcfa1483ca93949c8f290298837fa59" dependencies = [ "ring", "untrusted", @@ -4816,15 +5103,26 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.13" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ruzstd" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc31bd9b61a32c31f9650d18add92aa83a49ba979c143eefd27fe7177b05bd5f" +checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc" +dependencies = [ + "byteorder", + "thiserror-core", + "twox-hash", +] [[package]] name = "ryu" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe232bdf6be8c8de797b22184ee71118d63780ea42ac85b61d1baa6d3b782ae9" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "salsa20" @@ -4879,16 +5177,60 @@ dependencies = [ [[package]] name = "scale-decode" -version = "0.4.0" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0459d00b0dbd2e765009924a78ef36b2ff7ba116292d732f00eb0ed8e465d15" +dependencies = [ + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode-derive", + "scale-info", + "smallvec", + "thiserror", +] + +[[package]] +name = "scale-decode-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4391f0dfbb6690f035f6d2a15d6a12f88cc5395c36bcc056db07ffa2a90870ec" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scale-encode" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d823d4be477fc33321f93d08fb6c2698273d044f01362dc27573a750deb7c233" +checksum = "b0401b7cdae8b8aa33725f3611a051358d5b32887ecaa0fda5953a775b2d4d76" dependencies = [ "parity-scale-codec", + "primitive-types", "scale-bits", + "scale-encode-derive", "scale-info", + "smallvec", "thiserror", ] +[[package]] +name = "scale-encode-derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "316e0fb10ec0fee266822bd641bab5e332a4ab80ef8c5b5ff35e5401a394f5a6" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "scale-info" version = "2.9.0" @@ -4917,15 +5259,18 @@ dependencies = [ [[package]] name = "scale-value" -version = "0.6.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a5e7810815bd295da73e4216d1dfbced3c7c7c7054d70fa5f6e4c58123fff4" +checksum = "f2096d36e94ce9bf87d8addb752423b6b19730dc88edd7cc452bb2b90573f7a7" dependencies = [ + "base58", + "blake2", "either", - "frame-metadata", + "frame-metadata 15.1.0", "parity-scale-codec", "scale-bits", "scale-decode", + "scale-encode", "scale-info", "serde", "thiserror", @@ -4989,9 +5334,9 @@ dependencies = [ [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" @@ -5027,9 +5372,9 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -5077,9 +5422,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -5090,9 +5435,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -5109,9 +5454,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" dependencies = [ "serde", ] @@ -5136,31 +5481,31 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.167" +version = "1.0.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daf513456463b42aa1d94cff7e0c24d682b429f020b9afa4f5ba5c40a22b237" +checksum = "76dc28c9523c5d70816e393136b86d48909cfb27cecaa902d338c19ed47164dc" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.11" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a16be4fe5320ade08736447e3198294a5ea9a6d44dde6f35f0a5e06859c427a" +checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.167" +version = "1.0.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b69b106b68bc8054f0e974e70d19984040f8a5cf9215ca82626ea4853f82c4b9" +checksum = "a4e7b8c5dc823e3b90651ff1d3808419cd14e5ad76de04feaf37da114e7a306f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -5174,9 +5519,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.100" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f1e14e89be7aa4c4b78bdbdc9eb5bf8517829a600ae8eaa39a6e1d960b5185c" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ "itoa", "ryu", @@ -5228,7 +5573,7 @@ dependencies = [ "serde", "serde_json", "serde_with_macros", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -5237,10 +5582,10 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.1", + "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -5339,9 +5684,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ "libc", "signal-hook-registry", @@ -5418,6 +5763,120 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +[[package]] +name = "smol" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +dependencies = [ + "async-channel", + "async-executor", + "async-fs", + "async-io", + "async-lock", + "async-net", + "async-process", + "blocking", + "futures-lite", +] + +[[package]] +name = "smoldot" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cce5e2881b30bad7ef89f383a816ad0b22c45915911f28499026de4a76d20ee" +dependencies = [ + "arrayvec 0.7.4", + "async-lock", + "atomic", + "base64 0.21.2", + "bip39", + "blake2-rfc", + "bs58 0.5.0", + "crossbeam-queue", + "derive_more", + "ed25519-zebra", + "either", + "event-listener", + "fnv", + "futures-channel", + "futures-util", + "hashbrown 0.14.0", + "hex 0.4.3", + "hmac 0.12.1", + "itertools", + "libsecp256k1", + "merlin 3.0.0", + "no-std-net", + "nom 7.1.3", + "num-bigint", + "num-rational", + "num-traits", + "pbkdf2 0.12.2", + "pin-project", + "rand 0.8.5", + "rand_chacha 0.3.1", + "ruzstd", + "schnorrkel 0.10.2", + "serde", + "serde_json", + "sha2 0.10.7", + "siphasher", + "slab", + "smallvec", + "smol", + "snow", + "soketto", + "tiny-keccak", + "twox-hash", + "wasmi", +] + +[[package]] +name = "smoldot-light" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2f7b4687b83ff244ef6137735ed5716ad37dcdf3ee16c4eb1a32fb9808fa47" +dependencies = [ + "async-lock", + "blake2-rfc", + "derive_more", + "either", + "event-listener", + "fnv", + "futures-channel", + "futures-util", + "hashbrown 0.14.0", + "hex 0.4.3", + "itertools", + "log", + "lru", + "parking_lot 0.12.1", + "rand 0.8.5", + "serde", + "serde_json", + "siphasher", + "slab", + "smol", + "smoldot", +] + +[[package]] +name = "snow" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ccba027ba85743e09d15c03296797cad56395089b832b48b5a5217880f57733" +dependencies = [ + "aes-gcm 0.9.4", + "blake2", + "chacha20poly1305", + "curve25519-dalek 4.0.0-rc.1", + "rand_core 0.6.4", + "rustc_version 0.4.0", + "sha2 0.10.7", + "subtle", +] + [[package]] name = "socket2" version = "0.4.9" @@ -5445,9 +5904,9 @@ dependencies = [ [[package]] name = "solang-parser" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a94494913728908efa7a25a2dd2e4f037e714897985c24273c40596638ed909" +checksum = "9c792fe9fae2a2f716846f214ca10d5a1e21133e0bf36cef34bcc4a852467b21" dependencies = [ "itertools", "lalrpop", @@ -5459,9 +5918,9 @@ dependencies = [ [[package]] name = "sp-application-crypto" -version = "17.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f08604ba4bd856311946722958711a08bded5c929e1227f7a697c58deb09468" +checksum = "899492ea547816d5dfe9a5a2ecc32f65a7110805af6da3380aa4902371b31dc2" dependencies = [ "parity-scale-codec", "scale-info", @@ -5473,9 +5932,9 @@ dependencies = [ [[package]] name = "sp-arithmetic" -version = "12.0.0" +version = "16.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7796939f2e3b68a3b9410ea17a2063b78038cd366f57fa772dd3be0798bd3412" +checksum = "bb6020576e544c6824a51d651bc8df8e6ab67cd59f1c9ac09868bb81a5199ded" dependencies = [ "integer-sqrt", "num-traits", @@ -5488,15 +5947,15 @@ dependencies = [ [[package]] name = "sp-core" -version = "16.0.0" +version = "21.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c96dc3debbe5c22ebf18f99e6a53199efe748e6e584a1902adb88cbad66ae7c" +checksum = "f18d9e2f67d8661f9729f35347069ac29d92758b59135176799db966947a7336" dependencies = [ "array-bytes", - "base58", "bitflags 1.3.2", "blake2", "bounded-collections", + "bs58 0.4.0", "dyn-clonable", "ed25519-zebra", "futures", @@ -5509,6 +5968,7 @@ dependencies = [ "merlin 2.0.1", "parity-scale-codec", "parking_lot 0.12.1", + "paste", "primitive-types", "rand 0.8.5", "regex", @@ -5532,11 +5992,11 @@ dependencies = [ [[package]] name = "sp-core-hashing" -version = "6.0.0" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc2d1947252b7a4e403b0a260f596920443742791765ec111daa2bbf98eff25" +checksum = "2ee599a8399448e65197f9a6cee338ad192e9023e35e31f22382964c3c174c68" dependencies = [ - "blake2", + "blake2b_simd", "byteorder", "digest 0.10.7", "sha2 0.10.7", @@ -5547,20 +6007,20 @@ dependencies = [ [[package]] name = "sp-debug-derive" -version = "6.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fb9dc63d54de7d7bed62a505b6e0bd66c122525ea1abb348f6564717c3df2d" +checksum = "c7f531814d2f16995144c74428830ccf7d94ff4a7749632b83ad8199b181140c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.27", ] [[package]] name = "sp-externalities" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57052935c9c9b070ea6b339ef0da3bf241b7e065fc37f9c551669ee83ecfc3c1" +checksum = "a0f71c671e01a8ca60da925d43a1b351b69626e268b8837f8371e320cf1dd100" dependencies = [ "environmental", "parity-scale-codec", @@ -5570,9 +6030,9 @@ dependencies = [ [[package]] name = "sp-io" -version = "17.0.0" +version = "23.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578959f9a7e44fd2dd96e8b8bc893cea04fcd7c00a4ffbb0b91c5013899dd02b" +checksum = "9d597e35a9628fe7454b08965b2442e3ec0f264b0a90d41328e87422cec02e99" dependencies = [ "bytes", "ed25519", @@ -5581,6 +6041,7 @@ dependencies = [ "libsecp256k1", "log", "parity-scale-codec", + "rustversion", "secp256k1", "sp-core", "sp-externalities", @@ -5596,28 +6057,25 @@ dependencies = [ [[package]] name = "sp-keyring" -version = "18.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc13a168cdc15e185db5cbe8644e3eaafa534e229593768b3044b60bea00fc8c" +checksum = "4673405248580504a8bc4e09615ab25ccb182dfaccd27e000fda9dcb2ca1dab1" dependencies = [ "lazy_static", "sp-core", "sp-runtime", - "strum", + "strum 0.24.1", ] [[package]] name = "sp-keystore" -version = "0.22.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "480dbd54b281c638209fbcfce69902b82a0a1af0e22219d46825eadced3136b6" +checksum = "9be3cdd67cc1d9c1db17c5cbc4ec4924054a8437009d167f21f6590797e4aa45" dependencies = [ - "async-trait", "futures", - "merlin 2.0.1", "parity-scale-codec", "parking_lot 0.12.1", - "schnorrkel 0.9.1", "sp-core", "sp-externalities", "thiserror", @@ -5625,9 +6083,9 @@ dependencies = [ [[package]] name = "sp-panic-handler" -version = "6.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4abed79c3d5b3622f65ab065676addd9923b9b122cd257df23e2757ce487c6d2" +checksum = "ebd2de46003fa8212426838ca71cd42ee36a26480ba9ffea983506ce03131033" dependencies = [ "backtrace", "lazy_static", @@ -5636,9 +6094,9 @@ dependencies = [ [[package]] name = "sp-runtime" -version = "18.0.0" +version = "24.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8ab2fd44668d3e8674e2253a43852857a47d49be7db737e98bf157e4bcebefd" +checksum = "21c5bfc764a1a8259d7e8f7cfd22c84006275a512c958d3ff966c92151e134d5" dependencies = [ "either", "hash256-std-hasher", @@ -5659,9 +6117,9 @@ dependencies = [ [[package]] name = "sp-runtime-interface" -version = "13.0.0" +version = "17.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb7707246cee4967a8cc71e3ef0e82f562e8b1020606447a6a12b99c7c1b443" +checksum = "6e676128182f90015e916f806cba635c8141e341e7abbc45d25525472e1bbce8" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -5678,22 +6136,22 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" -version = "9.0.0" +version = "11.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2773c90e5765847c5e8b4a24b553d38a9ca52ded47c142cfcfb7948f42827af9" +checksum = "a5d5bd5566fe5633ec48dfa35ab152fd29f8a577c21971e1c6db9f28afb9bbb9" dependencies = [ "Inflector", "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.27", ] [[package]] name = "sp-state-machine" -version = "0.22.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c957b8b4c252507c12674948db427c5e34fd1760ce256922f1ec5f89f781a4f" +checksum = "9ef45d31f9e7ac648f8899a0cd038a3608f8499028bff55b6c799702592325b6" dependencies = [ "hash-db", "log", @@ -5712,15 +6170,15 @@ dependencies = [ [[package]] name = "sp-std" -version = "6.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af0ee286f98455272f64ac5bb1384ff21ac029fbb669afbaf48477faff12760e" +checksum = "53458e3c57df53698b3401ec0934bea8e8cfce034816873c0b0abbd83d7bac0d" [[package]] name = "sp-storage" -version = "11.0.0" +version = "13.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c20cb0c562d1a159ecb2c7ca786828c81e432c535474967d2df3a484977cea4" +checksum = "94294be83f11d4958cfea89ed5798f0b6605f5defc3a996948848458abbcc18e" dependencies = [ "impl-serde", "parity-scale-codec", @@ -5732,9 +6190,9 @@ dependencies = [ [[package]] name = "sp-tracing" -version = "8.0.0" +version = "10.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46bd547da89a9cda69b4ce4c91a5b7e1f86915190d83cd407b715d0c6bac042" +checksum = "357f7591980dd58305956d32f8f6646d0a8ea9ea0e7e868e46f53b68ddf00cec" dependencies = [ "parity-scale-codec", "sp-std", @@ -5745,13 +6203,13 @@ dependencies = [ [[package]] name = "sp-trie" -version = "16.0.0" +version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8efbe5b6d29a18fea7c2f52e0098135f2f864b31d335d5105b40a349866ba874" +checksum = "48e4eeb7ef23f79eba8609db79ef9cef242f994f1f87a3c0387b4b5f177fda74" dependencies = [ "ahash 0.8.3", "hash-db", - "hashbrown 0.12.3", + "hashbrown 0.13.2", "lazy_static", "memory-db", "nohash-hasher", @@ -5769,24 +6227,23 @@ dependencies = [ [[package]] name = "sp-wasm-interface" -version = "10.0.0" +version = "14.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbc05650b6338808892a7b04f0c56bb1f7f928bfa9ac58e0af2c1e5bef33229" +checksum = "a19c122609ca5d8246be6386888596320d03c7bc880959eaa2c36bcd5acd6846" dependencies = [ "anyhow", "impl-trait-for-tuples", "log", "parity-scale-codec", "sp-std", - "wasmi", "wasmtime", ] [[package]] name = "sp-weights" -version = "14.0.0" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ebab7696f915aa548494aef3ca8d15217baf10458fe6edb87e60587a47de358" +checksum = "45d084c735544f70625b821c3acdbc7a2fc1893ca98b85f1942631284692c75b" dependencies = [ "parity-scale-codec", "scale-info", @@ -5804,6 +6261,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.7.2" @@ -5924,7 +6387,16 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "strum_macros", + "strum_macros 0.24.3", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.1", ] [[package]] @@ -5940,6 +6412,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "strum_macros" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.27", +] + [[package]] name = "substrate-bip39" version = "0.4.4" @@ -5967,24 +6452,24 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "subxt" -version = "0.27.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54639dba6a113584083968b6a8f457dedae612abe1bd214762101ca29f12e332" +checksum = "0ba02ada83ba2640c46e200a1758cc83ce876a16326d2c52ca5db41b7d6645ce" dependencies = [ "base58", "blake2", "derivative", - "frame-metadata", + "either", + "frame-metadata 16.0.0", "futures", - "getrandom 0.2.10", "hex 0.4.3", "impl-serde", "jsonrpsee", "parity-scale-codec", - "parking_lot 0.12.1", "primitive-types", "scale-bits", "scale-decode", + "scale-encode", "scale-info", "scale-value", "serde", @@ -5992,6 +6477,7 @@ dependencies = [ "sp-core", "sp-core-hashing", "sp-runtime", + "subxt-lightclient", "subxt-macro", "subxt-metadata", "thiserror", @@ -6000,47 +6486,64 @@ dependencies = [ [[package]] name = "subxt-codegen" -version = "0.27.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e86cb719003f1cedf2710a6e55ca4c37aba4c989bbd3b81dd1c52af9e4827e" +checksum = "3213eb04567e710aa253b94de74337c7b663eea52114805b8723129763282779" dependencies = [ - "darling 0.14.4", - "frame-metadata", + "frame-metadata 16.0.0", "heck", "hex 0.4.3", "jsonrpsee", "parity-scale-codec", - "proc-macro-error", "proc-macro2", "quote", "scale-info", "subxt-metadata", - "syn 1.0.109", + "syn 2.0.27", + "thiserror", "tokio", ] +[[package]] +name = "subxt-lightclient" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a235bedd0e460c110e5341d919ec3a27f9be3dd4c1c944daad8a9b54d396d" +dependencies = [ + "futures", + "futures-util", + "serde", + "serde_json", + "smoldot-light", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + [[package]] name = "subxt-macro" -version = "0.27.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74c08de402a78c4c06c3ee3702c80e519efdcb65911348e018b6998d04404916" +checksum = "cfda460cc5f701785973382c589e9bb12c23bb8d825bfc3ac547b7c672aba1c0" dependencies = [ - "darling 0.14.4", + "darling 0.20.3", "proc-macro-error", "subxt-codegen", - "syn 1.0.109", + "syn 2.0.27", ] [[package]] name = "subxt-metadata" -version = "0.27.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593ab5f53435e6352675af4f9851342607f37785d84c7a3fb3139550d3c35f0" +checksum = "0283bd02163913fbd0a5153d0b179533e48b239b953fa4e43baa27c73f18861c" dependencies = [ - "frame-metadata", + "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", "sp-core-hashing", + "thiserror", ] [[package]] @@ -6144,7 +6647,7 @@ dependencies = [ "home", "once_cell", "reqwest", - "semver 1.0.17", + "semver 1.0.18", "serde", "serde_json", "sha2 0.10.7", @@ -6166,9 +6669,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.23" +version = "2.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59fb7d6d8281a51045d62b8eb3a7d1ce347b76f312af50cd3dc0af39c87c1737" +checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" dependencies = [ "proc-macro2", "quote", @@ -6183,9 +6686,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +checksum = "ec96d2ffad078296368d46ff1cb309be1c23c513b4ab0e22a45de0185275ac96" dependencies = [ "filetime", "libc", @@ -6194,21 +6697,20 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.8" +version = "0.12.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1c7f239eb94671427157bd93b3694320f3668d4e1eff08c7285366fd777fac" +checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ - "autocfg", "cfg-if", - "fastrand", + "fastrand 2.0.0", "redox_syscall 0.3.5", - "rustix 0.37.23", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -6234,22 +6736,42 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] +[[package]] +name = "thiserror-core" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d97345f6437bb2004cd58819d8a9ef8e36cdd7661c2abc4bbde0a7c40d9f497" +dependencies = [ + "thiserror-core-impl", +] + +[[package]] +name = "thiserror-core-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10ac1c5050e43014d16b2f94d0d2ce79e65ffdd8b38d8048f9c8f6a8a6da62ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "thiserror-impl" -version = "1.0.43" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -6312,16 +6834,16 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ "itoa", "libc", "num_threads", "serde", "time-core", - "time-macros 0.2.9", + "time-macros 0.2.10", ] [[package]] @@ -6342,9 +6864,9 @@ dependencies = [ [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -6433,7 +6955,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -6464,7 +6986,18 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.3", + "rustls 0.21.5", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.10", "tokio", ] @@ -6476,7 +7009,7 @@ checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" dependencies = [ "futures-util", "log", - "rustls 0.21.3", + "rustls 0.21.5", "tokio", "tokio-rustls 0.24.1", "tungstenite", @@ -6521,9 +7054,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.12" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c500344a19072298cd05a7224b3c0c629348b78692bf48466c5238656e315a78" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap 2.0.0", "serde", @@ -6558,7 +7091,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -6640,12 +7173,12 @@ dependencies = [ [[package]] name = "trie-db" -version = "0.24.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "004e1e8f92535694b4cb1444dc5a8073ecf0815e3357f729638b9f8fc4062908" +checksum = "767abe6ffed88a1889671a102c2861ae742726f52e0a5a425b92c9fbfa7e9c85" dependencies = [ "hash-db", - "hashbrown 0.12.3", + "hashbrown 0.13.2", "log", "rustc-hex", "smallvec", @@ -6653,9 +7186,9 @@ dependencies = [ [[package]] name = "trie-root" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a36c5ca3911ed3c9a5416ee6c679042064b93fc637ded67e25f92e68d783891" +checksum = "d4ed310ef5ab98f5fa467900ed906cb9232dd5376597e00fd4cba2a449d06c0b" dependencies = [ "hash-db", ] @@ -6679,7 +7212,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.3", + "rustls 0.21.5", "sha1 0.10.5", "thiserror", "url", @@ -6734,9 +7267,9 @@ checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22049a19f4a68748a168c0fc439f9516686aa045927ff767eca0a85101fb6e73" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unicode-normalization" @@ -6853,7 +7386,7 @@ checksum = "bbc5ad0d9d26b2c49a5ab7da76c3e79d3ee37e7821799f8223fcb8f2f391a2e7" dependencies = [ "anyhow", "rustversion", - "time 0.3.22", + "time 0.3.23", ] [[package]] @@ -6928,7 +7461,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", "wasm-bindgen-shared", ] @@ -6962,7 +7495,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6975,52 +7508,60 @@ checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" [[package]] name = "wasmi" -version = "0.13.2" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06c326c93fbf86419608361a2c925a31754cf109da1b8b55737070b4d6669422" +checksum = "e51fb5c61993e71158abf5bb863df2674ca3ec39ed6471c64f07aeaf751d67b4" dependencies = [ - "parity-wasm", - "wasmi-validation", + "intx", + "smallvec", + "spin 0.9.8", + "wasmi_arena", "wasmi_core", + "wasmparser-nostd", ] [[package]] -name = "wasmi-validation" -version = "0.5.0" +name = "wasmi_arena" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ff416ad1ff0c42e5a926ed5d5fab74c0f098749aa0ad8b2a34b982ce0e867b" -dependencies = [ - "parity-wasm", -] +checksum = "401c1f35e413fac1846d4843745589d9ec678977ab35a384db8ae7830525d468" [[package]] name = "wasmi_core" -version = "0.2.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d20cb3c59b788653d99541c646c561c9dd26506f25c0cebfe810659c54c6d7" +checksum = "624e6333e861ef49095d2d678b76ebf30b06bf37effca845be7e5b87c90071b7" dependencies = [ "downcast-rs", - "libm", - "memory_units", - "num-rational", + "libm 0.2.7", "num-traits", + "paste", ] [[package]] name = "wasmparser" -version = "0.96.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adde01ade41ab9a5d10ec8ed0bb954238cf8625b5cd5a13093d6de2ad9c2be1a" +checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b" dependencies = [ "indexmap 1.9.3", "url", ] +[[package]] +name = "wasmparser-nostd" +version = "0.100.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9157cab83003221bfd385833ab587a039f5d6fa7304854042ba358a3b09e0724" +dependencies = [ + "indexmap-nostd", +] + [[package]] name = "wasmtime" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49ffcc607adc9da024e87ca814592d4bc67f5c5b58e488f5608d5734a1ebc23e" +checksum = "f907fdead3153cb9bfb7a93bbd5b62629472dc06dee83605358c64c52ed3dda9" dependencies = [ "anyhow", "bincode", @@ -7028,7 +7569,7 @@ dependencies = [ "indexmap 1.9.3", "libc", "log", - "object 0.29.0", + "object 0.30.4", "once_cell", "paste", "psm", @@ -7038,30 +7579,30 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit", "wasmtime-runtime", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "wasmtime-asm-macros" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cb5dc4d79cd7b2453c395f64e9013d2ad90bd083be556d5565cb224ebe8d57" +checksum = "d3b9daa7c14cd4fa3edbf69de994408d5f4b7b0959ac13fa69d465f6597f810d" dependencies = [ "cfg-if", ] [[package]] name = "wasmtime-environ" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9350c919553cddf14f78f9452119c8004d7ef6bfebb79a41a21819ed0c5604d8" +checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949" dependencies = [ "anyhow", "cranelift-entity", - "gimli 0.26.2", + "gimli", "indexmap 1.9.3", "log", - "object 0.29.0", + "object 0.30.4", "serde", "target-lexicon", "thiserror", @@ -7071,52 +7612,52 @@ dependencies = [ [[package]] name = "wasmtime-jit" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ba5779ea786386432b94c9fc9ad5597346c319e8239db0d98d5be5cc109a7e" +checksum = "0de48df552cfca1c9b750002d3e07b45772dd033b0b206d5c0968496abf31244" dependencies = [ - "addr2line 0.17.0", + "addr2line 0.19.0", "anyhow", "bincode", "cfg-if", "cpp_demangle", - "gimli 0.26.2", + "gimli", "log", - "object 0.29.0", + "object 0.30.4", "rustc-demangle", "serde", "target-lexicon", "wasmtime-environ", "wasmtime-jit-icache-coherence", "wasmtime-runtime", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "wasmtime-jit-debug" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9841a44c82c74101c10ad4f215392761a2523b3c6c838597962bdb6de75fdb3" +checksum = "6e0554b84c15a27d76281d06838aed94e13a77d7bf604bbbaf548aa20eb93846" dependencies = [ "once_cell", ] [[package]] name = "wasmtime-jit-icache-coherence" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd4356c2493002da3b111d470c2ecea65a3017009afce8adc46eaa5758739891" +checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd" dependencies = [ "cfg-if", "libc", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "wasmtime-runtime" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd26efea7a790fcf430e663ba2519f0ab6eb8980adf8b0c58c62b727da77c2ec" +checksum = "658cf6f325232b6760e202e5255d823da5e348fdea827eff0a2a22319000b441" dependencies = [ "anyhow", "cc", @@ -7126,21 +7667,21 @@ dependencies = [ "log", "mach", "memfd", - "memoffset 0.6.5", + "memoffset 0.8.0", "paste", "rand 0.8.5", "rustix 0.36.15", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "wasmtime-types" -version = "5.0.1" +version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e1e4f66a2b9a114f9def450ab9971828c968db6ea6fccd613724b771fa4913" +checksum = "a4f6fffd2a1011887d57f07654dd112791e872e3ff4a2e626aee8059ee17f06f" dependencies = [ "cranelift-entity", "serde", @@ -7245,21 +7786,6 @@ dependencies = [ "windows-targets 0.48.1", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -7394,9 +7920,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.8" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9482fe6ceabdf32f3966bfdd350ba69256a97c30253dc616fe0005af24f164e" +checksum = "25b5872fa2e10bd067ae946f927e726d7d603eaeb6e02fa6a350e0722d2b8c11" dependencies = [ "memchr", ] @@ -7455,9 +7981,9 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" [[package]] name = "yap" -version = "0.7.2" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc77f52dc9e9b10d55d3f4462c3b7fc393c4f17975d641542833ab2d3bc26ef" +checksum = "e2a7eb6d82a11e4d0b8e6bda8347169aff4ccd8235d039bba7c47482d977dcf7" [[package]] name = "zeroize" @@ -7476,7 +8002,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.23", + "syn 2.0.27", ] [[package]] @@ -7488,14 +8014,14 @@ dependencies = [ "aes 0.8.3", "byteorder", "bzip2", - "constant_time_eq", + "constant_time_eq 0.1.5", "crc32fast", "crossbeam-utils", "flate2", "hmac 0.12.1", "pbkdf2 0.11.0", "sha1 0.10.5", - "time 0.3.22", + "time 0.3.23", "zstd", ] diff --git a/chains/astar/config/Cargo.toml b/chains/astar/config/Cargo.toml index 0fa38ab8..0a490066 100644 --- a/chains/astar/config/Cargo.toml +++ b/chains/astar/config/Cargo.toml @@ -9,3 +9,4 @@ description = "Polkadot configuration." [dependencies] anyhow = "1.0.69" rosetta-core = { version = "0.4.0", path = "../../../rosetta-core" } +subxt = "0.30" diff --git a/chains/astar/config/res/astar-dev.scale b/chains/astar/config/res/astar-dev.scale new file mode 100644 index 0000000000000000000000000000000000000000..7124fa3da121655ab7f61a446059634ad497b266 GIT binary patch literal 171371 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 literal 0 HcmV?d00001 diff --git a/chains/astar/config/src/lib.rs b/chains/astar/config/src/lib.rs index 84bd47fd..9751d16d 100644 --- a/chains/astar/config/src/lib.rs +++ b/chains/astar/config/src/lib.rs @@ -5,6 +5,12 @@ use rosetta_core::{ }; use std::sync::Arc; +// Generate an interface that we can use from the node's metadata. +pub mod metadata { + #[subxt::subxt(runtime_metadata_path = "res/astar-dev.scale")] + pub mod dev {} +} + pub fn config(network: &str) -> Result { anyhow::ensure!(network == "dev"); Ok(BlockchainConfig { @@ -19,14 +25,14 @@ pub fn config(network: &str) -> Result { currency_symbol: "ASTR", currency_decimals: 18, node_uri: NodeUri::parse("ws://127.0.0.1:9944")?, - node_image: "staketechnologies/astar-collator:latest", + node_image: "staketechnologies/astar-collator:v5.15.0", node_command: Arc::new(|network, port| { vec![ "astar-collator".into(), format!("--chain={network}"), "--rpc-cors=all".into(), - "--ws-external".into(), - format!("--ws-port={port}"), + "--rpc-external".into(), + format!("--rpc-port={port}"), "--alice".into(), "--tmp".into(), "--enable-evm-rpc".into(), diff --git a/chains/astar/server/Cargo.toml b/chains/astar/server/Cargo.toml index 3094c3db..ecc5e7ad 100644 --- a/chains/astar/server/Cargo.toml +++ b/chains/astar/server/Cargo.toml @@ -11,20 +11,20 @@ anyhow = "1.0.69" async-std = { version = "1.12.0", features = ["tokio1"] } async-trait = "0.1.66" ethers = "2.0.7" +hex = "0.4.3" parity-scale-codec = "3.4.0" rosetta-config-astar = { version = "0.4.0", path = "../config" } rosetta-config-ethereum = { version = "0.4.0", path = "../../ethereum/config" } rosetta-server = { version = "0.4.0", path = "../../../rosetta-server" } rosetta-server-ethereum = { version = "0.4.0", path = "../../ethereum/server" } serde_json = "1.0.94" -sp-core = { version = "16.0.0", default-features = false, features = ["blake2", "std"] } -sp-keyring = "18.0.0" -subxt = "0.27.1" +sp-core = { version = "21.0.0", default-features = false, features = ["blake2", "std"] } +sp-keyring = "24.0.0" +subxt = { version = "0.30", features = ["substrate-compat"] } tokio = { version = "1.26.0", features = ["rt-multi-thread", "macros"] } [dev-dependencies] ethers-solc = "2.0.1" -hex = "0.4.3" rosetta-client = { version = "0.4.0", path = "../../../rosetta-client" } rosetta-docker = { version = "0.4.0", path = "../../../rosetta-docker" } rosetta-server = { version = "0.4.0", path = "../../../rosetta-server", features = ["tests"] } diff --git a/chains/astar/server/src/lib.rs b/chains/astar/server/src/lib.rs index 256f6dbf..f1eba76d 100644 --- a/chains/astar/server/src/lib.rs +++ b/chains/astar/server/src/lib.rs @@ -1,7 +1,12 @@ -use anyhow::Result; +use anyhow::{Context, Result}; use ethers::prelude::*; +use parity_scale_codec::Decode; +use rosetta_config_astar::metadata::{ + dev as astar_metadata, + dev::runtime_types::{frame_system::AccountInfo, pallet_balances::types::AccountData}, +}; use rosetta_config_ethereum::{EthereumMetadata, EthereumMetadataParams}; -use rosetta_server::crypto::address::Address; +use rosetta_server::crypto::address::{Address, AddressFormat}; use rosetta_server::crypto::PublicKey; use rosetta_server::types::{ Block, BlockIdentifier, CallRequest, Coin, PartialBlockIdentifier, Transaction, @@ -10,10 +15,53 @@ use rosetta_server::types::{ use rosetta_server::{BlockchainClient, BlockchainConfig}; use rosetta_server_ethereum::EthereumClient; use serde_json::Value; +use sp_core::crypto::Ss58AddressFormat; +use subxt::{ + dynamic::Value as SubtxValue, rpc::types::BlockNumber, tx::PairSigner, utils::AccountId32, + OnlineClient, PolkadotConfig, +}; pub struct AstarClient { client: EthereumClient, - addr: String, + ws_client: OnlineClient, +} + +impl AstarClient { + async fn account_info( + &self, + address: &Address, + maybe_block: Option<&BlockIdentifier>, + ) -> Result>> { + let account: AccountId32 = address + .address() + .parse() + .map_err(|err| anyhow::anyhow!("{}", err)) + .context("invalid address")?; + + // Build a dynamic storage query to iterate account information. + let storage_query = + subxt::dynamic::storage("System", "Account", vec![SubtxValue::from_bytes(account)]); + + let block_hash = { + let block_number = maybe_block.map(|block| BlockNumber::from(block.index)); + self.ws_client + .rpc() + .block_hash(block_number) + .await? + .ok_or_else(|| anyhow::anyhow!("no block hash found"))? + }; + + let account_info = self + .ws_client + .storage() + .at(block_hash) + .fetch(&storage_query) + .await? + .ok_or_else(|| anyhow::anyhow!("account not found"))?; + + >>::decode(&mut account_info.encoded()) + .map_err(|_| anyhow::anyhow!("invalid format")) + } } #[async_trait::async_trait] @@ -27,17 +75,22 @@ impl BlockchainClient for AstarClient { async fn new(config: BlockchainConfig, addr: &str) -> Result { // TODO: Fix this hack, need to support multiple addresses per node - let ethereum_uri = if let Some(addr_without_scheme) = addr.strip_prefix("ws://") { - format!("http://{addr_without_scheme}") + let (http_uri, ws_uri) = if let Some(addr_without_scheme) = addr.strip_prefix("ws://") { + (format!("http://{addr_without_scheme}"), addr.to_string()) } else if let Some(addr_without_scheme) = addr.strip_prefix("wss://") { - format!("https://{addr_without_scheme}") + (format!("https://{addr_without_scheme}"), addr.to_string()) + } else if let Some(addr_without_scheme) = addr.strip_prefix("http://") { + (addr.to_string(), format!("ws://{addr_without_scheme}")) + } else if let Some(addr_without_scheme) = addr.strip_prefix("https://") { + (addr.to_string(), format!("wss://{addr_without_scheme}")) } else { - addr.to_string() + (format!("http://{addr}"), format!("ws://{addr}")) }; - let client = EthereumClient::new(config, ethereum_uri.as_str()).await?; + let ethereum_client = EthereumClient::new(config, http_uri.as_str()).await?; + let substrate_client = OnlineClient::::from_url(ws_uri.as_str()).await?; Ok(Self { - client, - addr: addr.into(), + client: ethereum_client, + ws_client: substrate_client, }) } @@ -58,7 +111,26 @@ impl BlockchainClient for AstarClient { } async fn balance(&self, address: &Address, block: &BlockIdentifier) -> Result { - self.client.balance(address, block).await + let balance = match address.format() { + AddressFormat::Ss58(_) => { + let account_info = self.account_info(address, Some(block)).await?; + account_info.data.free + } + AddressFormat::Eip55 => { + // Frontier `eth_getBalance` returns the reducible_balance instead the free balance: + // https://github.com/paritytech/frontier/blob/polkadot-v0.9.43/frame/evm/src/lib.rs#L853-L855 + // using substrate to get the free balance + let address = address + .evm_to_ss58(Ss58AddressFormat::custom(42)) + .map_err(|err| anyhow::anyhow!("{}", err))?; + let account_info = self.account_info(&address, Some(block)).await?; + account_info.data.free + } + _ => { + return Err(anyhow::anyhow!("invalid address format")); + } + }; + Ok(balance) } async fn coins(&self, address: &Address, block: &BlockIdentifier) -> Result> { @@ -66,37 +138,25 @@ impl BlockchainClient for AstarClient { } async fn faucet(&self, address: &Address, value: u128) -> Result> { - use parity_scale_codec::{Decode, Encode}; - use sp_keyring::AccountKeyring; - use subxt::tx::{PairSigner, StaticTxPayload}; - use subxt::utils::{AccountId32, MultiAddress}; - use subxt::{OnlineClient, PolkadotConfig}; - - #[derive(Decode, Encode, Debug)] - pub struct Transfer { - pub dest: MultiAddress, - #[codec(compact)] - pub value: u128, - } + // convert address + let dest = { + let address: H160 = address.address().parse()?; + let mut data = [0u8; 24]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + let hash = sp_core::hashing::blake2_256(&data); + AccountId32::from(Into::<[u8; 32]>::into(hash)) + }; - let client = OnlineClient::::from_url(&self.addr).await?; + // Build the transfer transaction + let balance_transfer_tx = astar_metadata::tx().balances().transfer(dest.into(), value); + let alice = sp_keyring::AccountKeyring::Alice.pair(); + let signer = PairSigner::::new(alice); - // convert address - let address: H160 = address.address().parse()?; - let mut data = [0u8; 24]; - data[0..4].copy_from_slice(b"evm:"); - data[4..24].copy_from_slice(&address[..]); - let hash = sp_core::hashing::blake2_256(&data); - let address = AccountId32::from(Into::<[u8; 32]>::into(hash)); - // - - let signer = PairSigner::::new(AccountKeyring::Alice.pair()); - let dest: MultiAddress = MultiAddress::Id(address); - let tx = StaticTxPayload::new("Balances", "transfer", Transfer { dest, value }, [0; 32]) - .unvalidated(); - let hash = client + let hash = self + .ws_client .tx() - .sign_and_submit_then_watch_default(&tx, &signer) + .sign_and_submit_then_watch_default(&balance_transfer_tx, &signer) .await? .wait_for_finalized_success() .await? @@ -122,10 +182,10 @@ impl BlockchainClient for AstarClient { async fn block_transaction( &self, - block: &BlockIdentifier, + block_identifier: &BlockIdentifier, tx: &TransactionIdentifier, ) -> Result { - self.client.block_transaction(block, tx).await + self.client.block_transaction(block_identifier, tx).await } async fn call(&self, req: &CallRequest) -> Result { @@ -175,12 +235,14 @@ mod tests { } #[tokio::test] + #[ignore] async fn test_find_transaction() -> Result<()> { let config = rosetta_config_astar::config("dev")?; rosetta_server::tests::find_transaction(config).await } #[tokio::test] + #[ignore] async fn test_list_transactions() -> Result<()> { let config = rosetta_config_astar::config("dev")?; rosetta_server::tests::list_transactions(config).await @@ -215,7 +277,7 @@ mod tests { async fn test_smart_contract() -> Result<()> { let config = rosetta_config_astar::config("dev")?; - let env = Env::new("smart-contract", config.clone()).await?; + let env = Env::new("astar-smart-contract", config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let wallet = env.ephemeral_wallet()?; @@ -249,7 +311,7 @@ mod tests { async fn test_smart_contract_view() -> Result<()> { let config = rosetta_config_astar::config("dev")?; - let env = Env::new("smart-contract-view", config.clone()).await?; + let env = Env::new("astar-smart-contract-view", config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let wallet = env.ephemeral_wallet()?; diff --git a/chains/ethereum/config/src/lib.rs b/chains/ethereum/config/src/lib.rs index 02b43288..200269fa 100644 --- a/chains/ethereum/config/src/lib.rs +++ b/chains/ethereum/config/src/lib.rs @@ -23,6 +23,7 @@ pub fn config(network: &str) -> Result { node_command: Arc::new(|_network, port| { vec![ "--dev".into(), + "--dev.period=1".into(), "--ipcdisable".into(), "--http".into(), "--http.addr=0.0.0.0".into(), diff --git a/chains/ethereum/server/src/lib.rs b/chains/ethereum/server/src/lib.rs index 5ed6be0c..618ed9eb 100644 --- a/chains/ethereum/server/src/lib.rs +++ b/chains/ethereum/server/src/lib.rs @@ -107,6 +107,7 @@ impl BlockchainClient for EthereumClient { .client .send_transaction(tx, None) .await? + .confirmations(2) .await? .unwrap() .transaction_hash @@ -155,6 +156,7 @@ impl BlockchainClient for EthereumClient { .client .send_raw_transaction(Bytes(tx)) .await? + .confirmations(2) .await? .context("Failed to get transaction receipt")? .transaction_hash @@ -382,6 +384,7 @@ mod tests { } #[tokio::test] + #[ignore] async fn test_find_transaction() -> Result<()> { let config = rosetta_config_ethereum::config("dev")?; rosetta_server::tests::find_transaction(config).await @@ -422,7 +425,7 @@ mod tests { async fn test_smart_contract() -> Result<()> { let config = rosetta_config_ethereum::config("dev")?; - let env = Env::new("smart-contract", config.clone()).await?; + let env = Env::new("ethereum-smart-contract", config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let wallet = env.ephemeral_wallet()?; @@ -456,7 +459,7 @@ mod tests { async fn test_smart_contract_view() -> Result<()> { let config = rosetta_config_ethereum::config("dev")?; - let env = Env::new("smart-contract-view", config.clone()).await?; + let env = Env::new("ethereum-smart-contract-view", config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let wallet = env.ephemeral_wallet()?; diff --git a/chains/polkadot/config/Cargo.toml b/chains/polkadot/config/Cargo.toml index 0eb0c9cc..a489da84 100644 --- a/chains/polkadot/config/Cargo.toml +++ b/chains/polkadot/config/Cargo.toml @@ -10,3 +10,4 @@ description = "Polkadot configuration." anyhow = "1.0.69" rosetta-core = { version = "0.4.0", path = "../../../rosetta-core" } serde = { version = "1.0.153", features = ["derive"] } +subxt = "0.30" diff --git a/chains/polkadot/config/res/polkadot-v9430.scale b/chains/polkadot/config/res/polkadot-v9430.scale new file mode 100644 index 0000000000000000000000000000000000000000..6a5c3ea974667cb737ed8b36f7a8e39811509c67 GIT binary patch literal 386413 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

XnOTLuC7B4H6 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 z z!}ki%4zh__btFRl`;)mIq614Vc2 zZV(yYKYhZCBYG<~@h=X?(~c`RE3rE&o&LW^RG22Am+pO&QWfOk;V*0DEizXm z_rRD7<4@f0mtsgrs4pkOS@A>9EC^W>#O&+en)O4ql))lMw!HIX6;JAgI)U6e`ok_bn)M%w)JgP=2hKqD`?+V(54F7w*bwZ2r>vBN2G*McHT+K z>spXQBP2IGQu&vQxRZb?VZWX8diBOe3v(Q&{R6@LxU z;)!zc*?zwc(SEkFUyJ?TC4Bwl*nTYz{_Ze+y?gxN?GN5^n4bUNiG#O)y)8!=XRi8s zzka>nl_)EgLRIyH!D}jmnaRo2oR^>?qzc*-j{{xPIZGPwyG8ZFR{Q0j1Fz@ZpUNUn z^gcQc=MnJuRp4(fd?gF)yJrV}=$yr-T*)~kfIh2_v$(G!pO55bp2Ej2KWUsXh0KX!TKE;x+2N(@S5lpB z4`4MEO`dXQ?ORReJ-JMzofNPe5%u@ZDyST_CXpJP6IcxuK3aJ8e`1kz+t4j`f6g?j zmV`$3JT|zxj87*1&wJ5m6up+tJv)PVZ0v;=RhXFm1hw|AK?v}wvH-*|FE;jBOxo%Z z@82!-!u}q_V?+vOKZl~lg`KnV93@|p6svdp;81k>9L9rXB=G}&kwnq29m$$WNftWT zWIAU?2~_JhlyDN&;{AN?_4@!0BV1>Oc@N?0c@N0^Cf%uWPxqWgJRDnfFx{-Si!3M% zful-1OgWIl!_nd40N~TP)?E|co_*2#N-xN{gbHM+d5lcjZ)jh%e8K6f?7^ao0N2&% zZW%|HFQ_!vt!8jSX*LFQIuy-5zuRo@(KD%PI(WFNyZ}`%*BevuguT+eMZ4~hOz?UcX$%;CONSZ?)k)ktVGHq@@s^PbfP;MUizkx*e^UCiO#BX z-!tR^8vwwN%efp{mZHVKMMt99MeHyv z#66&jDSlgLJnvRy^4<|q^G_(@RJ+}34*;}5$7m&60}%Qn@kddPX8c_+h)Y4_sp0rU zc7L8--+-a?AnQOftf`>K?FFF+qO-pLJR~YRx&ijVhZ(fCZV>&Qhyt%p!EP(Ubxr{> z{Rblbhu!q<`}Mogm5`X&PdlKOyKGR%C(^qSJ$I=Rod{zDM01zU54r^pMl*(cPPaB> z(y8>vN`rda_hj~gq~D{G(e9q7zan%M`3yY>V#wf#0R6lY?o^j9{`aHV3+BXsaksrq zP-Qem3Erjy`O_$mHz;umWrqV{!qW_>zf`* z24UK9EW9r_cX|(WJgR^Tx0A@mhUF|e<+qY z9Av?%P050GeToz=i5?h^@eN&bHf>uMbo2qy(Fcd42mAGqKN~T(>y3wo;|cpzl&g#{ z_ro00v%BQRVT*HQLONj2HYIp!||+Jfaltg8=^=0_1)cUV)7C+h1vj3ax+GOxeVjP(fC5U zUEiBcqQ!W^gp%2-;*;&^ToOHe$UmNw=rCcAkH0&K{?3aO$KQPw&c{7}0;ND+v^gAA zog|(UkYe@eP&Ac|uK?;kYf6g4NyVD~^1fZ1_j;7x0oqkHM^YoBI?Z*mTuy z0W^Imn(%O@8me=c^qXx}?lXr8asQ7E=WF&I9qy^wca)j3$NDEJRgMiu$I{&%=cMsl z8FN=IzFB?lRbeM9a`6Jb63kRBpV}A*16(3Q9%g=rUYD z@LksJH=hc2=)vd& z1HEYePa!Gi??rP=){}*2!Oqd|M>ETy3)I^H=?19y zgXpyD*=(p66d*5FdOCHu`ooB#-|aS8&!X|@tZU2ACvk@ID|k4Hj;GLF;2kUD=be-m zfl-4`rkCJ>lF5sLP@JOLfQ5t$!RV8&tGR~plPlgGWVXOws!}$WZX&#lfqP$`@~ISH zbJ(>H|5L&_8vKC2Z11Hbco(l|cHzCl@tpq3lRYYS_8X$7U8%faS9^?qp1a;3AuoXC z)qfr-bNv?j4ba;#L!n&3Jm%CDK9!zG!A2gJz>MD9#a9z{>N@bi&qvXj@Z}RG?^RC1 z;IrG&x#1Yy=o&XH6ZG^>p$O+hnVuhxo=?9mNO-P~_?z9L-K7JIcHJ%a5$(F0c8hic zn5a~=+Z-Ms+GS3N@r0NGuEeK@_fZfw8aNQ`7?@<8k>CTwJ-hPZ} zJp)IuuK=hl$p;hwbGs2_z_W!*I&Z-7f2HvE>7j!Oe@XP&;ds$FeCVVp9?p>D5kgWB zD~4xOVXa}t^Vg7Waz$Q_m{@5?kA0X@%2b! zAcsjI2X}3|#jxVrgUDY!C++30-t&2L<*y7e4HCg7pCK8rF?~tYJ{Wh`?NeP|Hh{-2^H*JofzRl{!=Y2Xv^AH)S+Yg!K{#SB)XX~P%J zoKcFWH(OSDTi(G_Uv< z>s#52{~Rs3E7HB%{&(ZQL}yLZFSd>*qj`i5!~imcgroQ@;h3qp>M?1LbQ3*?UQSI@ zpC2lirl#fN=;I9sBkmp?@?WD#sQt?ZCImp&r3CA~l!^#cM%;EU%>Pj|4I_594#s!t zZF02sem-UVf75j#IbzTh#w@vCZwE((sNiBSU)eMUeLp^E0q-6d z1evv$S6UWTIrx&kD*^?0h0GHuMS67`}NSPkg0boWSZRynR>sD z`YU95_bAFMWb!Hr#DQkNj_+L~v))f5v)-@oZjH?NZ&M=^ZKiTbPWv+6qkZWn2K}@z z1F`tsv@g>R%XY-!CDES_$Dhd=lY@2odTW|U&^x)N??d#OQ@InR3k@ouK7`?L1cAw` zcXoT#JG;Ouz@UFn@9Ygnd+E`2sdxVJtx@mHfHKY7&1-g+!*4VSZ!2|Pk5cD^;~d8;S|*n{q9^&km#b2UMFRbjJf*gaQtf4rMZ-( zw_itgwz)+hWS;Fh*cW3(R%{GbEMvgpF~cQcCecUldELFPARiYc{O~Xwt2gmK(apG$ zvg6_|*4d6M_)d$A!`yKEXT9qW*vusF`1zgd~-(Gn$)8-ymD?i9M^p6PwHQ>tgpCU z@9y^VHM#ZdvH-`(x!>%s}&7>>S?_Eb;`7yXppcKg8;9JnD^ zzJCvHKi_)W?dNT`pS~(-qgbXA=>)XyVo7`52ztC}x^>ELyZsEXSp9o-`++Lm-R-Au zql2iOA*Ti1P5i%!+t0Tg6@0yR?QaJn+GUmf?mkx8?}`9_e>nPn`fY&#zipM>NiAz| zT1BYY->7ys`rOmqLG4F<-E!Z6RTdKcwpG?tz)3V%xnFe2ecLLl^pnar^tM$NqfY0y zYL!Jq+s7(fe0vb`*n^qgw#p9hrhMBfYc}Y&t+G94-M6i>&WIDel~&mw440R-O@Y4R zGuy3TuHJ3-fp7M~rb(FSjb>qj-bJGlPf$0|oQ{ie7&-0Z>>Xz-w?v8A;2}?- zQX(#sfw0vk3$$vbY3^D~Q(;NIEBw8e zdGC`3k~WVJ4n;oJq8+09-H{O5f6kW;S#?S8S8Goyr%Q25d^$1rjmsD8jzSq+d{d=8 zVupT$No|Ik@+}hKSxzl&o$tgB(r1A-7*e|6yY{9Nq(VGfQXAF$aE)x<@jcq#ip_Ub zH(aMa9YX)f)ht<>JAaqH%6Daq*6wDm#EEO<3W)(sZjtPzG9FmDdToJQG<&;PRldR8 zuGFG`c?QSmo169a%RbTK9ilyS8cL4iQaN>=u0BV}Hf6v5Z`J&)j=rfm6@EBe-q`km z$RR;JH`OPF?htxs71vr@mltkOF-2f@&Nl(#L`O+qlIX}YPjX$0j1|Xb;|NGHF zyUu?XCl$r8CsD3S0)74DO)wDsbhy0g@fACLYu#dmS8kC~cHp5;4Xk zWQ@nhmRlf*2%Au)zSrzvAhZ_*hi}#Qaz7`07(v<~`lsRY2|pB2OwuBvoIP3`JEat- z@{f?M8@+Oz$G(Xvc%ej_v0d#0kfs_M3ilau?N5OK} zB+vam-%$!ip)5a_{ddLYDnxN@cE1}h(GYioQ> zL3g1a;J750p>Tu$y0qO8aU@|y-Q}+! zd=digLt!kke3zIe1x)p)F>xb4iQA>z1n)9>#^wir!tf z>Ob{c#6HQtqV|~e8p^D=N^@KZP9Y2hZlPKx&o-LZcW`C&Lr=Nff20~U*TBZn+6li( z#RMrqGDu_KI+MRx*s5OnfZv8ISN%$WDAg`g0w_1k{XEKeBt6Pqa`Qke3r7hko_I!% zGZxR?-c@{gD0veKT@1QDrAx7WDjMDJsE)kJ4XQhCk?ddIH`+0`bW$`LMW(GQE}&G4 zV#&gnt{@;qf;y*fH%VR$uch;{t6Q71fzmU8bbhDb&|yf`P}6qHWmBm^T_>x>PJ}@W zm2{$^UBe1pTe{g?^pP?;l=*b}ag#9bbF(c$Fsf>ji=yw%~n;6?8vMmjuF zp7$6DK95xDU2tq%!PN8_{|?98q%VGsl7C*P%JtjUf(A_T3^H)J!wUUv^sHyhTK7E8i=eX-Y9;GB72r_vk1(PN>Q~2B zR!sZ5y-{Zv0n(%=q+00)ahdB!>eZR{_nfh zWD?t`@1Z0_LLimI+RNv6m5U5AaXJqQb;ECn@xX@1A@_AUNwSomj>j?g^PWABF+7$@ zrL*2g2CGbycgh0zc}=z_N@lBe+t!Vq^P=1)K6te1d6U5rVKo7cP!|6gYy&_YzRP7w zckq8>cdO<+a_NrzW^@it;Y{ zyB{#TWe0I6`OE#M>?Z{szK^oQgV|M5xWf)bFODP zUa~<~pPpNF9li$?ts2L-(Joa}PTdXqOmhv9W&yQqR$RGj)s5hBYb5!7lRg8UTx;ko-W@Z?Pp&h-^;TR3~lE-BsLAix<;w$rIJ?`*GQnqpfh z>1ZF_&l~a3NO{>aacfHGYS~eH?uBu4l`&%m27&Xm`@a7@Sw(H2?vG`A<_P)ZXY?$|ikba{On?t?bofFldA_*wW6aESO2-XZ(kxFMZ0 zMMhH|oB}Q+LaR;DgU@=|zoR($p9}puf#p_KD0pDBKsQN&WvGyQx#n_c)+T+=V$l1| zu)hi@g^wO=HI#g$??jwL!Jw>WhA}S$Ek*zJ97;YpxSLGFp?$gN)H(yEKTf77ET=tJ zDN_&hEWvauI|B|Rkf!@c;2#+&f6{{)SH>A9jS*&DE5<>sYy&XCy&`AL8K1k@+CVSf z+Pa98qa&V>W|j(!kB(rr@tsN2%OiB<&SbwZl)6>r4INznneBG-){18VLZX0Z;;ZN_ z{5VF_J2qICaBDhYhEZkKWhAoTQy{s~Odd`l?!5-QT|9Ja6_BzoI@MJflBQB4%+b~9 zOR?z>+|c1WH=W&UR@ynpf^d@DsjBUnSmt__7)y$VnW|cyWCey-v9&zMqxS9fPSfft z^<8Nbp_mRDyKSlb)ddw8@}r=Iy|#BQUS&U@RXIdwBKOs*SFg2N8>=FgzHkE7ETvr6 zX0Nv}))ZFbcR$Fvr`xU8rmv4f4`Tfn!@)jFYK#rC+sSyf-?@)5- zZ4cW~1*pr=5|_&L+^xd!r)-J_Lp9cQZ7y`|!;Xi_XA$Akeq}5HFGO)n_%T8Owkr@i zEDSXWF}KtquvC>ao0eY(oSl6W&XoHgCzu*J0s=>u*|9$3>XmwPE$04XdK>8;9~+66?Om@tTiR*u^LC7M ziCai)R&wBQ^0&*fAKSeI!ZjG~N2FJ@(R7-1uUNLv?kCsy=t${6Xtoz`j!itbMG|Y2 z&;*NLw0n=EL6t0$?(ZQo&!daFM#MVFM}ddA#6F!Z{31Vm{JqWD0G$0?@SyO&C=HjoOTLky_pR z4mb(Rv|^YgKMFjM|IARZy_fOUdLN8y` z(_1_)nZDP%As+uA%C2Twekc|%>w5L$N@_uWr*;-Wy*@@w9HZ^Xdo5k3@3_0OVmEGhZ9ycW)ZeGQ?#AO`xi1$0yt~*W2q3O>Q zHe}b&A~l6TFlnZrR^4lgHVGL^N7C9lnoiUo;zZTW*9u&@ansrM zpOCyuNgA@NtB;CArf3wk8gw;Xu2INuVoZR|5spY*Gm9JGCaA5jJ^Np{b+X^-`1~yx zb4-G^FKn0@ymRZXU5d{*n?U^<_{FlGI}Iv3w{ z3z(l~R$K{eCuRyJSg0EA9eMDl>VJy0N%?muU)R<>-Q{})>SSD6T0<2EUE+~#)D$*S zAbvDnW^oR&W?Qiu;N)ftCVXu$ZCYA2F-P)5ns~3YFPHuK%P$mDc_E0Et{54gz0+I+H z*NZV7eNwA0;)J;b*0WEd;p7$V5#Hta4Y6c6pn#>Fw^w8Kob9zY3ia)L0M;BS7qN|P zb=mWqJfnRJ0d9+wb$d99q-QJxnuAvErRisn%Ao}IF>C#@GV|j}Hgll` z1bYH3V_&PaGgy+Gkj`wa*&f_t($mM*;5H>(w6vdXja=Bz0BYXFP9UJ0=YbP_i+xh7 zB5wHF(t4fJ*hOv17G9`r?}dkDR)^>`4Si2#(8U@}9Dg$>|X^9l#j;=dz7x1crtk@=Jbp$dN{`DSN(=5J4JRns61 z)4^skhXX&Qw8Esn5Ks7dMCIgvq~iuJ|Eytk;P|f;x543v3*7eoHUxFBP|1qCp}(8N zpUftoecvN>Js^Wh@6N2|`pUtSd)laV9h0|7^abdtY`xu_&hI22(K;pThZ6~$M{w+| zC6~>e-L56hf~mvylOyG`o&mm2iLDhBB|Dhw3l=NqXCe7XuVicD545G-R{DXq#Yiqi z_Ay!=7!N;4BPV?i>axG*vNR!u9`mxbr_lmPE$NsaO}xlPXUA&*u!xxMbJjdj(Vm!Z zCa#%3L$v_Q(`@t1IbZ_TDxrcxq)N3VBW7EYwJlR%M=-_(6;ln zIG$Ci_fwt=C7n6`@EB&))HXx)>nOQ~|EQ(e6lMpfXXsJAOjqR+s%KuYlDfU3$yo2) z#HgkIP%!bs#_phJ@Q8ZYwyq?80D!>hEw) z^4F*(H<#6iLNR(^_o}#Tqz|pw+4hdE`DsA? zeNps0B?eD7>y5?wPMx{}Bk|-(baGCzh)yBnzaI_Bw*Q@c6O%|7z;;>620_s32h!)$ z)tmIU!W`;XR~OTvNhG+jE1B@koRRq~q$AsmEMSOn4l*ZsPneAOM&>jm|Ep{ca?c>X zZ+B<#1TJ6NmiExcF?D`1EYcso}`uq@ymG-e*ARrto$B|SB;eG%x>56DG0ld>0W~ zI6qYm6=k^~`Y%v(rBY`>WYZPlTCbXs`l@2b$_|=|N~? z5LvR3+!>3hL8EEiiB^i(X_jawju}-KF(iPoSzF$JPN_f7LAGz?u5)S!>(uL*(|tsO z=k~`Jm77$hET9X=ky5&=DMi2PU|tA{nMwi5bHJ8jr-0T<+xotG`og&-6D#Q@)6&%* ziB~`1%4tsXbZvcm9o#f6{>vCgGV~*>)VJ$v#D;V|_F>B_VzI8Sp3Th?TFJo`sv)h`xnBBf#Fg6Ft8K4-;M!gmD?A-m3w|t4 zFS`->earn#ct`J^1;7^_@7b}dtF!)uG3d)m!WJ>IIZ1aJuU^*0o z7Kydv-I;)qOHmVeO}P$-)Gy(`;2WlyHzSLnK)a~VGpdrJ_8P&9z^voK_5S8`n26#b z4Uu2D8pg*y?D*oo8gJQGsFn~aBOWS5*y|D)3YF+a<))K|o;Jm<8ofsy`s)}w& zWXjRrn-)CnLtp(!=)h_4Z<*Am=H}?-Mngr8cwM!Ed(zNjz&4pJ=z~#ma9!>rlwTUz zH$_5#hE5Np#-%Yq?S@RaQuWIDCW>A)zV|(aqBGee9x2q!qqrV9?gdbi> zW3GBhU1jQm#kpasHx0LAZgZGaS;n@=K+xk@6{-G}>scR5x!(J6ghiRsfmnN_dg^`O z&*)2yhKskQ7#Z+Q)y&6`nA|K6-On@x^}!oH*4b$7^g(u|Ie2fCns1_bTyL>kGek{x znk(E@epccWxtA{ZC6Z&Dc=FW`&+I65#>xOSTlq;;RfZ2GZQT~G0S7<_Z-P7s z&V&2K!F_AjyrLA{dL6Twd`R5PVTxsCR0j?joQj`aZ%YT~t*25nZNaT*jv-b)Otpa7 z=#fs)Iydj&79noh8wYA%zDQ|LxszvIYL2$7?k?{qGHMP6KTx`fWqlxUVs62`^I}w) zd>8IPh1QRl)v8Mh>OsdqY&rjrw}6Wx)2=%F z?kNIpaWW_43FdToz&hLhP;4xlX;$=!3%}1pMW7xZ+O0Q80YK0`Pz5y-Fu1ici&?)+ z$2H;#=U)xj2Eq-pl{g3Y>H^j>7sNoQf$4(?^mW%jerfJ6ydJKt6aLkE``*ya8Dejr z%>pRGxL)GF?XW_Xk!#hS8=+n6dn0N~9@g2Z6vk_+fSY3PL5mrX0pw6}G(XMVv?rw( zz!dMcMkkZ89nNwlX5YOfqTI5JTwOiwHx*Xx`g+GIOvohGOHT$NyaBUJO1rTXdh$-H zlXzxRX(NPx98_s52&hz;3S9cm?R6&ZbU_*7sV>vV%~Pwn*@SZfT>Zv6}S8zD@fl355TWeb~{!y@xIu5QXJO6*M}8|CfdVHGX6S< zW5T`K8gJg?mLey&YZQ((l7z<^W;5l}*&n~ym0xjJz88lKC!4XhHb8XCdNutrRc(+4 z-ASZ(({q@HF*fVlva~o;@T#BIDtL%IYNU(f_5H-x>x1$2s{_H4q-u_uNx&GDE;~Zc2Ee)L0n+4^5JrlX)2`-Og8)u+PgaFE_Di8L@$hV5(ch z=xcirbzbH-bcgDB=#uuCT|%5BUk;vJ+kcHqOPE|=*f^Y=epbr@9i^+N&7Veg+h~Gl zz@@lm_2AujI}{{{mRwT zmoV^dTihy8Znc_A{YIRQC$Lgh1iB&1 zdPssIp|^@5qrK-z&t_e*nEbaU!+o`WDYg%EORSmgnDaHt#AdLIIxc+46RvKZD3k3C zmm@4pZJG_(4g-LZe8-u=Gis!plxn&dqQTzGh8?+p(q^v|<@SKmi@9>@hbmXQcO-@D zbZevtVvzq{6IxTQA3M>)oap1PgD0ca zW8=uR@({5O?z3uXmZi%;tPiX$PgFEoSdID2L1FIW~AvQI;q+_vhiU z`oWIp-j-@v=@w#^FCdnBQ_#+O^WYX9`)s6w05XDtH{@0Veh^3oFDkdZ|K)BhTL6eF z8=4P_168C|BO>p$lwfI=rJ)@iKQ~}f+_zTC~1%gid5YIjRX2_0ASQrxf!crWgHb@e1?y!swMfP>vMJ&xdL*V>1bi`_B> zg;*|aL){{iD5R}@6Sn;nUke6Trvj>f-XZE~3D$;Bj;;&L|87_jdPU6*vCM>9AXML zLaCI5ZBsPm#88p!_Ow%x=WymuYlFQn;A(CPQETb9nCd+&VCpY^SCaS-FWu}Fxbl)syD2029LpmhJ;tVIiPa8KJ! zIf&|%Q&rTn?MP>l%918TBpaZHzh%PxyLV24ABE%u}arg~_T?K*!?(tM^qCL|YA&yB`t~YQUMx{m9(yca zaC|cdqI+W|a+p=%Gvj>%2b*qJ%2+#WYo_^H^pE0I*2oJiR3d}84iIjUAi%cb>zsRt zDa4QJs8dJ0=oJ=Q;F*CSP#nyOdgGQ~+}$S2JUF7Tbd2hEUGoE#r?@_#3vNZ* zcICtl`0H71q0KUx8CbO3rLTlj)GaT71ju0>CP)VthMe~3;>;qbS_J?&I5~5zU-zp! zw~j-Y2GtTv(U0)q^T+8gi)@j4ALXy_@4jWL`znX432Du&FRVi_-P&!N-bxZBw2afP zMOetwHrZNPf4|p*S-c0wuD%Xv=>ZaOouvZKU3oL+jv5}9v1JgWT!43 zN_v1CkLRZ@sc8>x(Th@HLEue)%^ZSBoiF>)gKnbtdxlU%=)HGN7Tc)n9#FGKmIbV5 zvEr~k;uLPnwFkxQ%@%dhVO~LpN>3d=Unf<*@P=q=pr6n@>57D4I0fo;NK1hd(x_a4 zAim1}IB#q>2z}em9|e&ST~JLFbHDknOXvA8*dwtIsx@9fgY@Xn!9nACL6`AcEYe zWW6p(HOFn3e1zH(cL4_?Q?2XdC$mens|@GFmcR=@;#ZG4{(<0fJq|=_x=Njg4#a2H zv8N%c+v{Ub|DgQM{_JT;n`MAs;86EtQ17EI`9mX>GV0;dttZCeo4HIAK|dUqt0#SG z{3NHJilV7ATd098XMQRF0-kEjF;sEn{z#(i*-#Yij_g}bDwpr5aspohUku6XK;qIm zZZ*{p?9RQX`o!Z`(YP&}yBS8wrPx1^5@gM#{PXIJz`enR z8n$2cEqzC=_G)!%w*#Asl!b}O(3IoYj@Bl9Bc*1z#~DvMmDY;F!ZOuhOzjy{LWVR= zak3m{?!-M;@Tzt?Q#zj70?*@tf6r4GRFf;7-E_MbyeO3T%t~L8xFO6Ylb$7=di|VD zgmk?q@KH>g)0fXqHSpj}ms+T}btqXjVZw??iQz`lmNGMMtDhxRW0yi_FkW^ilouO7!ur zF)p9Qjo^Y)<6d&%D50FrOb0G!#ZzkvjGvXha!u)&Fix-S%N)=Gs8K0%aR zXFC+2dirVK>qX7_MihO52^=1Z{+zVk`9+RzD6pwBV;-$9ny)EkdCKwBHF?*Wi$U(H zOv<;u=OHv=1w7p8e0n7Q$WpT%G{vC&PG{bC%5(euz9{tr9DjC%`HaKE zP^$H_Biv51E2eZQeZ_SgaE7Cfs3r!Rihr>2o@ ziTSkkdn-oP-23{xj6T{|tR?B;r4kNIiV05`De< zw4GVT6LLZI_`Da;E^_nFbEVl@7u#foN~E*mMW*%YGOS)}?%Zy|qDg)Vu0?H!T9(Af z>$zNA{Il9k4dV~uJo?Mdatp?TlkDJRU6Mu@rBq=+zjsoNA$8=7_ko%0Lv*3{Hi;d_ zeJr79wqC z7<*M5de!I6t6~1yT5MjgqwW*xZIOVjNvQb0UEEz?!x_`MM!K?8gqi?eUh?^sZj@c3 zTATY88OncLRa|jxo^Jm?^whYtoK*WLNuJb}o1GV~N1y(8-h)A|^H7>-*RPc2(nfow zP#DfOz~#`RNP+Z&GqNZ>yS{<^+iXz0=O5@j$h6n(v7+GAm+h#w$ZJc3xk(&=3%@tM zU#q)lNddiu_8WwsDm@9RZ?Z$+FX5bLr^B;b&9$j#+==O*|*2J&3nhlb+fWFs~U-r-v# z(f6}FbfL3$>YO5dCi@5aJrS-{*c&$7l(s-Aw@({?;FVm4?t`Ont{Y8~Ub#^5XfoBo zl+#atI1&?TDHYIszaD_fF}o#!TB^e*hvI4fjblNh=!b2qDQ%8 z{P!axhBKAuC-;mvN)B(#W@zK5SvLQ$jlGv)e0;gpdWLEjQSz5dezQfsc3Su-3s&t$ zC>1V24Fm)$E^20BL+s2R7XzS*lP{zn3Z>WGO9&m{&Se3z(l2NEWWj>MluMRd@g1RD z0MSY%>t=b5g|`|Q##zEGcY`TG**FKwwB$yH#_02~IIdtY%6c21H*j)49Ie@@?qQwF zCRWRioVzg^<7pSRKps_JG-3~Y}L() z#=7#QchH?Q7wu1Q!vr*pY%qHX%wCK-$bRG+L~|~tfhJ4TK*eM|T8gg}pJmO5B9ay` zYJ=u4TzEE#9w^1j`6pS^Lrk=^&n$cAg2*!OZ_dtM(2y)!peFT2-G$rPJEMRY2(ogc; z!U4I2%aWyz?@{6LH`sBTucEfFbBhfi(wAq_faY6L{|)Z}=W}2#Dzz}upEUQLyNxSc=jQsh z8!6UERUGCqhx-?AXr#-F!B3XR6A2m@Y%*Y-hZx62ArF|Wk1ZxfCy>Q$BnqWsM|11e zgbcCdH?4T^hmt?LX!+(vLctt4-*w{{-8S5B=Ik-SL^&G&a&)wm7R-emCUhwa3e0%z zX$T_r4VS%|m=Y0eQ?EK_WfPK(nUL#@wK4*4Co0w=YcCGKHxX-4hdN7e_2OM^?9A3B zX6qv**&Bc@H_ zav5`-*y(eaQXunX&>>3g=qVwt@d2q?QJbd~D<~>!dc1+<1-%cn|EI zXe9aD^Jyw^r#;{dbSo74zNT=s)pPYbq5Uegdt48vsU_5jO3BBv&sAQi@RhY$t`%%_T z>GpyYtYGOXj}S?0G)9yCvlzoi|JIFEi0^ z{*paEd2@H`<#~UTEZM~SEFUk&?;7x-wdtThnfD$Fg!3q4V&_Ap_*1zaPx5m z9|kOL-i{JmHt!iFu6vZYnL~-|Jv)aQNz1b-<|!HJV_~{>*^hu85fkzM!1$Qu>W?;s z5Z6o5hwgcH6(`-2cr|6gcY7yyKCSl9kv|?4Yl=B=3wFhgg`8;I_T< z;Zmkrd-p65@ZnNkH9p;=SDQAO|D&8pQmRDJ$9o1>c3W5IXG!%|J4s%(sHxb+phRS@ zQ4~*!;YDV_1LG5=_|<2YK|SZ{+w&fUp1}<+*PeNPqLfrat5WhOag@9eSGfFt&dlt8 zhCW@2_>XBumFTmApwE?}&-F}q?$Q=c>>D_XTjJUQics$Pq)7*^B5}4Pz!i~*R4#$w zA+?K(?mQC5IA*U6QgTjuQKjACD52kL*-C*T$h<2!nRXj}-j?!(@#wEIA;F_1mzCV` z6Xx%m{Bdy`YzOZK(D7GLUrg%p8K<(Cq9w@$1Of%9IBn0d1j!JDEKGle_oyGRP4p%* zj=nf}T2mUAaD!I6QM~&TK2vjk`;b@H8!Ko&au1^~>G-}N}K19sI%quaAUkxftn$19yRl~%14ThzhB-I;F4MB;R@&sgCU zWTRDUE-5;Qqplu8+7b^r*}@JbxjE#Uvs~WSW=@gF!uy1G;8|9e&8&eRWU7Kys*Ana zTq-)dlRTW9NS`=4u(lX%x;j1AYB>3bfj3N?j=>9z?6Nci*JO+7)J_!mHx?L;lwXRy zea756@tT(-vF-p?Jp@6^70qAD*zc>289MK(mqD}j&D~8nG|W73E!Xzm8|T7ZraDdP zx}96!dLi_#?OipQPmeu@ZME(3QL8uS65|8vrdq$*d?;3Ufkn(rlj@V~-c)UK>1N<;WW> z)L(|L+D$=&Mc8Vu-DjG#|8hn_|ILOw>*xqvw+r%C6Q<4Wyn%Y1h&uzqT&@CX-wDj) z)J_NWP`kd2Wmg2B%>0-AQ!Gk#_0+Z(HK4&(?O43$uIFf1R8H=MkG3+dGoy?(MKNBq zfRlx-#-%Off@btU^6D9KusD%^iwo1S26lA2)}%J)uMDm@O7a~24rT#2&m7yVX*v+g z+d4cSlX2JSk=2MV0FZ&^ojeB<{ciHj^o7YNR-+HbTuhE6gq@qfK8jSSuS`W&W2<~m zc0*F^SxLT}zR6`fHX{T#Dlq1o5dUnixpjLgqJQ!VkokHhikgL`kACwHnPvAh} z>p-xFXIrjthYA+O5uw%)Ti0B3RW^Gr=c_c~!8aUV7iN=%5<{xd; zL;dLbBbnWI$?)r?GHi}`86DsRS%;)ip7WaJ#pVu?RUOsIvuL?C#sBOT;l=UK;76f= ze88`t#p#PEF7Rhov>|*C@A(a5L;h|y`WAl-eY+I#pZLu0$I*A~ukV*;qwkl>!OAnf z*4`sS`y`6><-P5uRe_5Z;|X(op1m4HKgcmpNC;f!UOr}Q#-nGalBbSbK-XP5`P!B9 zEfmD9HOrZuf~J&B$zPlY=+k!@39O!3G%TC)IVn%kVAAk8jSE>Ib0aA4Wf7>2pKsBm z1BdekI_HTa2Dwoz!9+njGRX`bM+K|%aLo4ssspDL0BQqac^axhObDbKcRCkVYew{R z2phGQ?3f?8rxx63x0AsS;)faQPlVf6W4k_mQC4_|wUgw0T!|}{vy6uTF|!0n08LBE z3xWYJkpIR?9ez1Ej~%Yj+^FxlzoT($hxt94^&g^?p@!StzC473LeI3$x@q~2oV!X% z(;GW0$62xUcbU%#0-|?Tg86d2+4)H+-tb~3{nP8em_K$G^XEBr-OokEejNRx)IS`e0{^f!`=Z7Ax1Zat!}rT;@>iv(6m6m> zjedna9j)1~N~yEt`sPY&3-8xv!($!y*?By5TkV%GiYG3gU1~PlXBwyAzI6*7Zo6z* zJV@i!E3C&o&gbmcufMa`d~d(Wo%L^Y)~}VKcr-0AoE}y$J}wa# zW}GY701jsr7dz)Ug`{2G-n~YyE8_vqX6yphO4>WuNH7Gqv79|tnG*N>zVnBNNAJ~h zV|3JAk_SdJ@-;fj29!yh5JeC0=McXi)T7cvqvO#-_dG-&J?_KVku(T6UBmHw&)I?J z@YqJu*=p==DpaRjbTqEQ5W*JK<$@gag>v1b@U`U&Nuoza<8NkN==$w;^1i^_7T-nc z$_W@#7#qEfN{E%>DmqdG=1g^smR^O!^D~jn^w7-Gl6C~cj&l60+~BntL#|g zi)a(qDBnD$UOGod{cXA$`~cr=$wQa>-I1Ss?jN4y;VPFZmkC0DGcp_FIHKJ@a2d=li|e=|HrK_qv9 zYuVdH6d{yCCTRMcFWrH!z+az-!^r8ce5a-y=~!dbcCOIJw5P47Wp5Zxf_N{_>YG#N zTVY__05C=Lb{R|&FEn>rOtqAJ#<|B(K_oaz-QpG62k7I$~1_{Swsgo>$osb<{=!ZTVrHC!bd;5R|QoB|BF8 z$`bmccFP8k?p>Z>f(9g)vU4S?ugTaTT_T>`atCv-rMv?nG)Px%XHPResx5jz33rL9 zK9GD&D#K=@_ms9v^5^3^gbZIyDs# z>(~`s^9L%FE$Wpa|*iYLo z9QAitpm&l*>HR;oI)YjCB6qAI{ELmxt#uuC1ss5m8kjM^@usxeVY{Tv#&Lg(32s~m zoL|NXh4Ytxd9ybEVw;*bmq?z5L5Q=8em@EBo@C48sWWKR<^vVO?M=Ibdiqr!nI$T- zaJU_0acW|MvwU!(hx)Z83=dOBXgmLc(P&_nav;KRe~>J@N50}kz;t+*yOL@ogyuO3|?Qpmp%yLj{MDloB}yF{6M}2J>!X4kafbnU;T& zyKI{`n~tLWhHPaT4~K2>1D2}uw8xKW&H!%3VIbY+@AbA`l?3bW(h4*ik5<8ir|RvE zJ;+oX>z=!^9u~|elqdpf(2kI|K?S^PO)wx&Xo;908?*krW%s3ag5Gq;!g0&dO<_lT z00QOKgWF_$wqbE`FO)qYN!oAf4b_{GCEZOkr zjtI(G7}=>dao#>fCy{*0?8^3~M2pnAEW<_GMe4h(0XqnIAIXnsPB*aIN;x0KtSxzF z&b~Nh{?OdoL&<0Qe;KGrU_7T_*@DwvlKg%CBeSd6q2?T!HoX(mH5cn#!!y@y(NcX+ zj!EDPQ^P3pgYy}}iO9zPSkpbN%L;K87pk=KuzaB;#{3_Tv$1gbR{0a zSeMib>c#aPgociyMv(k0`7SixiEHMVFJ2^L{&QP{e6k)Kf#eEjlCh4;@tnVtd{2DO zex2PCw+`t%(^Gn-!BcIzaUJ!z>!hNcJXiv9Pl9Wg)gt;dBH#h^{R8j&(W)R`dSvUQfylhHp?}Q_U`#C`}pPm z>1bDg#}uOciu1mjK*-)i{l>AOsdU*TK0KOtRL9;?k%kJhg--x6?i|%eOT`>-)g`0; z&IgAWI_HElhZD}nN7FF8u%CTFX>2=>%iNCRrWR;Plz2&{*~VkVQw!a*AYTMUpBHnJ zPomv(hr)e?KwguOiyNFYTl|j+c&X4tUO4bseM2DlY6^nRI>S?1o2cbd^x@i=Azj-- zr&~KzIu#3>k!nfOnI)*v3=QW|j>GHJEO<={C0==|$s+t$Jd*+^t0HpNSJa~g(wn;8 zsimSU$lA>u3Y{dcxJ_fZPO;}RNCX>GExA+lIQsL^@@lGd2o?cp zsX%^tL&{jj!eyLWw=QCG32$&am7-B);v|j{beKe+9*w`_f6V*y#$qOCN#{|EAuV)~ zH=;y&n@19TX*B+upy}GWk#*$t3W{~e^@$CJ{B?I*XP9HoVw6|t$CdtzBh$A!Ip#0=$a3#E7QYgYXRbQm9*sW{XBOIv z&R53|PYk3?cbiQ&I4p(@JzdqvFbz&KL0~FB_ok2J_=&DDr_H@5aAak8YQKso`u=GA zXWj*vpkRgLXOW5N5F`&ga6|m#r3lJLx z@w1-GUpd*_f>7xWePsy$B46`Q8$9pe8xDBVX`z6jY`aO0nd-n+2<;NAes?quStR;_ zZ4{p%`RckH48j)&h4&Z(J;_(0UOyO(@1!@xJ@VJoPnY>Rx3Zs-J>Tvk>t5elF`+EP ze#c|n*7oL)M&pn8&Zfd`?z*f;xoqDZc;FNMmJX8mOMMj9y=h{&&3S2>ZR{4OzYFt( zAo7DkyC3$p`=M+1!+{f?TlD+rHZ3WNDGCrbLeu4tWd2{ob3$lt5T$U|?^!`kihfj> z+)sKZ_Y*fc{X-b>E74EynZx`i&td*N$6@}H>ux;yIe!fC>lga>SECXCG0v0mYopO? z1NURnA$R;bOBu7C5*3OuVAQr$>ofoLk3>~*xg`$^nFdg31H=vhL$=Hw@Xj;zbEp_m zBZgG5xtlbf-U@Uscr)Z)&EaOFefRlgb8nV7il>|BJO89Yao~;I zgD6_OxYJbiy{xNBJa&x`r>$Hwb3M)fuHY25oqsUywk!WAnj+GD9VHFMai(|Oc<|qh z#yHcGqU4OSl~?bq5OYSDO4sAPeve7H^qX$YSU&Yh)-SrT_()t{X9)fv&0sk?d?fYq zPC1;u63%Q4Q zx3IG^Jy{Hz4OyFdUez=#=pKdCtD1|U=isa0Cx$u8qV8v5WV5AW>iJ*#B8)_6yJ_h% z^FYScY7#as_h<*-z?u@KDWr6{wb;T6Bw3MFX~i(rdLbQKCV15wx5U(FaWbm8-9wH* zY3Sx?_O`IToCBmI!L_MNTwmwLja4X)7l;`S$K#DWmXTE^mf#xZO$9qFF+EaNqyXA3 zd37}TYi&g6kPT5cY3^CqgTX?pT|>VfAm@lPr-bkNOvFhWTQU-AZ{%TO@yw2DAWvAP zxZDW{HxgZ(+xhg!)5z*tuPavhe=k?8(d@=jTz97_N7TZNHT&$?S&Wajh-;P5h2iJS zCbd|gHQ&);faRT6nRmM}FCFCSo7|J#4d;T%k#Drv(uT~KoN>#FoJx$~Qr}T8_Eq5n zYsMELZcDA5r;WF|ajE}VpL$mtKfM3Ub*Q6M8nT?;SlJO|v#Tws!!sSO$BSX*X3yP8 zr{gb)>NvWcVK$fbm3M2(f0sB>+m@m40?NpJ`yOQMW6y2hce(R{Bb6)YeqOFOT05b5 z3h8qWW|mqz0;@KZ_;z%tRClNw3SoK!XVdkH zrEN3`AUxU1l_H~~90|Ccl5b6xP%}XgyYDJYlR$~ zL6od-q&qOZhSNnDbqD~2g?3|C(0^9h-iT6jlCwEycEIjm5XjZNn_qw&siw$(;AZCa zrS~0n9z1fd!Aw6HO053DLr1b;riWk;hJG>>J$xihai(?YP;*JqN-xY{PAk1|+#-99 zq`66b(>`cPT!eO%j=)AA$?u|5hk~620=|dZ^1_akR_==+_9%|!F+oh<6Oboh_Xn%O zY>xPMymE!3!nCz>bC*(%p1J_*JhXfkaxJb=3XR%IqE?&DHk{uL=enXlvR;5ve7S|L zlr19dpf>4JJId{MC^;OvUl_jhHFVk1p<<91Ir4Tt^$?O6h7Cvus;!3AoBavJ!gJTn z9HY4Ue^{UjG}q~lQ9|7kP^+wjB(d;F)^BLqUq=a2%$yhcU6TKRG7CKrXXQ=O`KU-s zSTw6xv)F38i>cp%4IY@X?pXUUzO%*E9?gJd7guxAF!lmV60#Kvfs?E%xssYQg|uZl z-7%l+`|U&d*pbu@40NDx+woy|1cL=YxEnZ1|2^2GTh;FMg>tluiI7TKuIPMk=xQJ>M58ukB9nnBn8{@=bI7SSMZ#d0twJ{bd437|xl99mc)k@@ z3V}V1_!2IcAA0^Gs*RWTQV>TrT6B-9>BXtdrLW&lI)yE~<4&Ycoa~tL0_k(ao{%If z*Hh68V^q}$Lmur+gs9DWEb6l;9Z4>$nTt=%i5j(8e+>Q*-;r#j$PB9CQ33hLbm*zS zUJ6kiqMd%mCAH8L$MZNr)zM%H(F;AadbOy5G;XD91-m z9bDX~b>t8z4r(T^$$5oyZ)68yWX1eKi4XH%rJzx}oc4;BrO>O-&hcRKug*opTx42n z7!Yw}yXi`iAx>-25Y0}9B*L(kqRJZMg8>8IcfRd;LyDJ}2w4?&2cP#Z#{OLno`qr`(+ZN%AYA*YTfLrT#Wru`C zpFR|4U7%p&1Es#n_Y_4}g|}Wh64h;`O;*~x=asJem2T!%y56(CbrM8S=_Wzl-U0 za4`h&Q77>fbCYR9*O6V?St=zdrGg)!ZgyCgQs0}9RY2K0c8>mgUnE%wUSN&-2Q01;AQrk>uY4qlSWR8HZ;((^qPcs(1FfbW4ZH&LZ9r-A`IM$O4T(I&RRw zsA7{=8;X1($Kjx^`r+g$y|oTpH#=Hb*xLqF1$H{yXez8Lz>x4IT0UTu*aXkoX#0|rWQ>p->VL}R7DfR61|r$pzE z`Xn5=%NjUEG{yjk`wQ9qrXQEtZo2p={4kj_#ejvk0d{~v_3S?m7Py9s$(b!u9gkJ z1bd5l!NVYBj@mGn$KvM{vM5}bB33!>It4s9WzWm~(nmCbC4V^uCc>oB3%D!>>t-ED zZyVtlkHpgRhwEocHbu&`)mVlj+vN7I~{L8}N$#3C4AGV?}_q0>VtxmxVVU?z(?3l<+&nbI7 zvqWCX#8~75IN0%*!s5CFC?L~R%r37UaUm9nPa0!OjSJK%JFL^y1WwsKx$nsQqZtmD zerJb!JuXzavsYkrGW=b{>tyW^6~f*kH^e;l?RD?(mPqGep@m9NQ$6t>||G`?Vw!(>CKw${_eR~)jHQ_5f zSOUrX3M2e^K5@^Kt~XKGpJ#+Fg&ij$xMb)d5@!0h5x#)xOjU@u$Eu7;bl)}_wA;rhtM=t4I_WI0|!Xj75^keRro`z z1@Zp{rKf>v1$Aj?hwhZb%OU-lN+As=XM>r=PXV1yE#&)jP!WxkHWoq`$ep5fEG+Qy z|GJ!_dLdTV4XC`e>o|y=waDnVAiz z*?8Cg&))mM*?E=so$o7OStDtbj6rVXL~O5#Tt;;CGB$D|giJKj$jk)&88jnf2fK4e zGgq36=O6dZNE&K3W)~W}FPJx?0uNN zY^>akXW`cNzCs*UheY-Iy8#}&6#+ygRy9r}1 z>*oHsbJy##>^(brH(u2Bia_rKeiGK~n5`6oqVI<+bC;kmXxs|yZ0$L=Qy_Zrq-HTw z&ARfAf`1VW;j5Lc6nu!{5b8%6p?*OZCPQR@YQ$?39q^4;jKMr*=`B}EQvViYV$VI2 za&I4`U57tQmqd}MrMkgZLu1|cKCX#A_qRE{Z%5BS*k{YFrOw_nu*iwlQeP>v=IGCq<{?_Cpg~WW}VGK3-dmK`3!fu5SFFEI+Gj>G0Zc2 z|BiIQr@H7Oxp*Y+={_E_Yd9X`jnS_nUtbNE&l7b=W8>zBsVQg*(194*U&D9g^T z?a1FLP6X2)_rS|eRaP&*Qs{Drt0|gqspSVxgaR4kYQWzp>)*<9^X6^&k@(YbZ_2V? zd)5-{JHpM=Z>yDY2_L#<3}`ar3sXyI_RAFvV8v4IKYD=Fz;^zT9Rw8bQO--d^U)po zu&Q8IUyu>Yy*V4*!<6y4u4Wxr?a4kWJ21~5f7TQI#18kG{&vNv{R!*%Ew#SB?6=i1 z&!5`SdrhmqM-pOl#^ZWe&R7Ow6RD&g=_LQ?b=dUQv&fCy$b;PIIN1pV_L1xIiL+Ce zV?RgYAK;Gtiy0kuR}o{f&s^(7s@jQ#wH>0`BDaNevkIPnD>zk7kATD z4|Ck)eWaxrQCZ_o7&>*MQ~d(5fym}qaL_{P8ZDS*i!uK`s4_8fZ)@$n;mu-Qds z!aA6Z3f>+=KTdiFl15ghXWc%7a`dD|?-&XywMkT@QI+!D7&FfYAv*BLnd!^2b=t~s zV;na1cb+-^8vhhD%#`Snq`7c# z4tZ5KQ*gkCwnsb{`BMcCJ+B{pnnArdbSLfS$)5?1&7HNALgaR&C0j-VDaxV^bF+h&_29rOIbEAFogM$!z*__C>Mt zf$U2gjJ2WcSL4c&&T=jL%8q=W{<5`z*?oA3ySs>OjM}{ znV5$UBV3(ZP{kB@7M9R&Y%D(vOUn~L=P7p4oSf(C%Qa*4a>->Mmt5{~Y2sTu@buj~JGraHCwR@d>XMV4SIje^wYc{${nJqUzP$SrYS7gf|ru~mM2b&_`5u!*3 zn98KSf1;K@5VPt+UXZOt@->oEm-pgF_}-5ENO&>4#}5M@vowiGx%vGa`4i!Vax{-} zI?KJ0z)l-purztyUum*aJz1H(v7j}*};VW?Dr#fCWG;G9oK01YvqO@-OYCNHN3e= zpV{`!@lfaN783kAVlPP`BGGUaBGRPv$hx}VUVWjcs8_yF&`&5Atj;Bp zq9YwKR4SauoX?2Zx>+(2JHW7sFL~z%Mhpo*Pjm^ap^#pbieOwS_QD zySi((j%QNS#PEr&S5xLYGw&9|t`efg&CZ~{4^hN?TkRC_17y$z(O$`UcK@b?dIfOl z#RUr`h;E`dNA*1;FB%r6kle$KKe(qbBo2pQnPZSHM1TU8_3U<=UI<=I)HUDaGB))& zAFF5bjV2H(&A*P?If|)Ci3qmF*{3J?Bn1+g8nVzN`!KALIw#$jTIiXKh89Z4D=Kcc@4lW+qlfiYhGziV`GC4_(Ch^QeRV@ zr*prNmau79^7{qIM_5#RYqq23zI@2HU@YANZeQCN1ALRE4j&#S(Z=6y+^3CY(Ke~m zgf*czP#;T!`u(KuKc`P=kfNUwRa%0|{!thoR|9~0x#Y>z{G)3?eWklKn4h4xR}mTB zY@Z?XJ5GRDkUR1dkTAkjlP)(yd@Q^g2w&_^m9XF!X0%yL?8Utx zqf`jaiijw_icj>$;4{$@5fBSOu)(96QdunBQn@x0Hd*>S`T(5956cx$jsQ1JSfXtz zqEs0n`us#s8a&RRe5IHv`*qqP(9txO87>Fj&WVwHk>?e}6UqitU)1?ORz9SABUnk= z)#-WoOi{s1sVbG|=jvd;MF5!r$E3KOldiFr6420EmmX%p0Sh{deMO3sDtcxjcsZNw zCJXKI_d$<15tHHBlDT1091_@o=^^%p2EUv{# z9UmvI;9{!~*9&T-joGBxdHf{d1%q6mJ@F?kJHiJNN1S{RQ~YFp&J9KTpHVn+&^Qfjs&+}VAd`I7>QK)LCs#F6m^SLAhW-I;%(R2Gi(S4|t;Mj=XP z%4i@L$9U@vO%&?Aq&e!k_1kxPI2|y`PgUBK#B1~lT*EcRnwjE|s7Z=}Qw=Wjk4-S% zMqhi#)5?OlrA`i))yj*nN=xz5e1tAC*Xvj5L=b_jd&Z%c~Q6TGiIaqMF2PJmQndW4N9T_c|BWjf|U{da-uAlDK zPb*8ZRe4n}w}QqmC)WL3?f2fwuXx5flgk;Qtr8ztXf*U)HU510WTN~n{gIZggu((m=<{w5!>uElad@3nsc3qkhgce zj4f6Rxar#`?QIpb0J%W{s`#?=yX|+*<GGngc&v4_UKZi?Ob2vgkbWqyW0s^D#e;v=qi68`Ng_{Ca&=!B`F1XYLC zo3I^%FAzkax2A$$UBS%xQFRbtl5;#Q%t+-2g$@zD77^6Ah-Y_c5+T&7^Fmu^?85Zg z9K(FZcKBo{ePe|MHUVQcfN%}3j)lSpqF*Y9-9M#0A3?Lt8aBfspD6RRX8L~a}qIe0RbcZF#Cokh@S2Kb@Fm+W_dPF`luI9NyXdJw~e-S zd8vJ2a(;1UWsZT(&XrymTe@@sVslwV#o-WTXJRZ|en`I(j3Z3rA?eH4;NZbvC5m_y zl|@dq5%Nr1i>)!m$`G=a4`i10|m8@Uc@u#tmDuSL?r@%d>M=KPLBC5gd`&?2wm|vi)?d zwQOnXXU#)etDPo=miwR2hvuzY^RbOyhq)(h&Qcs|r?c#yYlUD5ONXCpL8q$@LHd3^ zXmHf?KCzUcZTY_A{5R~JK1DD#x8k6Tos7^x0yCza>2_-gBh)QhbLvEeAuu9^<|89) zT&yHkNXxm2l}Fx=EfG9OPS(}${CP&nZ6`bD2PLlSu*1A?^|wy?R)I2fZg41bLttMH zR`R3v{mdk$$!hb#c!nA?Jh3hBf2FvhPcpmj>U3Q$=6af5egw_MY$O=aRw$n|jXn)= zw-9RTnZf5(;&ZrdG#nHOWNTkEyjRS71vmCcrc;nkz}_*b&rhCU42liwg(r2#YCaszWqv zF;H>ejU#~~@jqVO0crP{5u(g@!4mU^W^purigoK};O#14^>PB#JoGKF1xA(ioH^eJZ!iNPHM+aI9|0UZc7X#BTVFAtECo5dP>i#TZ_s$PLWA zY*;R45`{r^%`0arRgSiCc~<<~-;RBl4AeM$Hd9Oq_;_#jZhk1jbmXYUrx=C z0^(Rit1V4&R4U^z>J298lT&Sq2=1yqrZx`)tQr&Ji3c$w>c|XPj3xWYag?WXu2WzX z$G}KJeK@%lWEqVt#SzX`{g{UP;aUT55sZM2Z#X`em9;5Q<`Qbr#77svI@{~GSJ9-N zNVz<=Zm7T7X>364V-?zrR8e80H`Lx8NyWHqpftWUUf|hRVphe;t|SguW3YTbT5YcP zQ=albyv}<+1*=R6Dh`D)#DfrZxS#l|an%0vpjJ_mM!Ex7n=R{U#Np3GZ3I2tcS8xAVkDOXuX*hq7l-CyvVpQ8qcPs3E&P);>i3SfwGp~}+hW=>d8 zOu0K}dUWWvg9-Wt`Oq?cJ=vD!ymUP~^^3BG*Cx8JWsP3LLHBtL zryc3R?fbz4x}pQUr*=awT$DQ#Oe#P80^13@zqVu>=3#7e;KA z2@M;c(tuc@Kd-*+vw#hFr@*!<0M$_gdaMs64%r`fIU{6&v{g))`B9fb?PvGN+IF#} z3(nngDqWo(6}QrkPGs<7J@2x)H`p&zX5eV(TpgYlbVxsU0k_-0szL&hoAY+1ky!WBBE3YALqY*mo zGzXpxu4BbQnj(rvfG_}ra$;)n_sH38^0}9IJlYC@xOE+`WBs9yqwne^AZLZc`Si^UMm80?Z#@AtoA{|pfeum8%P}heSUe6e%=N98(T96mLxp|3BXWrU7^I+&9x;qZ+mLYjt*@TEYo?9-%eAd z@KW>vNNr`2Io*g6Xo+;mDmtk|X@ggN1 z-?izegF1W8P&^LfF7Bb8{t`X4Y$J4K**?8uDxA80k3e~t`{nfC_wUT!f33@ONFxtf zvcJSl#jtN=+St3qXvDRHiai=wf$e?BlrtY7lA`?lRkURJJ`-tq`^sA5!3VAxthIgi zROU+ve~F)-b;}ZshvWiYeYoA4ROjBYOBasIP&i~xBprTcDp>2C*_{uXO=i*sysH~s z!mDk&Z|Lf;_TqL~cewU@9NNtKA|3f2bAoj~v@?G|n>a#$T$OUW%3|SI{gBAvBRjK? zTni!&c6GI8`q1PVya0ZiFEm-wL6+?e3RjPkYAV0v8=IcGjmBB_Q2}}D*6icg1|(~C zvUQ<3y*f>GxO{H~EPV16!eCoeXl6@x(xK#3D2XS#E*q0NAscgfLY!~q zgRR-vnjidw>$B_=%%j%x@D?&DuVp4C5975$lbmTPQYo4^4+ed8Ql*eOpW2x>w9aSC z3zSvZsB`2rQPTNE9PT0jF8}PYJD`*_nOjnt)l`eFSD8Dqzu;nh%<@ z6(z)pQ|8srX(*=u^rj5%P#}?4E)GdvfyM0}I*%!kCEJ_Yvh0hSb}$k;I2(dY5DYQm z?M3gGK0`Ozm#$@=c5bMMJEo|i_C-rh9=zz!rh&YAYi{0a>8x3P#Kao+1xe32wKYFv zBC0iM;ox@SB9r2UPvmt`iZQ|LD_0jWo%gJ_kq#<2!RxV_0W7P%U463U2 z5DDMCw%_m*pQ0>T#I^{x2oQyJLkwK|VIXspQz^X2ENv?lM|{Y*FU<(KW=!e$<~Oc< z?0&Z5?#RVTdoLLVs;u*bbYUqKRQ#ut=H+R~_lUO7@ z;_Vsxarca0SBcVXN>uUY2wk9}p!jqfARjZy1AGSRL#2eesJaexi*C=1w#e9BkY1~{ z$WPjIqlL$&E2)2@DMwj&Bz8BvxPre-Mz!H-aGQ)shx2FZ@yn1JT zROdoTNHd%VdrZKe+4#qUfeKMcs?F^~ z7uDrp6(4Wkcw?-Y9fM}tun#2bGsBcInh?)=oa8O`xbL%+MAfptY99+!!iAkxOBp6JmxK@M4`Fxx5A3mQ~;7|?Rbdn;XI}~ta@PM+f6l*e$HfisZp)lY}Bb*L*U>Mqe5p#)$ z6mLe@qPVayqMdo%XV`_6AFkb(`&%-z(o6bU3dAP!PjeS>3OBZqBVeJ2Vs;HTsG_CM z*zNB%a+0}$Zgb> za_-**OXezn&SlUWbv8boXE*h3<^dWAqNc8t$+Cla!y~Fo-;QKPh3A~wnR8WHRqT{3 zDN6*=eKU*mlO6nHwY>h?l|wJDzx1~I5GaB%eY1GOicI^0-W<0${dwL&DcY(nIEO4$ zNTRO#otB?qb@Kk^YUk$O+>#ZBeCIB&V%PVdNA>m*+_UIHvT@q$H}-lBuF}qEuN_SS z_M{mxJGb=aAFO~>y71kB)eWL7GJ6-ye4YXkuOZ5@@l3&tn}$$s7IDcM$UGCPx<@1a z3pQPU>dQv7_fX#BhON~1Aabup44_>cL}Yz zH9N3rM}w@Mf>cfWc3V_mekd&tl?@l$m{lLZmFp7VfSk4_5t{Gk@Zk_6H&Xd#>Y~EM zmapkMl>lj@y(mr&?{RQ+q0p?cvfbJna{Y-aBNGSAFdkOv73rv!@}4i2P*CzT9{VE_}ZS3Js$}_ZO}*h{3?-BTh;{XVW1$A z1H1(T3+%4TT45%LXb3sF&SG(0?Sar%#-((1Sd64uC!-7wzfY$KS zuZ`6B?y?iTPrv}e(-h$f;YAD1;nIeagh8l!ScuJ$t)+w5_+@hbf@3|5SG}}AhqdYp zgn5+6?i3^Eh>r;(R-95#?TJe3`mdBhXxD{Usru*qSbEtt?vT1wpaxfm#yrt-9IH2h z}ZOu$p>xq61ntlGS{G)CQ<3yfmo1aq`& zuIv{H7l=>nu2%56$Jl{%hQrF)-ll$q{Z<+f71c(njp9_|_hVt-Ar*Oys!RcBmRC#y zjg28RryMqhO?4xjTUITn)^(ps?yDgnnIYHO6I(ieki^j9Fdpw#20_v2?s>F~9IE;K z3zrlvVnLt&xgPWz5Ex zwDI8!{u=r2&vjtHsa}e{#E2ezKtdhThwkq^BGW;Ks$${hHuFsQg@LG6Wb-Un>l!Q0 zhdKZl%m_N!8(!eA4YG{(D2}8wvt_UD-SiIOwJ@wF{X^@#9W$aizbvlX-%$()y{6(E z$!p8y>v3U97fI!ElyJ*?C^^7_s&m-8Z!1?vXdRs?aK%@mLa(dc8xJKRl#mxp$sX*i z7#(?uQUqzOMvS}@ioGjGmka*(fr?R#MSC?A*U*D#OQ1~I`k)E577F1+zqvz$BgH~A zy59`Wj-#%~40B9romstYHRTtmOSHexXlA4%;nnCl!J6>d@MbcVC%1|j;3KS3b~Pa% zbB$YPd+n2JdkKD>*oS`>JFzL6m-eL55!Qg!JYvF0%a2URv9+{9L@}Pe7_Jydw5Xq2 z!Q+6x+u*V;#m_wY-5)PXGvKzZ>89OtkK3@>CJZWG*A9jGUYD1~@x%l*l~w4qLbqTuLw{PNUNwu_sn1KJ1y z0|to*!m$G{?pJ>acDCT=u6Ou|Yl7vaf@*`W#3U_Y`8-)v_BG-Gfi9TrQM467>J|rm zEc9PqY~TN!v#4`AGN0a--LpBHFlN7j7~C@~x?nSufd}zGEKyamis0X5O^W`L#OyY` zu7{ggIgJ$bg{JT2J#4MC{}tW)+$Rp-X95IK6xkGiUAGU}qS?#8)i|P7@47gm7B3U* zqyJD0`r$2mviZ%?TAy06vOXJNcJJ_z|3)x-dy#9zI#MbgwXF8=m8dszR6Nbd9QIl< zY^WV0s(FzpVTCUsX*?({Y?xF;BfseD5X4JdG!gJ&CF90nBW|hPt;V=ZBCkRoXT?Jq zi~uFRV~S*mNe1^`oSN=(U5+nt)2qEi{Gd;+7z{t1K(?5H+v9O^vd+yEN5kP_ zvzx&k3)}sIW+h6i;=*R>g>|&Q_}Suo&Fzf^Uc5Xrw+Pwmh9VvR zeb;ia!9Zn^$-3*$H>=Lb_2KOnS$ge{B2foFlEvm)hCo~9kc~u$_7ruhXR7JVy)45z zS0S#9>N~?0>w=Pl3HH2IoL}k9mrq&*P1)8J0)_65(U~+>Crd`C%q&IE7|E{vtzR|D zqNjA9qfc^mwsI}_KDrjHH6GHuclT-45o6=)-T){RzEx9Mbdq@4<9o`Mu5hU>S+=_Q zmM_EcoYD~4wabf{N|%U1cTSPS7s4d+kk_#O zD~!Xs3WNiRb4){8bV{n8R)1-|5i*!pnvG&kh;*Pm=czIzJml;8xeF-2zzAb`xE)dF z<-$h5H_D#Zztir!1yyfk18et7{2%%n=6wG&;8XJJJH!>olnlcq^o zo>IOH#Lq4BmeOUPM>gj%+wRX%y(uc{pdeL>s@b|&TuL!a|7+&4)t!3!1}(`GhK*5` zY$3=fICeU^Otq*ha9d^G;D2{BV0mszp3)D+*zw8^WW;ey8*|8=Ul)AU-DxMTSE3V~ z^Imvwz{=89`)HK4iD0%wmiCkvTxk=!?ph4sxJ<6F?X^d%U3Bn;=!O~0EY-WKi@U2Y zITdMw2%V3wgVtATgR|jakm}F0TNhgkNRXzJ2X~M;GQeW2UeXFWdAGFRTl=IPt|j7= zs%p|&ir245fraxbk4hyQ?nY>mfpj3bl<3=)CcjL}E%v5DBLs5ynCyjeaV&6jazP0M z2KY+SoH^4rHW<48A-k=l+BN0E&f|UNeA|2sNl>cVxPF8|F-wkO2$Ey>hg~`-XC4J? zfdpxC_;PMn*Qpck=!W)Wdc%Y;U7~?S zF-XxQ4!xa+tK;(FGC}&+5D+-Ol``z9qV(vqpTUF>+V? z!mtvAE0W!fwGUe%vGR=6$6ij3%9>JQv_J1UOHh_RMgKJN@clws-GO|lo5jW@G#fcf z!BP&yI*~A2&m4#XpuMC)JkjO3wvoKCx3@o((z-G|AI`-Ak`vmivLdf^)}73IgO!n@ z)JVq4q-nOlNZ$TkSmw|Wn=>ZipuU>InB^y_{(4@O(n)Pp5gtNA+HdO3iI0#%d1T|y z5RC{c(syjn)`iu#^yWvy2mMO*Upb`8;Cp4!!HB*_G|IBrD->_?7bTFLAzcm7eXS0` z>q`1cg)p++wqdBN;8X21-)fGrFw?W)js@a%*M)K+ioB^yVPWW=K2>=|sOeKF#ai~o zt){TNrR%+i*DE#;yJDmN)Ovb)vbXm3^s-vR33nAhdhWWdmfd_k(fGHiK)x1;&9Nox zx$C91Y+mgzt+Zc9nuhh-2Q2R}#c5z)U-m9MPZkn^n@owz=*z5C=PD(a-_u(g2fFNi zy=C39_gK$g+}cMgYA%oO--y~swlRF3Y7w)laUeY6`SLz)5K&7rT!kdBr@aUQ<4>U_ zt~0fZvN3yD4LZ__ff$Yb!(OVIUD4sLf@igVbyRrmoKiv;eW0F+Q>pPG---@|K%!1meKB zDDmU0mHOxz;WW@)E$z`6jxeL|{2^Tm9^27YxnRKy3GT`JR&KrR5Z6Uv*}D2hb<^cl z_p;&$ZRpNNd-Km8Q`IB)MU(im7A7_+15-t>3K?$Fk3MVK`gowNPgH2@<3?K#?a4kN z(&Fj2pLMsN3f+FD((R|L+dXWC&!}G>Key5H_)V?mjT{>|w?OSGWDZscm&<*2o|2J^ zh=E{9)S2q*Le(bkt(5N$)D>9Yw&OI0oO94{q;t}##sMGT*SJupx`-+o_j)n_jXa}ZJ_Y%My+LXZQZxzU_a8NtQ=@6kLcDG*#kRq1i0T)8UIOm&f zYPfbDpCY|q<#;dDx#(%y<>T`fdb{qEJ6m(e_GY%QxSSYf=GCe+d0lkmaab4ZT{+|| z15#)U0c{vEJ}kL2e2thDZjSD%ygWl;D{AF(&=if~620tt1W|4R(oVte`EB)7MZago z#&fAr2BDN%3(_ea(D81wXJQjE(+#l^as+~ZG#gNcsRfLiDO2V8BtddaP`rsM%GcL! z&yS}<(ZtSsyNM8GKQm2|@#ur~=KA+$SxLDHu!*thMpok(a)CaDn1motRpQW}6~{Jv zY`FIix-;V@2A2+j(n)^^5_(VVivJ}-3j%p?J{vU@{l}&ftKA+7VS^Z*?xF?(P0meV za1A+spf$|RX4ew6X-xyV>?RzXLBi?){YLy#275@P8|=(;L0mwVtrXd|KKq-+#RANG zaYF*g%Jm}ohI82lwv_k==(BBCf%fj>r}nEx

    YFDJw-P*N=BE2XYe>!I>GD7=*%3 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

    )t=1 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 aG5_ifn+Z#K?4s6bz1HeS&cFJo`TsAtU;L~9 literal 0 HcmV?d00001 diff --git a/chains/polkadot/config/src/lib.rs b/chains/polkadot/config/src/lib.rs index c2b15fcf..9c6ef800 100644 --- a/chains/polkadot/config/src/lib.rs +++ b/chains/polkadot/config/src/lib.rs @@ -5,6 +5,12 @@ use rosetta_core::{BlockchainConfig, NodeUri}; use serde::{Deserialize, Serialize}; use std::sync::Arc; +// Generate an interface that we can use from the node's metadata. +pub mod metadata { + #[subxt::subxt(runtime_metadata_path = "res/polkadot-v9430.scale")] + pub mod dev {} +} + pub fn config(network: &str) -> Result { let (network, kusama) = match network { "dev" => ("dev", false), @@ -31,15 +37,18 @@ pub fn config(network: &str) -> Result { currency_symbol: if kusama { "KSM" } else { "DOT" }, currency_decimals: if kusama { 12 } else { 10 }, node_uri: NodeUri::parse("ws://127.0.0.1:9944")?, - node_image: "parity/polkadot:v0.9.37", + node_image: "parity/polkadot:v1.0.0", node_command: Arc::new(|network, port| { + let chain = if network == "dev" { + "--dev".to_string() + } else { + format!("--chain={network}") + }; vec![ - format!("--chain={network}"), - "--rpc-cors=all".into(), - "--ws-external".into(), - format!("--ws-port={port}"), + chain, + "--rpc-external".into(), + format!("--rpc-port={port}"), "--alice".into(), - "--tmp".into(), ] }), node_additional_ports: &[], diff --git a/chains/polkadot/server/Cargo.toml b/chains/polkadot/server/Cargo.toml index fc359134..991dd410 100644 --- a/chains/polkadot/server/Cargo.toml +++ b/chains/polkadot/server/Cargo.toml @@ -17,8 +17,8 @@ rosetta-server = { version = "0.4.0", path = "../../../rosetta-server" } scale-info = "2.3.1" serde = { version = "1.0.153", features = ["derive"] } serde_json = "1.0.94" -sp-keyring = "18.0.0" -subxt = "0.27.1" +sp-keyring = "24.0" +subxt = { version = "0.30", features = ["substrate-compat"] } tokio = { version = "1.26.0", features = ["rt-multi-thread", "macros"] } [dev-dependencies] diff --git a/chains/polkadot/server/src/block.rs b/chains/polkadot/server/src/block.rs index a38299c9..bd77dfaf 100644 --- a/chains/polkadot/server/src/block.rs +++ b/chains/polkadot/server/src/block.rs @@ -5,17 +5,18 @@ use rosetta_server::types::{ }; use rosetta_server::BlockchainConfig; use serde_json::{json, Value}; -use subxt::blocks::Extrinsic; -use subxt::config::Hasher; -use subxt::events::EventDetails; -use subxt::ext::scale_value::scale::TypeId; -use subxt::ext::scale_value::{Composite, Primitive, ValueDef}; -use subxt::utils::H256; -use subxt::{Config, OnlineClient}; +use subxt::{ + blocks::ExtrinsicDetails, + config::Hasher, + events::EventDetails, + ext::scale_value::{scale::TypeId, Composite, Primitive, ValueDef}, + utils::H256, + Config, OnlineClient, +}; pub async fn get_transaction>( config: &BlockchainConfig, - extrinsic: &Extrinsic<'_, T, OnlineClient>, + extrinsic: &ExtrinsicDetails>, ) -> Result { let events = extrinsic.events().await?; let mut operations = vec![]; @@ -24,8 +25,8 @@ pub async fn get_transaction>( let event_parsed_data = get_operation_data(config, &event)?; let mut fields = vec![]; - for field in event.event_metadata().fields().iter() { - fields.push(json!({"name": field.name(), "type": field.type_name()})); + for field in event.event_metadata().variant.fields.iter() { + fields.push(json!({"name": field.name, "type": field.type_name})); } let op_metadata = Value::Array(fields); @@ -92,9 +93,9 @@ pub async fn get_transaction>( }) } -fn get_operation_data( +fn get_operation_data>( config: &BlockchainConfig, - event: &EventDetails, + event: &EventDetails, ) -> Result { let pallet_name = event.pallet_name(); let event_name = event.variant_name(); diff --git a/chains/polkadot/server/src/call.rs b/chains/polkadot/server/src/call.rs index ed92aa5f..249fb9b3 100644 --- a/chains/polkadot/server/src/call.rs +++ b/chains/polkadot/server/src/call.rs @@ -6,11 +6,12 @@ use scale_info::{ }; use serde_json::Value; use serde_json::{Map, Value as SerdeValue}; -use subxt::dynamic::Value as SubxtValue; -use subxt::ext::frame_metadata::StorageEntryType; -use subxt::ext::scale_value::scale::TypeId; -use subxt::ext::scale_value::{self, BitSequence, ValueDef}; -use subxt::{OnlineClient, PolkadotConfig as GenericConfig}; +use subxt::{ + dynamic::Value as SubxtValue, + ext::scale_value::{self, scale::TypeId, BitSequence, ValueDef}, + metadata::types::StorageEntryType, + OnlineClient, PolkadotConfig as GenericConfig, +}; pub fn dynamic_constant_req( subxt: &OnlineClient, @@ -32,13 +33,17 @@ pub async fn dynamic_storage_req( ) -> Result { let metadata = subxt.metadata(); let types = metadata.types(); - let pallet = metadata.pallet(pallet_name)?; - - let storage_metadata = pallet.storage(storage_name)?; + let pallet = metadata + .pallet_by_name(pallet_name) + .ok_or_else(|| anyhow::anyhow!("pallet not found"))?; + let storage_metadata = pallet + .storage() + .and_then(|s| s.entry_by_name(storage_name)) + .ok_or_else(|| anyhow::anyhow!("storage not found"))?; - let storage_type = storage_metadata.ty.clone(); + let storage_type = storage_metadata.entry_type().clone(); let type_id = match storage_type { - StorageEntryType::Map { key, .. } => Some(key.id), + StorageEntryType::Map { key_ty, .. } => Some(key_ty), _ => None, }; let params = if let Some(id) = type_id { @@ -61,7 +66,7 @@ pub async fn dynamic_storage_req( let data = subxt .storage() - .at(None) + .at_latest() .await? .fetch_or_default(&storage_address) .await?; diff --git a/chains/polkadot/server/src/lib.rs b/chains/polkadot/server/src/lib.rs index 174c4dac..38914ad2 100644 --- a/chains/polkadot/server/src/lib.rs +++ b/chains/polkadot/server/src/lib.rs @@ -1,6 +1,8 @@ use anyhow::{Context, Result}; use parity_scale_codec::{Decode, Encode}; -use rosetta_config_polkadot::{PolkadotMetadata, PolkadotMetadataParams}; +use rosetta_config_polkadot::{ + metadata::dev as polkadot_metadata, PolkadotMetadata, PolkadotMetadataParams, +}; use rosetta_server::crypto::address::Address; use rosetta_server::crypto::PublicKey; use rosetta_server::types::{ @@ -12,13 +14,13 @@ use serde_json::Value; use sp_keyring::AccountKeyring; use std::time::Duration; use subxt::config::{Hasher, Header}; -use subxt::metadata::DecodeStaticType; -use subxt::rpc::types::BlockNumber; -use subxt::storage::address::{StorageHasher, StorageMapKey, Yes}; -use subxt::storage::StaticStorageAddress; -use subxt::tx::{PairSigner, StaticTxPayload, SubmittableExtrinsic}; -use subxt::utils::{AccountId32, MultiAddress, H256}; -use subxt::{Config, OnlineClient, PolkadotConfig}; +use subxt::{ + dynamic::Value as SubtxValue, + rpc::types::BlockNumber, + tx::{PairSigner, SubmittableExtrinsic}, + utils::{AccountId32, MultiAddress}, + Config, OnlineClient, PolkadotConfig, +}; mod block; mod call; @@ -33,45 +35,37 @@ impl PolkadotClient { async fn account_info( &self, address: &Address, - block: Option<&BlockIdentifier>, + maybe_block: Option<&BlockIdentifier>, ) -> Result> { - let address: AccountId32 = address + let account: AccountId32 = address .address() .parse() .map_err(|err| anyhow::anyhow!("{}", err)) .context("invalid address")?; - let hash = self.client.metadata().storage_hash("System", "Account")?; - let key = StaticStorageAddress::< - DecodeStaticType>, - Yes, - Yes, - Yes, - >::new( - "System", - "Account", - vec![StorageMapKey::new( - &address, - StorageHasher::Blake2_128Concat, - )], - hash, - ); - - let block = if let Some(block) = block { - let block = hex::decode(&block.hash)? - .try_into() - .map_err(|_| anyhow::anyhow!("invalid block"))?; - Some(H256(block)) - } else { - None + + // Build a dynamic storage query to iterate account information. + let storage_query = + subxt::dynamic::storage("System", "Account", vec![SubtxValue::from_bytes(account)]); + + let block_hash = { + let block_number = maybe_block.map(|block| BlockNumber::from(block.index)); + self.client + .rpc() + .block_hash(block_number) + .await? + .ok_or_else(|| anyhow::anyhow!("no block hash found"))? }; + let account_info = self .client .storage() - .at(block) + .at(block_hash) + .fetch(&storage_query) .await? - .fetch_or_default(&key) - .await?; - Ok(account_info) + .ok_or_else(|| anyhow::anyhow!("account not found"))?; + + AccountInfo::decode(&mut account_info.encoded()) + .map_err(|_| anyhow::anyhow!("invalid format")) } } @@ -141,9 +135,11 @@ impl BlockchainClient for PolkadotClient { .map_err(|err| anyhow::anyhow!("{}", err)) .context("invalid address")?; let signer = PairSigner::::new(AccountKeyring::Alice.pair()); - let dest: MultiAddress = MultiAddress::Id(address); - let tx = StaticTxPayload::new("Balances", "transfer", Transfer { dest, value }, [0; 32]) - .unvalidated(); + + let tx = polkadot_metadata::tx() + .balances() + .transfer(address.into(), value); + let hash = self .client .tx() @@ -164,10 +160,17 @@ impl BlockchainClient for PolkadotClient { let account_info = self.account_info(&address, None).await?; let runtime = self.client.runtime_version(); let metadata = self.client.metadata(); - let pallet = metadata.pallet(¶ms.pallet_name)?; + let pallet = metadata + .pallet_by_name(¶ms.pallet_name) + .ok_or_else(|| anyhow::anyhow!("pallet not found"))?; let pallet_index = pallet.index(); - let call_index = pallet.call_index(¶ms.call_name)?; - let call_hash = metadata.call_hash(¶ms.pallet_name, ¶ms.call_name)?; + let call_variant = pallet + .call_variant_by_name(¶ms.call_name) + .ok_or_else(|| anyhow::anyhow!("call name not found"))?; + let call_index = call_variant.index; + let call_hash = pallet + .call_hash(¶ms.call_name) + .ok_or_else(|| anyhow::anyhow!("call hash not found"))?; let genesis_hash = self.client.genesis_hash().0; Ok(PolkadotMetadata { nonce: account_info.nonce, @@ -200,22 +203,19 @@ impl BlockchainClient for PolkadotClient { .await? .context("block not found")? }; - let block = self.client.blocks().at(Some(block_hash)).await?; - let timestamp_now_address = - StaticStorageAddress::, Yes, Yes, ()>::new( - "Timestamp", - "Now", - vec![], - [0; 32], - ) - .unvalidated(); + + let block = self.client.blocks().at(block_hash).await?; + + // Build timestamp query + let timestamp_now_query = polkadot_metadata::storage().timestamp().now(); + let timestamp = block .storage() - .fetch_or_default(×tamp_now_address) + .fetch_or_default(×tamp_now_query) .await?; let body = block.body().await?; let mut transactions = vec![]; - for extrinsic in body.extrinsics() { + for extrinsic in body.extrinsics().iter().filter_map(Result::ok) { let transaction = crate::block::get_transaction(self.config(), &extrinsic).await?; transactions.push(transaction); } @@ -241,15 +241,11 @@ impl BlockchainClient for PolkadotClient { ) -> Result { let block_hash = block_identifier.hash.parse()?; let transaction_hash = transaction_identifier.hash.parse()?; - let body = self - .client - .blocks() - .at(Some(block_hash)) - .await? - .body() - .await?; + let body = self.client.blocks().at(block_hash).await?.body().await?; let extrinsic = body .extrinsics() + .iter() + .filter_map(Result::ok) .find(|extrinsic| { ::Hasher::hash_of(&extrinsic.bytes()) == transaction_hash }) diff --git a/docker-compose.yml b/docker-compose.yml index 42a93f7e..d59013f3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -44,8 +44,8 @@ services: - "ethereum-volume:/root" polkadot: - image: "parity/polkadot:v0.9.37" - command: "--chain dev --rpc-cors all --ws-external --alice --blocks-pruning archive --state-pruning archive --base-path /polkadot" + image: "parity/polkadot:v1.0.0" + command: "--dev --rpc-external --rpc-port=9944 --alice --blocks-pruning archive --state-pruning archive --base-path /polkadot" expose: - "9944" user: root @@ -61,7 +61,7 @@ services: - "polkadot-volume:/polkadot" astar: - image: "staketechnologies/astar-collator:latest" + image: "staketechnologies/astar-collator:v5.15.0" command: "astar-collator --chain dev --ws-port 9994 --rpc-port 9995 --rpc-cors all --ws-external --alice --blocks-pruning archive --state-pruning archive --base-path /polkadot" expose: - "9994" diff --git a/pull_nodes.sh b/pull_nodes.sh index dc7956e7..6fb681e6 100755 --- a/pull_nodes.sh +++ b/pull_nodes.sh @@ -1,4 +1,7 @@ +#!/usr/bin/env bash +set -e + docker image pull ruimarinho/bitcoin-core:23 docker image pull ethereum/client-go:v1.10.26 -docker image pull parity/polkadot:v0.9.37 -docker image pull staketechnologies/astar-collator:latest +docker image pull parity/polkadot:v1.0.0 +docker image pull staketechnologies/astar-collator:v5.15.0 diff --git a/rosetta-crypto/Cargo.toml b/rosetta-crypto/Cargo.toml index f3ddce91..9d72c29f 100644 --- a/rosetta-crypto/Cargo.toml +++ b/rosetta-crypto/Cargo.toml @@ -13,6 +13,7 @@ blake2-rfc = "0.2.18" bs58 = "0.4.0" ecdsa = { version = "0.16.0", features = ["arithmetic"] } ed25519-dalek = "1.0.1" +ethers = "2.0.7" hex = "0.4.3" hmac = "0.12.1" k256 = "0.13.0" @@ -22,8 +23,10 @@ rust-bip39 = "1.0.0" schnorrkel = "0.10.2" sha2 = "0.10.6" sha3 = "0.10.6" +sp-core = { version = "21.0.0", default-features = false, features = ["blake2", "std"] } ss58-registry = "1.39.0" substrate-bip39 = "0.4.4" +thiserror = "1.0" [dev-dependencies] bs58 = "0.4.0" diff --git a/rosetta-crypto/src/address/mod.rs b/rosetta-crypto/src/address/mod.rs index 7d88d90c..5664aa4b 100644 --- a/rosetta-crypto/src/address/mod.rs +++ b/rosetta-crypto/src/address/mod.rs @@ -1,6 +1,12 @@ //! Support for various blockchain address formats. use crate::bip32::DerivedPublicKey; +use crate::error::AddressError; use crate::PublicKey; +use ethers::types::H160; +use sp_core::{ + crypto::{AccountId32, Ss58Codec}, + hashing::blake2_256, +}; mod bech32; mod eip55; @@ -8,6 +14,8 @@ mod ss58; pub use ss58::{Ss58AddressFormat, Ss58AddressFormatRegistry}; +/// Error format + /// Address format. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AddressFormat { @@ -54,6 +62,41 @@ impl Address { Self::new(format, address) } + /// Converts an EVM address to its corresponding SS58 address. + /// reference: https://github.com/polkadot-js/common/blob/v12.3.2/packages/util-crypto/src/address/evmToAddress.ts + pub fn evm_to_ss58(&self, ss58format: Ss58AddressFormat) -> Result { + if self.format != AddressFormat::Eip55 { + return Err(AddressError::InvalidAddressFormat); + } + let address: H160 = self + .address + .parse() + .map_err(|_| AddressError::FailedToDecodeAddress)?; + let mut data = [0u8; 24]; + data[0..4].copy_from_slice(b"evm:"); + data[4..24].copy_from_slice(&address[..]); + let hash = blake2_256(&data); + Ok(Self { + format: AddressFormat::Ss58(ss58format), + address: ss58::ss58_encode(ss58format, &hash), + }) + } + + /// Converts an SS58 address to its corresponding EVM address. + /// reference: https://github.com/polkadot-js/common/blob/v12.3.2/packages/util-crypto/src/address/addressToEvm.ts#L13 + pub fn ss58_to_evm(&self) -> Result { + if !matches!(self.format, AddressFormat::Ss58(_)) { + return Err(AddressError::InvalidAddressFormat); + } + let ss58_addr = ::from_string(&self.address) + .map_err(|_| AddressError::FailedToDecodeAddress)?; + let bytes: [u8; 32] = ss58_addr.into(); + Ok(Self { + format: AddressFormat::Eip55, + address: hex::encode(&bytes[0..20]), + }) + } + /// Returns the format of the address. pub fn format(&self) -> AddressFormat { self.format diff --git a/rosetta-crypto/src/error.rs b/rosetta-crypto/src/error.rs new file mode 100644 index 00000000..db6d9a55 --- /dev/null +++ b/rosetta-crypto/src/error.rs @@ -0,0 +1,11 @@ +use thiserror::Error; + +/// Errors that can occur while converting or parsing addresses. +#[derive(Debug, Error, PartialEq)] +pub enum AddressError { + #[error("Invalid address format")] + InvalidAddressFormat, + + #[error("Failed to decode address")] + FailedToDecodeAddress, +} diff --git a/rosetta-crypto/src/lib.rs b/rosetta-crypto/src/lib.rs index 6a139ad9..1d31c513 100644 --- a/rosetta-crypto/src/lib.rs +++ b/rosetta-crypto/src/lib.rs @@ -14,6 +14,7 @@ pub mod address; pub mod bip32; pub use bip39; pub mod bip44; +mod error; /// Signing algorithm. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] diff --git a/rosetta-server/Cargo.toml b/rosetta-server/Cargo.toml index fa64c342..3ceffbc3 100644 --- a/rosetta-server/Cargo.toml +++ b/rosetta-server/Cargo.toml @@ -17,6 +17,7 @@ femme = "2.2.1" futures = { version = "0.3.26", optional = true } hex = "0.4.3" log = "0.4.17" +nanoid = "0.4.0" rosetta-core = { version = "0.4.0", path = "../rosetta-core" } rosetta-docker = { version = "0.4.0", path = "../rosetta-docker", optional = true } serde = "1.0.153" diff --git a/rosetta-server/src/lib.rs b/rosetta-server/src/lib.rs index f4e3e664..7ab2c3a2 100644 --- a/rosetta-server/src/lib.rs +++ b/rosetta-server/src/lib.rs @@ -451,10 +451,19 @@ impl Error { pub mod tests { use super::*; use futures::stream::StreamExt; + use nanoid::nanoid; use rosetta_docker::Env; + fn env_id() -> String { + nanoid!( + 10, + &['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f',] + ) + } + pub async fn network_list(config: BlockchainConfig) -> Result<()> { - let env = Env::new("network-list", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-network-list"), config.clone()).await?; let client = env.connector()?; let networks = client.network_list().await?; @@ -468,7 +477,8 @@ pub mod tests { } pub async fn network_options(config: BlockchainConfig) -> Result<()> { - let env = Env::new("network-options", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-network-options"), config.clone()).await?; let client = env.node::().await?; let version = client.node_version().await?; @@ -482,7 +492,8 @@ pub mod tests { } pub async fn network_status(config: BlockchainConfig) -> Result<()> { - let env = Env::new("network-status", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-network-status"), config.clone()).await?; let client = env.node::().await?; let genesis = client.genesis_block().clone(); @@ -498,7 +509,8 @@ pub mod tests { } pub async fn account(config: BlockchainConfig) -> Result<()> { - let env = Env::new("account", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-account"), config.clone()).await?; let value = 100 * u128::pow(10, config.currency_decimals); let wallet = env.ephemeral_wallet()?; @@ -513,7 +525,8 @@ pub mod tests { } pub async fn construction(config: BlockchainConfig) -> Result<()> { - let env = Env::new("construction", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-construction"), config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let value = u128::pow(10, config.currency_decimals); @@ -530,7 +543,8 @@ pub mod tests { } pub async fn find_transaction(config: BlockchainConfig) -> Result<()> { - let env = Env::new("find-transaction", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-find-transaction"), config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let value = u128::pow(10, config.currency_decimals); @@ -548,7 +562,8 @@ pub mod tests { } pub async fn list_transactions(config: BlockchainConfig) -> Result<()> { - let env = Env::new("list-transactions", config.clone()).await?; + let env_id = env_id(); + let env = Env::new(&format!("{env_id}-list-transactions"), config.clone()).await?; let faucet = 100 * u128::pow(10, config.currency_decimals); let value = u128::pow(10, config.currency_decimals); From d8f47983a11592822ef97ac31934f8bc820c17c7 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Thu, 27 Jul 2023 22:40:00 +0100 Subject: [PATCH 2/3] issue-147: Remove indexer (#148) * Remove indexer * Remove dead code * Refactor state variable name * Remove unused dependencies * Fix clippy warnings * Update Cargo.lock --- Cargo.lock | 60 +---- chains/astar/server/src/lib.rs | 14 -- chains/ethereum/server/src/lib.rs | 13 - chains/polkadot/server/src/lib.rs | 12 - docker-compose.yml | 35 +-- rosetta-crypto/src/address/mod.rs | 2 - rosetta-docker/src/lib.rs | 1 - rosetta-server/Cargo.toml | 5 +- rosetta-server/src/indexer.rs | 402 ------------------------------ rosetta-server/src/lib.rs | 99 +------- 10 files changed, 19 insertions(+), 624 deletions(-) delete mode 100644 rosetta-server/src/indexer.rs diff --git a/Cargo.lock b/Cargo.lock index 59d3a527..362a3887 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1565,7 +1565,7 @@ dependencies = [ "hashbrown 0.14.0", "lock_api", "once_cell", - "parking_lot_core 0.9.8", + "parking_lot_core", ] [[package]] @@ -3941,17 +3941,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -3959,21 +3948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -4794,7 +4769,6 @@ dependencies = [ "rosetta-docker", "serde", "serde_json", - "sled", "tide", "tokio", "tokio-retry", @@ -5741,22 +5715,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "sled" -version = "0.34.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" -dependencies = [ - "crc32fast", - "crossbeam-epoch", - "crossbeam-utils", - "fs2", - "fxhash", - "libc", - "log", - "parking_lot 0.11.2", -] - [[package]] name = "smallvec" version = "1.11.0" @@ -5851,7 +5809,7 @@ dependencies = [ "itertools", "log", "lru", - "parking_lot 0.12.1", + "parking_lot", "rand 0.8.5", "serde", "serde_json", @@ -5967,7 +5925,7 @@ dependencies = [ "log", "merlin 2.0.1", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot", "paste", "primitive-types", "rand 0.8.5", @@ -6075,7 +6033,7 @@ checksum = "9be3cdd67cc1d9c1db17c5cbc4ec4924054a8437009d167f21f6590797e4aa45" dependencies = [ "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot", "sp-core", "sp-externalities", "thiserror", @@ -6156,7 +6114,7 @@ dependencies = [ "hash-db", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot", "rand 0.8.5", "smallvec", "sp-core", @@ -6214,7 +6172,7 @@ dependencies = [ "memory-db", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot", "scale-info", "schnellru", "sp-core", @@ -6370,7 +6328,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "phf_shared 0.10.0", "precomputed-hash", ] @@ -6939,7 +6897,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite 0.2.10", "signal-hook-registry", "socket2", diff --git a/chains/astar/server/src/lib.rs b/chains/astar/server/src/lib.rs index f1eba76d..4a54b891 100644 --- a/chains/astar/server/src/lib.rs +++ b/chains/astar/server/src/lib.rs @@ -234,20 +234,6 @@ mod tests { rosetta_server::tests::construction(config).await } - #[tokio::test] - #[ignore] - async fn test_find_transaction() -> Result<()> { - let config = rosetta_config_astar::config("dev")?; - rosetta_server::tests::find_transaction(config).await - } - - #[tokio::test] - #[ignore] - async fn test_list_transactions() -> Result<()> { - let config = rosetta_config_astar::config("dev")?; - rosetta_server::tests::list_transactions(config).await - } - fn compile_snippet(source: &str) -> Result> { let solc = Solc::default(); let source = format!("contract Contract {{ {source} }}"); diff --git a/chains/ethereum/server/src/lib.rs b/chains/ethereum/server/src/lib.rs index 618ed9eb..e84dace0 100644 --- a/chains/ethereum/server/src/lib.rs +++ b/chains/ethereum/server/src/lib.rs @@ -383,19 +383,6 @@ mod tests { rosetta_server::tests::construction(config).await } - #[tokio::test] - #[ignore] - async fn test_find_transaction() -> Result<()> { - let config = rosetta_config_ethereum::config("dev")?; - rosetta_server::tests::find_transaction(config).await - } - - #[tokio::test] - async fn test_list_transactions() -> Result<()> { - let config = rosetta_config_ethereum::config("dev")?; - rosetta_server::tests::list_transactions(config).await - } - fn compile_snippet(source: &str) -> Result> { let solc = Solc::default(); let source = format!("contract Contract {{ {source} }}"); diff --git a/chains/polkadot/server/src/lib.rs b/chains/polkadot/server/src/lib.rs index 38914ad2..5c1b28a9 100644 --- a/chains/polkadot/server/src/lib.rs +++ b/chains/polkadot/server/src/lib.rs @@ -336,16 +336,4 @@ mod tests { let config = rosetta_config_polkadot::config("dev")?; rosetta_server::tests::construction(config).await } - - #[tokio::test] - async fn test_find_transaction() -> Result<()> { - let config = rosetta_config_polkadot::config("dev")?; - rosetta_server::tests::find_transaction(config).await - } - - #[tokio::test] - async fn test_list_transactions() -> Result<()> { - let config = rosetta_config_polkadot::config("dev")?; - rosetta_server::tests::list_transactions(config).await - } } diff --git a/docker-compose.yml b/docker-compose.yml index d59013f3..2fbb86e9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,10 +5,6 @@ volumes: ethereum-volume: polkadot-volume: astar-volume: - bitcoin-connector-volume: - ethereum-connector-volume: - polkadot-connector-volume: - astar-connector-volume: services: bitcoin: @@ -62,10 +58,9 @@ services: astar: image: "staketechnologies/astar-collator:v5.15.0" - command: "astar-collator --chain dev --ws-port 9994 --rpc-port 9995 --rpc-cors all --ws-external --alice --blocks-pruning archive --state-pruning archive --base-path /polkadot" + command: "astar-collator --chain dev --rpc-port=9994 --rpc-cors=all --rpc-external --alice --tmp --enable-evm-rpc --base-path /astar" expose: - "9994" - - "9995" user: root ulimits: nofile: @@ -81,55 +76,35 @@ services: connector-bitcoin: image: "analoglabs/connector-bitcoin" - command: "--network regtest --addr 0.0.0.0:8080 --node-addr bitcoin:18443 --path /data" + command: "--network regtest --addr 0.0.0.0:8080 --node-addr http://bitcoin:18443" ports: - "8080:8080" depends_on: - bitcoin - volumes: - - "bitcoin-connector-volume:/data" connector-ethereum: image: "analoglabs/connector-ethereum" - command: "--network dev --addr 0.0.0.0:8081 --node-addr ethereum:8545 --path /data" + command: "--network dev --addr 0.0.0.0:8081 --node-addr http://ethereum:8545" ports: - "8081:8081" depends_on: - ethereum - volumes: - - "ethereum-connector-volume:/data" connector-polkadot: image: "analoglabs/connector-polkadot" - command: "--network dev --addr 0.0.0.0:8082 --node-addr polkadot:9944 --path /data" + command: "--network dev --addr 0.0.0.0:8082 --node-addr ws://polkadot:9944" ports: - "8082:8082" depends_on: - polkadot - volumes: - - "polkadot-connector-volume:/data" # TODO: need to do a proper health check restart: always connector-astar: image: "analoglabs/connector-astar" - command: "--network dev --addr 0.0.0.0:8083 --node-addr astar:9994 --path /data" + command: "--network dev --addr 0.0.0.0:8083 --node-addr ws://astar:9994" ports: - "8083:8083" depends_on: - astar - volumes: - - "astar-connector-volume:/data" - # TODO: need to do a proper health check restart: always - - - explorer: - image: "analoglabs/rosetta-explorer" - ports: - - "3000:3000" - depends_on: - - connector-bitcoin - - connector-ethereum - - connector-polkadot - - connector-astar diff --git a/rosetta-crypto/src/address/mod.rs b/rosetta-crypto/src/address/mod.rs index 5664aa4b..6d4a7d50 100644 --- a/rosetta-crypto/src/address/mod.rs +++ b/rosetta-crypto/src/address/mod.rs @@ -14,8 +14,6 @@ mod ss58; pub use ss58::{Ss58AddressFormat, Ss58AddressFormatRegistry}; -/// Error format - /// Address format. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AddressFormat { diff --git a/rosetta-docker/src/lib.rs b/rosetta-docker/src/lib.rs index a25b58a6..04bedde9 100644 --- a/rosetta-docker/src/lib.rs +++ b/rosetta-docker/src/lib.rs @@ -263,7 +263,6 @@ impl<'a> EnvBuilder<'a> { format!("--network={}", config.network), format!("--addr=0.0.0.0:{}", config.connector_port), format!("--node-addr={}", config.node_uri.with_host(link.as_str())), - "--path=/data".into(), ]) .auto_remove(true) .attach_stdout(true) diff --git a/rosetta-server/Cargo.toml b/rosetta-server/Cargo.toml index 3ceffbc3..0575e6c9 100644 --- a/rosetta-server/Cargo.toml +++ b/rosetta-server/Cargo.toml @@ -7,7 +7,7 @@ repository = "https://github.com/analog-labs/chain-connectors" description = "Generic rosetta server implementation." [features] -tests = ["futures", "rosetta-docker"] +tests = ["futures", "rosetta-docker", "nanoid"] [dependencies] anyhow = "1.0.69" @@ -17,12 +17,11 @@ femme = "2.2.1" futures = { version = "0.3.26", optional = true } hex = "0.4.3" log = "0.4.17" -nanoid = "0.4.0" +nanoid = { version = "0.4.0", optional = true } rosetta-core = { version = "0.4.0", path = "../rosetta-core" } rosetta-docker = { version = "0.4.0", path = "../rosetta-docker", optional = true } serde = "1.0.153" serde_json = "1.0.94" -sled = "0.34.7" tide = { version = "0.16.0", default-features = false, features = ["h1-server", "logger"] } tokio = { version = "1.26.0", features = ["full"] } tokio-retry = "0.3" diff --git a/rosetta-server/src/indexer.rs b/rosetta-server/src/indexer.rs deleted file mode 100644 index c9ee783a..00000000 --- a/rosetta-server/src/indexer.rs +++ /dev/null @@ -1,402 +0,0 @@ -use crate::types::{ - AccountIdentifier, Block, BlockTransaction, CoinIdentifier, Currency, Operator, - PartialBlockIdentifier, SearchTransactionsRequest, SearchTransactionsResponse, Transaction, - TransactionIdentifier, -}; -use crate::BlockchainClient; -use anyhow::Result; -use std::ops::Deref; -use std::path::Path; - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub struct TransactionRef { - pub block_index: u64, - pub transaction_index: u32, -} - -impl TransactionRef { - fn new(block_index: u64, transaction_index: u32) -> Self { - Self { - block_index, - transaction_index, - } - } - - fn to_bytes(self) -> [u8; 12] { - let mut buf = [0; 12]; - buf[..8].copy_from_slice(&self.block_index.to_be_bytes()[..]); - buf[8..].copy_from_slice(&self.transaction_index.to_be_bytes()[..]); - buf - } - - fn from_bytes(bytes: &[u8]) -> Self { - let mut block_index = [0; 8]; - block_index.copy_from_slice(&bytes[..8]); - let block_index = u64::from_be_bytes(block_index); - let mut transaction_index = [0; 4]; - transaction_index.copy_from_slice(&bytes[8..]); - let transaction_index = u32::from_be_bytes(transaction_index); - Self::new(block_index, transaction_index) - } -} - -#[derive(Clone, Debug)] -pub struct TransactionTable { - tree: sled::Tree, -} - -impl TransactionTable { - pub fn new(tree: sled::Tree) -> Self { - Self { tree } - } - - pub fn height(&self) -> Result { - Ok(if let Some(height) = self.tree.get([])? { - u64::from_be_bytes(height[..].try_into()?) - } else { - 0 - }) - } - - pub fn set_height(&self, height: u64) -> Result<()> { - self.tree.insert([], &height.to_be_bytes())?; - Ok(()) - } - - pub fn iter(&self) -> impl Iterator> { - self.tree - .iter() - .values() - .map(|res| Ok(TransactionRef::from_bytes(&res?))) - } - - pub fn get(&self, tx: &TransactionIdentifier) -> Result> { - Ok(self - .tree - .get(hex::decode(&tx.hash)?)? - .map(|value| TransactionRef::from_bytes(&value))) - } - - pub fn insert(&self, tx: &TransactionIdentifier, tx_ref: &TransactionRef) -> Result<()> { - self.tree - .insert(hex::decode(&tx.hash)?, &tx_ref.to_bytes()[..])?; - Ok(()) - } - - pub fn len(&self) -> usize { - self.tree.len() - } - - #[allow(unused)] - pub fn remove(&self, tx: &TransactionIdentifier) -> Result<()> { - self.tree.remove(hex::decode(&tx.hash)?)?; - Ok(()) - } -} - -#[derive(Clone, Debug)] -pub struct AccountTable { - tree: sled::Tree, -} - -impl AccountTable { - pub fn new(tree: sled::Tree) -> Self { - Self { tree } - } - - pub fn get(&self, account: &AccountIdentifier) -> impl Iterator> { - let address_len = account.address.as_bytes().len(); - self.tree - .scan_prefix(account.address.as_bytes()) - .keys() - .map(move |key| Ok(TransactionRef::from_bytes(&key?[address_len..]))) - } - - pub fn insert(&self, account: &AccountIdentifier, tx: &TransactionRef) -> Result<()> { - self.tree.insert(account_table_key(account, tx), &[])?; - Ok(()) - } - - pub fn len(&self, account: &AccountIdentifier) -> usize { - self.tree - .scan_prefix(account.address.as_bytes()) - .keys() - .count() - } - - #[allow(unused)] - pub fn remove(&self, account: &AccountIdentifier, tx: &TransactionRef) -> Result<()> { - self.tree.remove(account_table_key(account, tx))?; - Ok(()) - } -} - -fn account_table_key(account: &AccountIdentifier, tx: &TransactionRef) -> Vec { - let address_len = account.address.as_bytes().len(); - let mut key = Vec::with_capacity(address_len + 12); - key.extend(account.address.as_bytes()); - key.extend(tx.to_bytes()); - key -} - -#[derive(Clone)] -pub struct Indexer { - transaction_table: TransactionTable, - account_table: AccountTable, - client: C, -} - -impl Deref for Indexer { - type Target = C; - - fn deref(&self) -> &Self::Target { - &self.client - } -} - -impl Indexer { - pub fn new(db: &Path, client: C) -> Result { - let db = sled::open(db)?; - let transaction_table = TransactionTable::new(db.open_tree("transaction_table")?); - let account_table = AccountTable::new(db.open_tree("account_table")?); - Ok(Self { - transaction_table, - account_table, - client, - }) - } - - async fn block_by_index(&self, index: u64) -> Result { - self.client - .block(&PartialBlockIdentifier { - index: Some(index), - hash: None, - }) - .await - } - - async fn get(&self, tx: &TransactionRef) -> Result> { - let block = self.block_by_index(tx.block_index).await?; - Ok( - if let Some(transaction) = block - .transactions - .get(tx.transaction_index as usize) - .cloned() - { - Some(BlockTransaction { - block_identifier: block.block_identifier.clone(), - transaction, - }) - } else { - None - }, - ) - } - - async fn transaction(&self, tx: &TransactionIdentifier) -> Result> { - if let Some(tx) = self.transaction_table.get(tx)? { - self.get(&tx).await - } else { - Ok(None) - } - } - - pub async fn sync(&self) -> Result<()> { - let synced_height = self.transaction_table.height()?; - let current_height = self.client.current_block().await?.index; - for block_index in (synced_height + 1)..current_height + 1 { - let block = self.block_by_index(block_index).await?; - for (transaction_index, transaction) in block.transactions.iter().enumerate() { - let tx = TransactionRef::new(block_index, transaction_index as _); - self.transaction_table - .insert(&transaction.transaction_identifier, &tx)?; - for op in &transaction.operations { - if let Some(account) = op.account.as_ref() { - self.account_table.insert(account, &tx)?; - } - } - } - log::info!("indexed blocks to {}", block_index); - self.transaction_table.set_height(block_index)?; - } - Ok(()) - } - - pub async fn search( - &self, - req: &SearchTransactionsRequest, - ) -> Result { - let height = self.transaction_table.height()?; - let max_block = req.max_block.unwrap_or(height as _) as u64; - let mut offset = req.offset.unwrap_or(0); - let limit = std::cmp::min(req.limit.unwrap_or(100), 1000) as usize; - let account = if let Some(account) = &req.account_identifier { - Some(account.clone()) - } else { - req.address.as_ref().map(|address| AccountIdentifier { - address: address.clone(), - sub_account: None, - metadata: None, - }) - }; - let matcher = Matcher { - op: req.operator.unwrap_or(Operator::And), - status: req.status.as_deref(), - r#type: req.r#type.as_deref(), - success: req.success, - currency: req.currency.as_ref(), - coin: req.coin_identifier.as_ref(), - }; - - let mut transactions = Vec::with_capacity(limit as _); - let (next_offset, total_count) = if let Some(tx) = req.transaction_identifier.as_ref() { - let total_count = if let Some(tx) = self.transaction(tx).await? { - if matcher.matches(&tx.transaction) { - transactions.push(tx); - } - 1 - } else { - 0 - }; - (None, total_count) - } else if let Some(account) = account.as_ref() { - let mut block: Option = None; - for tx in self.account_table.get(account).skip(offset as usize) { - let tx = tx?; - let cached = block - .as_ref() - .map(|block| block.block_identifier.index == tx.block_index) - .unwrap_or_default(); - if !cached { - if tx.block_index > max_block { - break; - } - block = Some(self.block_by_index(tx.block_index).await?); - } - let block = block.as_ref().unwrap(); - offset += 1; - if let Some(tx) = block.transactions.get(tx.transaction_index as usize) { - if matcher.matches(tx) { - transactions.push(BlockTransaction { - block_identifier: block.block_identifier.clone(), - transaction: tx.clone(), - }); - if transactions.len() >= limit { - break; - } - } - } - } - (Some(offset), self.account_table.len(account)) - } else { - let mut block: Option = None; - for tx in self.transaction_table.iter().skip(offset as usize) { - let tx = tx?; - let cached = block - .as_ref() - .map(|block| block.block_identifier.index == tx.block_index) - .unwrap_or_default(); - if !cached { - if tx.block_index > max_block { - break; - } - block = Some(self.block_by_index(tx.block_index).await?); - } - let block = block.as_ref().unwrap(); - offset += 1; - if let Some(tx) = block.transactions.get(tx.transaction_index as usize) { - if matcher.matches(tx) { - transactions.push(BlockTransaction { - block_identifier: block.block_identifier.clone(), - transaction: tx.clone(), - }); - if transactions.len() >= limit { - break; - } - } - } - } - (Some(offset), self.transaction_table.len()) - }; - Ok(SearchTransactionsResponse { - transactions, - total_count: total_count as _, - next_offset, - }) - } -} - -struct Matcher<'a> { - op: Operator, - r#type: Option<&'a str>, - status: Option<&'a str>, - currency: Option<&'a Currency>, - coin: Option<&'a CoinIdentifier>, - success: Option, -} - -impl<'a> Matcher<'a> { - fn matches(&self, tx: &Transaction) -> bool { - let mut matches_success = false; - if let Some(success) = self.success { - matches_success = success == is_success(tx); - } - let mut matches_type = false; - let mut matches_status = false; - let mut matches_currency = false; - let mut matches_coin = false; - for op in &tx.operations { - if let Some(ty) = self.r#type { - if ty == op.r#type { - matches_type = true; - } - } - if let Some(status) = self.status { - if let Some(op_status) = op.status.as_deref() { - if status == op_status { - matches_status = true; - } - } - } - if let Some(currency) = self.currency { - if let Some(amount) = op.amount.as_ref() { - if currency == &amount.currency { - matches_currency = true; - } - } - } - if let Some(coin) = self.coin { - if let Some(coin_change) = op.coin_change.as_ref() { - if coin == &coin_change.coin_identifier { - matches_coin = true; - } - } - } - } - match self.op { - Operator::And => { - (matches_success || self.success.is_none()) - && (matches_type || self.r#type.is_none()) - && (matches_status || self.status.is_none()) - && (matches_currency || self.currency.is_none()) - && (matches_coin || self.coin.is_none()) - } - Operator::Or => { - matches_success - || matches_type - || matches_status - || matches_currency - || matches_coin - } - } - } -} - -// TODO: is this really correct? -fn is_success(tx: &Transaction) -> bool { - if let Some(op) = tx.operations.last() { - !op.r#type.to_lowercase().contains("fail") - } else { - false - } -} diff --git a/rosetta-server/src/lib.rs b/rosetta-server/src/lib.rs index 7ab2c3a2..19c808a8 100644 --- a/rosetta-server/src/lib.rs +++ b/rosetta-server/src/lib.rs @@ -1,4 +1,3 @@ -use crate::indexer::Indexer; use anyhow::Result; use clap::Parser; use rosetta_core::crypto::address::Address; @@ -9,10 +8,9 @@ use rosetta_core::types::{ BlockTransactionResponse, CallRequest, CallResponse, ConstructionMetadataRequest, ConstructionMetadataResponse, ConstructionSubmitRequest, MetadataRequest, NetworkIdentifier, NetworkListResponse, NetworkOptionsResponse, NetworkRequest, NetworkStatusResponse, - SearchTransactionsRequest, TransactionIdentifier, TransactionIdentifierResponse, Version, + TransactionIdentifier, TransactionIdentifierResponse, Version, }; use std::net::SocketAddr; -use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; use tide::http::headers::HeaderValue; @@ -25,8 +23,6 @@ use tokio_retry::{ pub use rosetta_core::*; -mod indexer; - #[derive(Parser)] struct Opts { #[clap(long)] @@ -35,8 +31,6 @@ struct Opts { addr: SocketAddr, #[clap(long)] node_addr: String, - #[clap(long)] - path: PathBuf, } pub async fn main() -> Result<()> { @@ -65,8 +59,6 @@ pub async fn main() -> Result<()> { .await? }; - let indexer = Arc::new(Indexer::new(&opts.path, client)?); - let cors = CorsMiddleware::new() .allow_methods("POST".parse::().unwrap()) .allow_origin(Origin::from("*")) @@ -74,16 +66,7 @@ pub async fn main() -> Result<()> { let mut app = tide::new(); app.with(tide::log::LogMiddleware::new()); app.with(cors); - app.at("/").nest(server(indexer.clone())); - - tokio::task::spawn(async move { - loop { - tokio::time::sleep(Duration::from_secs(10)).await; - if let Err(err) = indexer.sync().await { - log::error!("{}", err); - } - } - }); + app.at("/").nest(server(Arc::new(client))); log::info!("listening on {}", &opts.addr); app.listen(opts.addr).await?; @@ -91,7 +74,7 @@ pub async fn main() -> Result<()> { Ok(()) } -type State = Arc>; +type State = Arc; fn server(client: State) -> tide::Server> { let config = client.config(); @@ -113,7 +96,6 @@ fn server(client: State) -> tide::Server> { app.at("/network/list").post(network_list); app.at("/network/options").post(network_options); app.at("/network/status").post(network_status); - app.at("/search/transactions").post(search_transactions); // unsupported app.at("/mempool").post(unsupported); app.at("/mempool/transaction").post(unsupported); @@ -352,19 +334,6 @@ async fn block_transaction(mut req: Request>) -> t ok(&response) } -async fn search_transactions(mut req: Request>) -> tide::Result { - let request: SearchTransactionsRequest = req.body_json().await?; - let config = req.state().config(); - if !is_network_supported(&request.network_identifier, config) { - return Error::UnsupportedNetwork.to_result(); - } - let response = match req.state().search(&request).await { - Ok(response) => response, - Err(err) => return Error::RpcError(err).to_result(), - }; - ok(&response) -} - async fn call(mut req: Request>) -> tide::Result { let request: CallRequest = req.body_json().await?; let config = req.state().config(); @@ -450,7 +419,6 @@ impl Error { #[cfg(feature = "tests")] pub mod tests { use super::*; - use futures::stream::StreamExt; use nanoid::nanoid; use rosetta_docker::Env; @@ -541,65 +509,4 @@ pub mod tests { env.shutdown().await?; Ok(()) } - - pub async fn find_transaction(config: BlockchainConfig) -> Result<()> { - let env_id = env_id(); - let env = Env::new(&format!("{env_id}-find-transaction"), config.clone()).await?; - - let faucet = 100 * u128::pow(10, config.currency_decimals); - let value = u128::pow(10, config.currency_decimals); - let alice = env.ephemeral_wallet()?; - alice.faucet(faucet).await?; - - let bob = env.ephemeral_wallet()?; - let tx_id = alice.transfer(bob.account(), value).await?; - - let tx = alice.transaction(tx_id.clone()).await?; - assert_eq!(tx.transaction.transaction_identifier, tx_id); - - env.shutdown().await?; - Ok(()) - } - - pub async fn list_transactions(config: BlockchainConfig) -> Result<()> { - let env_id = env_id(); - let env = Env::new(&format!("{env_id}-list-transactions"), config.clone()).await?; - - let faucet = 100 * u128::pow(10, config.currency_decimals); - let value = u128::pow(10, config.currency_decimals); - let alice = env.ephemeral_wallet()?; - alice.faucet(faucet).await?; - - let bob = env.ephemeral_wallet()?; - alice.transfer(bob.account(), value).await?; - alice.transfer(bob.account(), value).await?; - alice.transfer(bob.account(), value).await?; - - tokio::time::sleep(Duration::from_secs(1)).await; - - let mut stream = bob.transactions(1); - let mut count = 0; - while let Some(res) = stream.next().await { - let transactions = res?; - assert_eq!(transactions.len(), 1); - assert_eq!(stream.total_count(), Some(3)); - count += 1; - assert!(count <= 3); - } - assert_eq!(count, 3); - - let mut stream = bob.transactions(10); - let mut count = 0; - while let Some(res) = stream.next().await { - let transactions = res?; - assert_eq!(transactions.len(), 3); - assert_eq!(stream.total_count(), Some(3)); - count += 1; - assert!(count <= 1); - } - assert_eq!(count, 1); - - env.shutdown().await?; - Ok(()) - } } From 617bf55fe4c5e307dee6974ccfa061b9e7504209 Mon Sep 17 00:00:00 2001 From: Lohann Paterno Coutinho Ferreira Date: Fri, 28 Jul 2023 06:51:54 +0100 Subject: [PATCH 3/3] Support Apple Silicon and Linux Arm64 targets (#140) * Improve build_connection.sh script * Add chain metadata * Fix ci error * Add missing args * Refactor build_connectors.sh * Fix ethereum unit tests * add --no-cache flag * add --no-fail-fast to ci * Remove connector image tag * Add temporary ssh github debug action * Fix CI workflow --- build_connectors.sh | 142 +++++++++++++++++++++++++++++++------ chains/astar/Dockerfile | 21 ++++++ chains/bitcoin/Dockerfile | 21 ++++++ chains/ethereum/Dockerfile | 21 ++++++ chains/polkadot/Dockerfile | 21 ++++++ 5 files changed, 206 insertions(+), 20 deletions(-) diff --git a/build_connectors.sh b/build_connectors.sh index 99abbd1f..e4b92aae 100755 --- a/build_connectors.sh +++ b/build_connectors.sh @@ -1,20 +1,122 @@ -#!/bin/sh -cargo build -p rosetta-server-bitcoin --target x86_64-unknown-linux-musl --release -mkdir -p target/release/bitcoin/bin -cp target/x86_64-unknown-linux-musl/release/rosetta-server-bitcoin target/release/bitcoin/bin -docker build target/release/bitcoin -f chains/bitcoin/Dockerfile -t analoglabs/connector-bitcoin - -cargo build -p rosetta-server-ethereum --target x86_64-unknown-linux-musl --release -mkdir -p target/release/ethereum/bin -cp target/x86_64-unknown-linux-musl/release/rosetta-server-ethereum target/release/ethereum/bin -docker build target/release/ethereum -f chains/ethereum/Dockerfile -t analoglabs/connector-ethereum - -cargo build -p rosetta-server-polkadot --target x86_64-unknown-linux-musl --release -mkdir -p target/release/polkadot/bin -cp target/x86_64-unknown-linux-musl/release/rosetta-server-polkadot target/release/polkadot/bin -docker build target/release/polkadot -f chains/polkadot/Dockerfile -t analoglabs/connector-polkadot - -cargo build -p rosetta-server-astar --target x86_64-unknown-linux-musl --release -mkdir -p target/release/astar/bin -cp target/x86_64-unknown-linux-musl/release/rosetta-server-astar target/release/astar/bin -docker build target/release/astar -f chains/astar/Dockerfile -t analoglabs/connector-astar +#!/usr/bin/env bash +set -e + +# Check for 'git' and abort if it is not available. +git --version > /dev/null 2>&1 || { echo >&2 "ERROR - requires 'git' to get commit hash and tag."; exit 1; } + +REGISTRY_PATH="docker.io/analoglabs" +VCS_REF="$(git rev-parse HEAD)" +IMAGE_TAG="latest" + +# Check for 'uname' and abort if it is not available. +uname -v > /dev/null 2>&1 || { echo >&2 "ERROR - requires 'uname' to identify the platform."; exit 1; } + +# Check for 'docker' and abort if it is not running. +docker info > /dev/null 2>&1 || { echo >&2 "ERROR - requires 'docker', please start docker and try again."; exit 1; } + +# Check for 'rustup' and abort if it is not available. +rustup -V > /dev/null 2>&1 || { echo >&2 "ERROR - requires 'rustup' for compile the binaries"; exit 1; } + +# Detect host architecture +case "$(uname -m)" in + x86_64) + rustTarget='x86_64-unknown-linux-musl' + muslLinker='x86_64-linux-musl-gcc' + ;; + arm64|aarch64) + rustTarget='aarch64-unknown-linux-musl' + muslLinker='aarch64-linux-musl-gcc' + ;; + *) + echo >&2 "ERROR - unsupported architecture: $(uname -m)" + exit 1 + ;; +esac + +# Check if the musl linker is installed +"$muslLinker" --version > /dev/null 2>&1 || { echo >&2 "ERROR - requires '$muslLinker' linker for compile"; exit 1; } + +# Check if the rust target is installed +if ! rustup target list | grep -q "$rustTarget"; then + echo "Installing the musl target with rustup '$rustTarget'" + rustup target add "$rustTarget" +fi + +# Detect host operating system +case $(uname -s) in + # macOS + Darwin) + buildArgs=( + --release + --target "$rustTarget" + --config "target.$rustTarget.linker='$muslLinker'" + --config "env.CC_$rustTarget='$muslLinker'" + ) + ;; + # Linux + Linux) + buildArgs=( + --release + --target "$rustTarget" + ) + ;; + *) + echo >&2 "ERROR - unsupported or unidentified operating system: $(uname -s)" + exit 1 + ;; +esac + +# Build all Connectors +cargo build \ + -p rosetta-server-bitcoin \ + -p rosetta-server-polkadot \ + -p rosetta-server-ethereum \ + -p rosetta-server-astar \ + "${buildArgs[@]}" || exit 1 + +# Move binaries +mkdir -p target/release/{bitcoin,ethereum,polkadot,astar}/bin +cp "target/$rustTarget/release/rosetta-server-bitcoin" target/release/bitcoin/bin +cp "target/$rustTarget/release/rosetta-server-ethereum" target/release/ethereum/bin +cp "target/$rustTarget/release/rosetta-server-polkadot" target/release/polkadot/bin +cp "target/$rustTarget/release/rosetta-server-astar" target/release/astar/bin + +# Build Bitcoin Connector +docker build target/release/bitcoin \ + -f chains/bitcoin/Dockerfile \ + -t analoglabs/connector-bitcoin \ + --build-arg "REGISTRY_PATH=$REGISTRY_PATH" \ + --build-arg "VCS_REF=$VCS_REF" \ + --build-arg "BUILD_DATE=$(date +%Y%m%d)" \ + --build-arg "IMAGE_VERSION=$IMAGE_TAG" \ + --no-cache + +# Build Ethereum Connector +docker build target/release/ethereum \ + -f chains/ethereum/Dockerfile \ + -t analoglabs/connector-ethereum \ + --build-arg "REGISTRY_PATH=$REGISTRY_PATH" \ + --build-arg "VCS_REF=$VCS_REF" \ + --build-arg "BUILD_DATE=$(date +%Y%m%d)" \ + --build-arg "IMAGE_VERSION=$IMAGE_TAG" \ + --no-cache + +# Build Polkadot Connector +docker build target/release/polkadot \ + -f chains/polkadot/Dockerfile \ + -t analoglabs/connector-polkadot \ + --build-arg "REGISTRY_PATH=$REGISTRY_PATH" \ + --build-arg "VCS_REF=$VCS_REF" \ + --build-arg "BUILD_DATE=$(date +%Y%m%d)" \ + --build-arg "IMAGE_VERSION=$IMAGE_TAG" \ + --no-cache + +# Build Astar Connector +docker build target/release/astar \ + -f chains/astar/Dockerfile \ + -t analoglabs/connector-astar \ + --build-arg "REGISTRY_PATH=$REGISTRY_PATH" \ + --build-arg "VCS_REF=$VCS_REF" \ + --build-arg "BUILD_DATE=$(date +%Y%m%d)" \ + --build-arg "IMAGE_VERSION=$IMAGE_TAG" \ + --no-cache diff --git a/chains/astar/Dockerfile b/chains/astar/Dockerfile index b40a2902..21ae7275 100644 --- a/chains/astar/Dockerfile +++ b/chains/astar/Dockerfile @@ -1,3 +1,24 @@ +ARG REGISTRY_PATH +ARG IMAGE_VERSION +ARG VCS_REF +ARG BUILD_DATE + FROM scratch + +# metadata +LABEL summary="Analog’s connectors for astar parachain" \ + name="${REGISTRY_PATH}/connector-astar" \ + version="${IMAGE_VERSION}" \ + description="Astar chain connector" \ + one.analog.image.vendor="Analog One Foundation" \ + one.analog.image.source="https://github.com/Analog-Labs/chain-connectors/blob/${VCS_REF}/\ +chains/astar/Dockerfile" \ + one.analog.image.revision="${VCS_REF}" \ + one.analog.image.created="${BUILD_DATE}" + COPY bin/rosetta-server-astar rosetta-server-astar + +# check if executable works in this container +RUN ["/rosetta-server-astar", "--help"] + ENTRYPOINT ["/rosetta-server-astar"] diff --git a/chains/bitcoin/Dockerfile b/chains/bitcoin/Dockerfile index acfc2232..07b72665 100644 --- a/chains/bitcoin/Dockerfile +++ b/chains/bitcoin/Dockerfile @@ -1,3 +1,24 @@ +ARG REGISTRY_PATH +ARG IMAGE_VERSION +ARG VCS_REF +ARG BUILD_DATE + FROM scratch + +# metadata +LABEL summary="Analog’s connectors for bitcoin network" \ + name="${REGISTRY_PATH}/connector-bitcoin" \ + version="${IMAGE_VERSION}" \ + description="Bitcoin chain connector" \ + one.analog.image.vendor="Analog One Foundation" \ + one.analog.image.source="https://github.com/Analog-Labs/chain-connectors/blob/${VCS_REF}/\ +chains/bitcoin/Dockerfile" \ + one.analog.image.revision="${VCS_REF}" \ + one.analog.image.created="${BUILD_DATE}" + COPY bin/rosetta-server-bitcoin rosetta-server-bitcoin + +# check if executable works in this container +RUN ["/rosetta-server-bitcoin", "--help"] + ENTRYPOINT ["/rosetta-server-bitcoin"] diff --git a/chains/ethereum/Dockerfile b/chains/ethereum/Dockerfile index 83ecc419..d811bc17 100644 --- a/chains/ethereum/Dockerfile +++ b/chains/ethereum/Dockerfile @@ -1,3 +1,24 @@ +ARG REGISTRY_PATH +ARG IMAGE_VERSION +ARG VCS_REF +ARG BUILD_DATE + FROM scratch + +# metadata +LABEL summary="Analog’s connectors for ethereum network" \ + name="${REGISTRY_PATH}/connector-ethereum" \ + version="${IMAGE_VERSION}" \ + description="Ethereum chain connector" \ + one.analog.image.vendor="Analog One Foundation" \ + one.analog.image.source="https://github.com/Analog-Labs/chain-connectors/blob/${VCS_REF}/\ +chains/ethereum/Dockerfile" \ + one.analog.image.revision="${VCS_REF}" \ + one.analog.image.created="${BUILD_DATE}" + COPY bin/rosetta-server-ethereum rosetta-server-ethereum + +# check if executable works in this container +RUN ["/rosetta-server-ethereum", "--help"] + ENTRYPOINT ["/rosetta-server-ethereum"] diff --git a/chains/polkadot/Dockerfile b/chains/polkadot/Dockerfile index 88c1ab4e..714b5d20 100644 --- a/chains/polkadot/Dockerfile +++ b/chains/polkadot/Dockerfile @@ -1,3 +1,24 @@ +ARG REGISTRY_PATH +ARG IMAGE_VERSION +ARG VCS_REF +ARG BUILD_DATE + FROM scratch + +# metadata +LABEL summary="Analog’s connectors for polkadot network" \ + name="${REGISTRY_PATH}/connector-polkadot" \ + version="${IMAGE_VERSION}" \ + description="Polkadot chain connector" \ + one.analog.image.vendor="Analog One Foundation" \ + one.analog.image.source="https://github.com/Analog-Labs/chain-connectors/blob/${VCS_REF}/\ +chains/polkadot/Dockerfile" \ + one.analog.image.revision="${VCS_REF}" \ + one.analog.image.created="${BUILD_DATE}" + COPY bin/rosetta-server-polkadot rosetta-server-polkadot + +# check if executable works in this container +RUN ["/rosetta-server-polkadot", "--help"] + ENTRYPOINT ["/rosetta-server-polkadot"]