From bc21c9e459313b49f6f9d87e639c6a05d315a2ad Mon Sep 17 00:00:00 2001 From: MedovTimur Date: Sun, 26 May 2024 19:31:32 +0300 Subject: [PATCH] minor fixes, add tests --- Cargo.lock | 2431 ++++++++++++++++++++++++---- Cargo.toml | 14 +- app/Cargo.toml | 7 +- app/src/lib.rs | 24 +- app/src/services/admin/funcs.rs | 148 +- app/src/services/admin/mod.rs | 89 +- app/src/services/aggregated/mod.rs | 31 +- app/src/services/erc20/funcs.rs | 1 + app/src/services/erc20/mod.rs | 2 +- app/src/services/erc20/utils.rs | 1 + app/src/services/pausable/mod.rs | 2 +- app/src/services/roles/mod.rs | 10 +- app/src/services/utils.rs | 4 +- app/tests/node_test.rs | 170 ++ app/tests/test.rs | 116 ++ app/tests/utils/mod.rs | 36 + app/tests/utils_gclient/mod.rs | 211 +++ erc20_wasm.opt.wasm | Bin 124269 -> 140093 bytes wasm/.binpath | 2 +- wasm/Cargo.toml | 7 +- wasm/build.rs | 8 +- wasm/{erc20.idl => ft.idl} | 12 +- 22 files changed, 2942 insertions(+), 384 deletions(-) create mode 100644 app/tests/node_test.rs create mode 100644 app/tests/test.rs create mode 100644 app/tests/utils/mod.rs create mode 100644 app/tests/utils_gclient/mod.rs rename wasm/{erc20.idl => ft.idl} (92%) diff --git a/Cargo.lock b/Cargo.lock index 0a853f1..b6704fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,9 +14,9 @@ dependencies = [ [[package]] name = "actor-system-error" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec45e6f7ab7ffaf319988b1e1bb43e293362b8df84250af85630b7544a9c107a" +checksum = "4f8a6550b9526fc02453c364913479fe4b1bb096c9d7ac1611b62c3363cf508a" dependencies = [ "derive_more", ] @@ -45,13 +45,48 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -63,7 +98,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.14", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -110,47 +145,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.13" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -158,15 +194,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" [[package]] name = "array-bytes" -version = "6.2.2" +version = "6.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" +checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293" [[package]] name = "arrayref" @@ -195,6 +231,165 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy 0.5.2", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8828ec6e544c02b0d6691d21ed9f9218d0384a82542855073c2a3f58304aaf0" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand 2.1.0", + "futures-lite 2.3.0", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.3.0", + "parking", + "polling 3.7.0", + "rustix 0.38.34", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + +[[package]] +name = "async-net" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0434b1ed18ce1cf5769b8ac540e33f01fa9471058b5e89da9e06f3c882a8c12f" +dependencies = [ + "async-io 1.13.0", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.34", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-signal" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afe66191c335039c7bb78f99dc7520b0cbb166b3a1cb33a03f53d8a1c6f2afda" +dependencies = [ + "async-io 2.3.2", + "async-lock 3.3.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.34", + "signal-hook-registry", + "slab", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + [[package]] name = "async-trait" version = "0.1.80" @@ -203,14 +398,26 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "backtrace" @@ -233,18 +440,39 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + [[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64ct" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" +dependencies = [ + "serde", +] + [[package]] name = "bincode" version = "1.3.3" @@ -254,6 +482,21 @@ dependencies = [ "serde", ] +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + [[package]] name = "bitflags" version = "1.3.2" @@ -360,6 +603,19 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite 2.3.0", + "piper", +] + [[package]] name = "bounded-collections" version = "0.1.9" @@ -441,9 +697,9 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "camino" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" dependencies = [ "serde", ] @@ -471,11 +727,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cargo_toml" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a98356df42a2eb1bd8f1793ae4ee4de48e384dd974ce5eac8eee802edb7492be" +dependencies = [ + "serde", + "toml", +] + [[package]] name = "cc" -version = "1.0.95" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" [[package]] name = "cfg-expr" @@ -492,6 +758,30 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.38" @@ -506,11 +796,31 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" [[package]] name = "colored" @@ -522,6 +832,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -543,7 +862,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", "once_cell", "tiny-keccak", ] @@ -595,6 +914,16 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.6" @@ -603,9 +932,9 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-processor" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de23a26b09a0dabcc4f3074f85f6d18885136dd70085bb132e8b4e1f61cc5f6" +checksum = "236806467c5f5e08191835709e5900787a1997f1cb52187004aed6a6354bae38" dependencies = [ "actor-system-error", "derive_more", @@ -721,9 +1050,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -747,11 +1076,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -778,6 +1116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array 0.14.7", + "rand_core 0.6.4", "typenum", ] @@ -801,6 +1140,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "2.1.3" @@ -852,41 +1200,90 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core 0.14.4", + "darling_macro 0.14.4", ] [[package]] name = "darling" -version = "0.20.8" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core 0.20.9", + "darling_macro 0.20.9", +] + +[[package]] +name = "darling_core" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ - "darling_core", - "darling_macro", + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 2.0.60", + "strsim 0.11.1", + "syn 2.0.66", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core 0.14.4", + "quote", + "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" dependencies = [ - "darling_core", + "darling_core 0.20.9", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -899,6 +1296,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive-syn-parse" version = "0.1.5" @@ -1083,9 +1491,9 @@ dependencies = [ [[package]] name = "either" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" [[package]] name = "elliptic-curve" @@ -1121,7 +1529,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" dependencies = [ - "enum-iterator-derive 1.3.1", + "enum-iterator-derive 1.4.0", ] [[package]] @@ -1137,13 +1545,13 @@ dependencies = [ [[package]] name = "enum-iterator-derive" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19cbb53d33b57ac4df1f0af6b92c38c107cded663c4aea9fae1189dcfc17cf5" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1161,10 +1569,10 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ - "darling", + "darling 0.20.9", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1220,15 +1628,17 @@ name = "erc20" version = "0.1.0" dependencies = [ "env_logger 0.11.3", + "gclient", + "gear-core", "gear-wasm-builder", "gstd", + "gtest", "log", "parity-scale-codec", "primitive-types", - "sails-idl-meta", - "sails-macros", "sails-rtl", "scale-info", + "tokio", ] [[package]] @@ -1237,19 +1647,84 @@ version = "0.1.0" dependencies = [ "erc20", "gear-wasm-builder", - "sails-idlgen", + "sails-idl-gen", ] [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "etc" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b241177c7107d9829286c2ffdc5eee98d992d6356f3515e7f412f988b1a72fd" + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.0", + "pin-project-lite", +] + [[package]] name = "expander" version = "2.1.0" @@ -1261,7 +1736,7 @@ dependencies = [ "prettier-please", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1276,6 +1751,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + [[package]] name = "fastrand" version = "2.1.0" @@ -1294,9 +1778,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "fixed-hash" @@ -1325,6 +1809,17 @@ dependencies = [ "percent-encoding", ] +[[package]] +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" @@ -1345,7 +1840,7 @@ checksum = "12ab435a28c0b92be45e871a20faae7307a5f1153168aed11076892511b97332" dependencies = [ "bitflags 1.3.2", "environmental", - "frame-metadata", + "frame-metadata 16.0.0", "frame-support-procedural", "impl-trait-for-tuples", "k256", @@ -1388,7 +1883,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1401,7 +1896,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1412,7 +1907,7 @@ checksum = "0c3562da4b7b8e24189036c58d459b260e10c8b7af2dd180b7869ae29bb66277" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1499,6 +1994,34 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand 2.1.0", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -1507,7 +2030,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -1522,6 +2045,12 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.30" @@ -1542,18 +2071,39 @@ dependencies = [ [[package]] name = "galloc" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99dca925c5f3985a741dc70c55372b8896c775d9022977feb713d6b2e5926714" +checksum = "eec05cbaee718ae5fe97e62dacbec2807186c942ed24e72e6984e6bb2e81ab3f" dependencies = [ "gear-dlmalloc", ] +[[package]] +name = "gclient" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673d9cf393858a473ae64b800427dd29a91caf002e543b87e9e732272fc65c15" +dependencies = [ + "anyhow", + "async-trait", + "futures", + "gear-core", + "gear-core-errors", + "gear-utils", + "gsdk", + "hex", + "parity-scale-codec", + "subxt", + "thiserror", + "url", + "wabt", +] + [[package]] name = "gcore" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c54420edffb115198575c6d9cd408f3936bfa3feb6fbddd573681a43c6183524" +checksum = "6dcd57f0ef3eada83210201b59f0cff9fe2c3849563eccf03f5942943adb4ae8" dependencies = [ "gear-core-errors", "gear-stack-buffer", @@ -1563,9 +2113,9 @@ dependencies = [ [[package]] name = "gear-common" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff00021793ef3316be5629d7998b13c5cb8702153ccc4579ef8d52d6cf014454" +checksum = "8d0d189a85244cc0f2da12bed3ab52bb31aea2455702e5e62a624b1332dfc96f" dependencies = [ "derive_more", "enum-iterator 1.5.0", @@ -1586,19 +2136,19 @@ dependencies = [ [[package]] name = "gear-common-codegen" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b404ba0a180173918fac0067c08b5d3a8fab2051dc6f06c5687e1481c11bfb5" +checksum = "4952f29b83939ab19c2ed52afc219776d0dc43541864d607e869c5af85a52f3b" dependencies = [ "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "gear-core" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "660f7f6866240b8c42831f9351dcd9d7430e34af85f28cb1e8cf4c4629072994" +checksum = "6f6d6e9d3d4eee34166236bff1622b1ee22379097ccd03c2cd843ccd790fac5f" dependencies = [ "blake2-rfc", "byteorder", @@ -1607,10 +2157,11 @@ dependencies = [ "gear-core-errors", "gear-wasm-instrument", "gsys", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "log", "num-traits", + "numerated", "parity-scale-codec", "paste", "scale-info", @@ -1620,9 +2171,9 @@ dependencies = [ [[package]] name = "gear-core-backend" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5372f3e9c4538c236d4de5c47ab11f09b737e38be5c4b51477d6aab415eb3c34" +checksum = "5b58fcea032ed4e65ae0e01c43e5cf417180b887daf4214a26730b37a3d0ea3a" dependencies = [ "actor-system-error", "blake2-rfc", @@ -1640,9 +2191,9 @@ dependencies = [ [[package]] name = "gear-core-errors" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36293ee8813273934186736378c2d25019031790713c2c5fc5215e3a42766dbb" +checksum = "ee3baa8a387c829d5045015f788a31a35b6cd50df72f25420bb850d2bd432416" dependencies = [ "derive_more", "enum-iterator 1.5.0", @@ -1665,9 +2216,9 @@ dependencies = [ [[package]] name = "gear-lazy-pages" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0151d562c87ee96c982027b08ee04979fb9b4ae9070648cbe83f491591f419" +checksum = "6f7dc103df0762cb9bb8d7542eb592025438e8eefe6ba0ef0feefd3fbfd6a0bc" dependencies = [ "cfg-if", "derive_more", @@ -1679,6 +2230,7 @@ dependencies = [ "log", "mach", "nix", + "numerated", "region", "sp-wasm-interface-common", "winapi", @@ -1686,9 +2238,9 @@ dependencies = [ [[package]] name = "gear-lazy-pages-common" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc797ee72dabca5c1f00059b13e044dd563c4d002f46a43e41daeec24e28be12" +checksum = "0cc7eb677fe5858fbe9986a7efb0e9f4edb8485e179ad673c620b25f058de46d" dependencies = [ "gear-core", "num_enum", @@ -1697,9 +2249,9 @@ dependencies = [ [[package]] name = "gear-lazy-pages-interface" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6193c95d62343666ea01f9c998ecb030d7e6d41b38c6c7acb42a4d19fb4213a" +checksum = "835118723f4f9c92397c200b4010e3e9b786ad4a4f76ce4cb3f9195ef400ad79" dependencies = [ "byteorder", "gear-common", @@ -1723,9 +2275,9 @@ dependencies = [ [[package]] name = "gear-runtime-interface" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bc8634992d30f1f29bb3e39edf4722fd054bb0de12ad77447959a4fbcae065" +checksum = "acafa1d430af6cacb236cde58d351898a8fdb6bc578bdb3358d9d81f65f75628" dependencies = [ "byteorder", "gear-core", @@ -1743,9 +2295,9 @@ dependencies = [ [[package]] name = "gear-sandbox" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dfe89b66020e136aa345cfeed2d833a37919d0dee428bd6e8237f9d2d5c3236" +checksum = "b8fc632508a89bb79b53f9908e698b6ca1ebca0741c2139927ac2e66ae09cb13" dependencies = [ "gear-runtime-interface", "gear-sandbox-env", @@ -1759,9 +2311,9 @@ dependencies = [ [[package]] name = "gear-sandbox-env" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2020a9e098a03bb2dd7cfdc8bbd0bb18d68af9f0aaeaf1eb1a9b7fd10d7f782f" +checksum = "4d46c37e2aa67d4ec9e398d622024d3f009fa25fcccd606d29d6694cddc95727" dependencies = [ "parity-scale-codec", "sp-debug-derive", @@ -1771,9 +2323,9 @@ dependencies = [ [[package]] name = "gear-sandbox-host" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e84a742d8f0d067806cb47eb38a6d3e79fa7680a42f04d524592902cd0700ee4" +checksum = "ef003d6736020d54c242e040aeb42666068b7e4b5ec6d5472d43529fc8cbd13b" dependencies = [ "environmental", "gear-sandbox-env", @@ -1787,20 +2339,31 @@ dependencies = [ "wasmer", "wasmer-cache", "wasmer-types", - "wasmi", + "wasmi 0.13.2", +] + +[[package]] +name = "gear-ss58" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8a82173968491c367a0fd0a315337f942228d3663322a9c08b66e057903858" +dependencies = [ + "anyhow", + "blake2", + "bs58 0.5.1", ] [[package]] name = "gear-stack-buffer" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda85b63aca9a1abbe646995225ddf92f210a204916bec1f1463aa43236081ec" +checksum = "78c49ff4ab26f2949996266c3edce0cb3494931d546e4ee8ae928c65c3a50fce" [[package]] name = "gear-utils" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf1bdb9a9cbc65a968ac137179dc9acdd1f9523fc1074d52277202b75ae60e7" +checksum = "89ea24c1f22c250523656ec9c1cfefd4ddec91131435a58a9fc48a5ab468e896" dependencies = [ "env_logger 0.10.2", "gear-core", @@ -1820,9 +2383,9 @@ checksum = "bbfbfa701dc65e683fcd2fb24f046bcef22634acbdf47ad14724637dc39ad05b" [[package]] name = "gear-wasm-builder" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a33590365b3e06e6b7a97cbf64befd64bd5c97002329158f7511a6d5a016d5" +checksum = "b048074283e5e81f039668709de25d69fb63d43adc9260a5dfb7a0fb7ba8b314" dependencies = [ "anyhow", "cargo_metadata", @@ -1837,6 +2400,7 @@ dependencies = [ "once_cell", "pathdiff", "regex", + "rustc_version", "thiserror", "toml", "wasmparser-nostd", @@ -1845,9 +2409,9 @@ dependencies = [ [[package]] name = "gear-wasm-instrument" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86a68b7cec417630759073a22805ae7628c5663ae695e37ed4980edf0fc22660" +checksum = "4a30f5b93b1278ed6157924b60afae8d7b9d1697ba893b71be8f36f3527622cf" dependencies = [ "derive_more", "enum-iterator 1.5.0", @@ -1887,9 +2451,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -1905,6 +2469,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug 0.3.1", + "polyval", +] + [[package]] name = "gimli" version = "0.26.2" @@ -1933,11 +2507,17 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" + [[package]] name = "gmeta" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0307bbffd022225d8b35712daa3ad126ec9637e5ce9d0808971a77c628e24ad" +checksum = "8ab99c1c5b31b55620dac12ba4bd042fac156a6f2842c9c4edcfd278caf8c6ae" dependencies = [ "blake2-rfc", "derive_more", @@ -1986,7 +2566,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2016,21 +2596,63 @@ dependencies = [ "subtle", ] +[[package]] +name = "gsdk" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "191437fb62ba5c0743b65283f450afa1e5446bbdab9b7b9bcf2d67263e4de5e8" +dependencies = [ + "anyhow", + "base64 0.21.7", + "colored", + "futures", + "futures-util", + "gear-core", + "gear-core-errors", + "gear-utils", + "gsdk-codegen", + "hex", + "indexmap 2.2.6", + "jsonrpsee 0.16.3", + "log", + "parity-scale-codec", + "parking_lot", + "rand 0.8.5", + "scale-decode", + "scale-value", + "serde", + "serde_json", + "sp-core", + "sp-runtime", + "subxt", + "thiserror", +] + +[[package]] +name = "gsdk-codegen" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba45bf62736d7f636d34eec157c522a2696730b6127ef3445151726838008b4" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "gstd" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8216c54291edaab2a1935913bea6b2ea421b9e24b706e79f9fb86486635e8108" +checksum = "191118e6cdbc43811c17d96aaa4cf52a402e474f5f626936825bc0d1b330fc68" dependencies = [ "arrayvec 0.7.4", - "bs58 0.5.1", "const_format", "futures", "galloc", "gcore", "gear-core-errors", "gstd-codegen", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "parity-scale-codec", "primitive-types", @@ -2039,31 +2661,35 @@ dependencies = [ [[package]] name = "gstd-codegen" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "054636b87f7a7eef568707a94c2660b2a354330aca556d25386dd94dc1778426" +checksum = "f0122a5b154e398c88b477644ca560e59296de2001f20bf4d16f21760923f3ce" dependencies = [ + "gear-ss58", + "hex", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "gsys" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f7dc9624dc4bdcb00e675b4a20c39a127c2cbb15be223592e044ab0f155f2b1" +checksum = "7e26e485e593d193dbea49821a9f67f83ffaec4f82c289b860b56dd2fd092462" [[package]] name = "gtest" -version = "1.3.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ebe1a09120472bd29ebfea7da5b70f3370a7ef7dda2b55babbfb3bd3a3b3826" +checksum = "70c5f0d488266355a09b6b1777fd3b10d1a5875027604cbff3c6449c8ed2dd14" dependencies = [ + "cargo_toml", "colored", "core-processor", "derive_more", "env_logger 0.10.2", + "etc", "gear-core", "gear-core-errors", "gear-lazy-pages", @@ -2072,6 +2698,7 @@ dependencies = [ "gear-wasm-instrument", "gsys", "hex", + "indexmap 2.2.6", "log", "parity-scale-codec", "path-clean", @@ -2114,6 +2741,25 @@ dependencies = [ "region", ] +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "handlebars" version = "4.5.0" @@ -2172,14 +2818,21 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ "ahash 0.8.11", "allocator-api2", + "serde", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -2242,32 +2895,107 @@ dependencies = [ ] [[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "iana-time-zone" -version = "0.1.60" +name = "http" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "http-body" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "cc", + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "webpki-roots", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", ] [[package]] @@ -2333,7 +3061,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.14.5", ] [[package]] @@ -2342,6 +3070,24 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + [[package]] name = "integer-sqrt" version = "0.1.5" @@ -2379,6 +3125,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -2403,6 +3155,195 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpsee" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367a292944c07385839818bb71c8d76611138e2dedb0677d035b8da21d29c78b" +dependencies = [ + "jsonrpsee-core 0.16.3", + "jsonrpsee-http-client 0.16.3", + "jsonrpsee-types 0.16.3", + "jsonrpsee-ws-client", +] + +[[package]] +name = "jsonrpsee" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affdc52f7596ccb2d7645231fc6163bb314630c989b64998f3699a28b4d5d4dc" +dependencies = [ + "jsonrpsee-client-transport 0.20.3", + "jsonrpsee-core 0.20.3", + "jsonrpsee-http-client 0.20.3", + "jsonrpsee-types 0.20.3", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8b3815d9f5d5de348e5f162b316dc9cdf4548305ebb15b4eb9328e66cf27d7a" +dependencies = [ + "futures-util", + "http", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "webpki-roots", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +dependencies = [ + "futures-util", + "http", + "jsonrpsee-core 0.20.3", + "pin-project", + "rustls-native-certs", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" +dependencies = [ + "anyhow", + "async-lock 2.8.0", + "async-trait", + "beef", + "futures-channel", + "futures-timer", + "futures-util", + "hyper", + "jsonrpsee-types 0.16.3", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +dependencies = [ + "anyhow", + "async-lock 2.8.0", + "async-trait", + "beef", + "futures-timer", + "futures-util", + "hyper", + "jsonrpsee-types 0.20.3", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5f9fabdd5d79344728521bb65e3106b49ec405a78b66fbff073b72b389fa43" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f80c17f62c7653ce767e3d7288b793dfec920f97067ceb189ebdd3570f2bc20" +dependencies = [ + "async-trait", + "hyper", + "hyper-rustls", + "jsonrpsee-core 0.20.3", + "jsonrpsee-types 0.20.3", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245ba8e5aa633dd1c1e4fae72bce06e71f42d34c14a2767c6b4d173b57bee5e5" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +dependencies = [ + "anyhow", + "beef", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e1b3975ed5d73f456478681a417128597acd6a2487855fdb7b4a3d4d195bf5e" +dependencies = [ + "http", + "jsonrpsee-client-transport 0.16.3", + "jsonrpsee-core 0.16.3", + "jsonrpsee-types 0.16.3", +] + [[package]] name = "k256" version = "0.13.3" @@ -2439,9 +3380,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libc-print" @@ -2485,7 +3426,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" dependencies = [ "arrayref", - "base64", + "base64 0.13.1", "digest 0.9.0", "hmac-drbg", "libsecp256k1-core", @@ -2534,9 +3475,15 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -2575,6 +3522,12 @@ dependencies = [ "syn 1.0.109", ] +[[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" @@ -2602,7 +3555,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2616,7 +3569,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2627,7 +3580,7 @@ checksum = "d710e1214dffbab3b5dacb21475dde7d6ed84c69ff722b3a47a782668d44fbac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2638,7 +3591,7 @@ checksum = "b8fb85ec1620619edf2984a7693497d4ec88a9665d8b87e942856884c92dbf2a" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -2740,15 +3693,32 @@ dependencies = [ "zeroize", ] +[[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.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + [[package]] name = "more-asserts" version = "0.2.2" @@ -2768,6 +3738,12 @@ dependencies = [ "pin-utils", ] +[[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" @@ -2780,6 +3756,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +[[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 = "nonempty" version = "0.8.1" @@ -2788,11 +3774,10 @@ checksum = "aeaf4ad7403de93e699c191202f017118df734d3850b01e13a3a8b2e6953d3c9" [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2818,11 +3803,10 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", "num-bigint", "num-integer", "num-traits", @@ -2830,9 +3814,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -2864,7 +3848,19 @@ checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", +] + +[[package]] +name = "numerated" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d916380bb26b78ca4f72aedba04025728a57339514cb14fa9c49e5fe95c1eee3" +dependencies = [ + "derive_more", + "num-traits", + "parity-scale-codec", + "scale-info", ] [[package]] @@ -2918,6 +3914,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + [[package]] name = "page_size" version = "0.6.0" @@ -2930,9 +3932,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ "arrayvec 0.7.4", "bitvec", @@ -2945,11 +3947,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.2", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -2961,11 +3963,17 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2986,9 +3994,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "path-clean" @@ -3020,6 +4028,15 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -3028,9 +4045,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ "memchr", "thiserror", @@ -3039,9 +4056,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -3049,28 +4066,48 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "pest_meta" -version = "2.7.9" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", "sha2 0.10.8", ] +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -3084,8 +4121,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pkcs8" -version = "0.10.2" +name = "piper" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "464db0c665917b13ebb5d453ccdec4add5658ee1adc7affc7677615356a8afaf" +dependencies = [ + "atomic-waker", + "fastrand 2.1.0", + "futures-io", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ @@ -3099,6 +4147,60 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.1", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug 0.3.1", + "universal-hash", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -3112,7 +4214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" dependencies = [ "proc-macro2", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -3140,12 +4242,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.21.1", ] [[package]] @@ -3180,14 +4281,14 @@ checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" dependencies = [ "unicode-ident", ] @@ -3295,7 +4396,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", ] [[package]] @@ -3342,29 +4443,29 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.14", + "getrandom 0.2.15", "libredox", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -3453,6 +4554,21 @@ dependencies = [ "subtle", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rkyv" version = "0.7.44" @@ -3484,9 +4600,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3523,6 +4639,20 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.34" @@ -3532,38 +4662,83 @@ dependencies = [ "bitflags 2.5.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] [[package]] -name = "rustversion" -version = "1.0.15" +name = "rustls" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] [[package]] -name = "ryu" +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] -name = "sails-idl-meta" -version = "0.0.1" -source = "git+https://github.com/gear-tech/sails#2ca9ba7951b16858a4f2623573310a0f4b657961" +name = "ruzstd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3ffab8f9715a0d455df4bbb9d21e91135aab3cd3ca187af0cd0c3c3f868fdc" dependencies = [ - "scale-info", + "byteorder", + "thiserror-core", + "twox-hash", ] [[package]] -name = "sails-idlgen" +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "sails-idl-gen" version = "0.0.1" -source = "git+https://github.com/gear-tech/sails#2ca9ba7951b16858a4f2623573310a0f4b657961" +source = "git+https://github.com/gear-tech/sails?rev=51b731ef8f064a23c6c98fa92d06eeafe44d3f9d#51b731ef8f064a23c6c98fa92d06eeafe44d3f9d" dependencies = [ "convert_case 0.6.0", "handlebars", - "sails-idl-meta", "sails-rtl", "scale-info", "serde", @@ -3574,7 +4749,7 @@ dependencies = [ [[package]] name = "sails-macros" version = "0.0.1" -source = "git+https://github.com/gear-tech/sails#2ca9ba7951b16858a4f2623573310a0f4b657961" +source = "git+https://github.com/gear-tech/sails?rev=51b731ef8f064a23c6c98fa92d06eeafe44d3f9d#51b731ef8f064a23c6c98fa92d06eeafe44d3f9d" dependencies = [ "proc-macro-error", "sails-macros-core", @@ -3583,38 +4758,107 @@ dependencies = [ [[package]] name = "sails-macros-core" version = "0.0.1" -source = "git+https://github.com/gear-tech/sails#2ca9ba7951b16858a4f2623573310a0f4b657961" +source = "git+https://github.com/gear-tech/sails?rev=51b731ef8f064a23c6c98fa92d06eeafe44d3f9d#51b731ef8f064a23c6c98fa92d06eeafe44d3f9d" dependencies = [ + "const_format", "convert_case 0.6.0", "parity-scale-codec", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "sails-rtl" version = "0.0.1" -source = "git+https://github.com/gear-tech/sails#2ca9ba7951b16858a4f2623573310a0f4b657961" +source = "git+https://github.com/gear-tech/sails?rev=51b731ef8f064a23c6c98fa92d06eeafe44d3f9d#51b731ef8f064a23c6c98fa92d06eeafe44d3f9d" dependencies = [ "futures", "gear-core-errors", "gstd", "gtest", - "hashbrown 0.14.3", + "hashbrown 0.14.5", "hex", "parity-scale-codec", "primitive-types", + "sails-macros", "scale-info", "thiserror-no-std", ] +[[package]] +name = "scale-bits" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "036575c29af9b6e4866ffb7fa055dbf623fe7a9cc159b33786de6013a6969d89" +dependencies = [ + "parity-scale-codec", + "scale-info", + "serde", +] + +[[package]] +name = "scale-decode" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7789f5728e4e954aaa20cadcc370b99096fb8645fca3c9333ace44bb18f30095" +dependencies = [ + "derive_more", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode-derive", + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-decode-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27873eb6005868f8cc72dcfe109fae664cf51223d35387bc2f28be4c28d94c47" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "scale-encode" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d70cb4b29360105483fac1ed567ff95d65224a14dd275b6303ed0a654c78de5" +dependencies = [ + "derive_more", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-encode-derive", + "scale-info", + "smallvec", +] + +[[package]] +name = "scale-encode-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "995491f110efdc6bea96d6a746140e32bfceb4ea47510750a5467295a4707a25" +dependencies = [ + "darling 0.14.4", + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "scale-info" -version = "2.11.2" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec", "cfg-if", @@ -3626,21 +4870,50 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.2" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "scale-value" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6538d1cc1af9c0baf401c57da8a6d4730ef582db0d330d2efa56ec946b5b0283" +dependencies = [ + "base58", + "blake2", + "derive_more", + "either", + "frame-metadata 15.1.0", + "parity-scale-codec", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "serde", + "yap", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "schnellru" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +checksum = "c9a8ef13a93c54d20580de1e5c413e624e53121d42fc7e2c11d10ef7f8b02367" dependencies = [ "ahash 0.8.11", "cfg-if", @@ -3665,6 +4938,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "schnorrkel" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "844b7645371e6ecdf61ff246ba1958c29e802881a749ae3fb1993675d210d28d" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "curve25519-dalek-ng", + "merlin 3.0.0", + "rand_core 0.6.4", + "sha2 0.9.9", + "subtle-ng", + "zeroize", +] + [[package]] name = "schnorrkel" version = "0.11.4" @@ -3688,6 +4977,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "seahash" version = "4.1.0" @@ -3735,20 +5034,43 @@ dependencies = [ "zeroize", ] +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.199" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -3764,20 +5086,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.199" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -3786,13 +5108,26 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" dependencies = [ "serde", ] +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + [[package]] name = "sha2" version = "0.8.2" @@ -3848,6 +5183,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + [[package]] name = "signature" version = "1.6.4" @@ -3871,19 +5215,174 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] -name = "slab" -version = "0.4.9" +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "smol" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" +dependencies = [ + "async-channel 1.9.0", + "async-executor", + "async-fs", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-net", + "async-process", + "blocking", + "futures-lite 1.13.0", +] + +[[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 2.8.0", + "atomic", + "base64 0.21.7", + "bip39", + "blake2-rfc", + "bs58 0.5.1", + "crossbeam-queue", + "derive_more", + "ed25519-zebra", + "either", + "event-listener 2.5.3", + "fnv", + "futures-channel", + "futures-util", + "hashbrown 0.14.5", + "hex", + "hmac 0.12.1", + "itertools", + "libsecp256k1", + "merlin 3.0.0", + "no-std-net", + "nom", + "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.8", + "siphasher", + "slab", + "smallvec", + "smol", + "snow", + "soketto", + "tiny-keccak", + "twox-hash", + "wasmi 0.30.0", +] + +[[package]] +name = "smoldot-light" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2f7b4687b83ff244ef6137735ed5716ad37dcdf3ee16c4eb1a32fb9808fa47" +dependencies = [ + "async-lock 2.8.0", + "blake2-rfc", + "derive_more", + "either", + "event-listener 2.5.3", + "fnv", + "futures-channel", + "futures-util", + "hashbrown 0.14.5", + "hex", + "itertools", + "log", + "lru", + "parking_lot", + "rand 0.8.5", + "serde", + "serde_json", + "siphasher", + "slab", + "smol", + "smoldot", +] + +[[package]] +name = "snow" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" +dependencies = [ + "aes-gcm", + "blake2", + "chacha20poly1305", + "curve25519-dalek 4.1.2", + "rand_core 0.6.4", + "rustc_version", + "sha2 0.10.8", + "subtle", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ - "autocfg", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "smallvec" -version = "1.13.2" +name = "soketto" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] [[package]] name = "sp-api" @@ -3919,7 +5418,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -3983,7 +5482,7 @@ dependencies = [ "secp256k1", "secrecy", "serde", - "sp-core-hashing", + "sp-core-hashing 10.0.0", "sp-debug-derive", "sp-externalities", "sp-runtime-interface", @@ -3997,6 +5496,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "sp-core-hashing" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee599a8399448e65197f9a6cee338ad192e9023e35e31f22382964c3c174c68" +dependencies = [ + "blake2b_simd", + "byteorder", + "digest 0.10.7", + "sha2 0.10.8", + "sha3", + "sp-std 8.0.0", + "twox-hash", +] + [[package]] name = "sp-core-hashing" version = "10.0.0" @@ -4018,8 +5532,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8dc707d9f5bf155d584900783e328cb3dc79c950f898a18a8f24066f41f040a5" dependencies = [ "quote", - "sp-core-hashing", - "syn 2.0.60", + "sp-core-hashing 10.0.0", + "syn 2.0.66", ] [[package]] @@ -4030,7 +5544,7 @@ checksum = "f12dae7cf6c1e825d13ffd4ce16bd9309db7c539929d0302b4443ed451a9f4e5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -4105,7 +5619,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369e75e418bcfdeede4acb92563ef2d514ad0e7d81c350ba9ae98841a237f3c" dependencies = [ - "frame-metadata", + "frame-metadata 16.0.0", "parity-scale-codec", "scale-info", "sp-std 9.0.0", @@ -4174,7 +5688,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -4317,7 +5831,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -4342,7 +5856,7 @@ checksum = "03223ee788e1490f6341eb5b76501f83abf931fa8b5d83b5f49a4fecaf83f4ae" dependencies = [ "parity-scale-codec", "sp-std 9.0.0", - "wasmi", + "wasmi 0.13.2", ] [[package]] @@ -4410,6 +5924,18 @@ version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ceb97b7225c713c2fd4db0153cb6b3cab244eb37900c3f634ed4d43310d8c34" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "substrate-bip39" version = "0.4.6" @@ -4429,6 +5955,107 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "subxt" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588b8ce92699eeb06290f4fb02dad4f7e426c4e6db4d53889c6bcbc808cf24ac" +dependencies = [ + "async-trait", + "base58", + "blake2", + "derivative", + "either", + "frame-metadata 16.0.0", + "futures", + "hex", + "impl-serde", + "jsonrpsee 0.20.3", + "parity-scale-codec", + "primitive-types", + "scale-bits", + "scale-decode", + "scale-encode", + "scale-info", + "scale-value", + "serde", + "serde_json", + "sp-core-hashing 9.0.0", + "subxt-lightclient", + "subxt-macro", + "subxt-metadata", + "thiserror", + "tracing", +] + +[[package]] +name = "subxt-codegen" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98f5a534c8d475919e9c845d51fc2316da4fcadd04fe17552d932d2106de930e" +dependencies = [ + "frame-metadata 16.0.0", + "heck", + "hex", + "jsonrpsee 0.20.3", + "parity-scale-codec", + "proc-macro2", + "quote", + "scale-info", + "subxt-metadata", + "syn 2.0.66", + "thiserror", + "tokio", +] + +[[package]] +name = "subxt-lightclient" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10fd0ac9b091211f962b6ae19e26cd08e0b86efa064dfb7fac69c8f79f122329" +dependencies = [ + "futures", + "futures-util", + "serde", + "serde_json", + "smoldot-light", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "subxt-macro" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12e8be9ab6fe88b8c13edbe15911e148482cfb905a8b8d5b8d766a64c54be0bd" +dependencies = [ + "darling 0.20.9", + "proc-macro-error", + "subxt-codegen", + "syn 2.0.66", +] + +[[package]] +name = "subxt-metadata" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6898275765d36a37e5ef564358e0341cf41b5f3a91683d7d8b859381b65ac8a" +dependencies = [ + "frame-metadata 16.0.0", + "parity-scale-codec", + "scale-info", + "sp-core-hashing 9.0.0", + "thiserror", +] + [[package]] name = "syn" version = "1.0.109" @@ -4442,9 +6069,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" dependencies = [ "proc-macro2", "quote", @@ -4470,7 +6097,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand", + "fastrand 2.1.0", "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -4486,22 +6113,42 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] +[[package]] +name = "thiserror-core" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c001ee18b7e5e3f62cbf58c7fe220119e68d902bb7443179c0c8aef30090e999" +dependencies = [ + "thiserror-core-impl", +] + +[[package]] +name = "thiserror-core-impl" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c60d69f36615a077cc7663b9cb8e42275722d23e58a7fa3d2c7f2915d09d04" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -4577,23 +6224,86 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2 0.5.7", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] + [[package]] name = "toml" -version = "0.8.2" +version = "0.8.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.22.13", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" dependencies = [ "serde", ] @@ -4606,22 +6316,60 @@ checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.2.6", "toml_datetime", - "winnow", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.8", ] +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + [[package]] name = "tracing" version = "0.1.40" @@ -4642,7 +6390,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] @@ -4720,6 +6468,12 @@ dependencies = [ "hash-db", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "tt-call" version = "1.0.9" @@ -4810,6 +6564,22 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.0" @@ -4845,6 +6615,44 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wabt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bef93d5e6c81a293bccf107cf43aa47239382f455ba14869d36695d8963b9c" +dependencies = [ + "serde", + "serde_derive", + "serde_json", + "wabt-sys", +] + +[[package]] +name = "wabt-sys" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a4e043159f63e16986e713e9b5e1c06043df4848565bf672e27c523864c7791" +dependencies = [ + "cc", + "cmake", + "glob", +] + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -4878,7 +6686,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", "wasm-bindgen-shared", ] @@ -4900,7 +6708,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4913,9 +6721,9 @@ checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-encoder" -version = "0.206.0" +version = "0.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d759312e1137f199096d80a70be685899cd7d3d09c572836bb2e9b69b4dc3b1e" +checksum = "6425e84e42f7f558478e40ecc2287912cb319f2ca68e5c0bb93c61d4fc63fa17" dependencies = [ "leb128", ] @@ -5191,7 +6999,21 @@ checksum = "06c326c93fbf86419608361a2c925a31754cf109da1b8b55737070b4d6669422" dependencies = [ "parity-wasm", "wasmi-validation", - "wasmi_core", + "wasmi_core 0.2.1", +] + +[[package]] +name = "wasmi" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51fb5c61993e71158abf5bb863df2674ca3ec39ed6471c64f07aeaf751d67b4" +dependencies = [ + "intx", + "smallvec", + "spin", + "wasmi_arena", + "wasmi_core 0.12.0", + "wasmparser-nostd", ] [[package]] @@ -5223,6 +7045,18 @@ dependencies = [ "region", ] +[[package]] +name = "wasmi_core" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624e6333e861ef49095d2d678b76ebf30b06bf37effca845be7e5b87c90071b7" +dependencies = [ + "downcast-rs", + "libm", + "num-traits", + "paste", +] + [[package]] name = "wasmparser" version = "0.83.0" @@ -5382,9 +7216,9 @@ dependencies = [ [[package]] name = "wast" -version = "206.0.0" +version = "208.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68586953ee4960b1f5d84ebf26df3b628b17e6173bc088e0acfbce431469795a" +checksum = "bc00b3f023b4e2ccd2e054e240294263db52ae962892e6523e550783c83a67f1" dependencies = [ "bumpalo", "leb128", @@ -5395,13 +7229,19 @@ dependencies = [ [[package]] name = "wat" -version = "1.206.0" +version = "1.208.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4c6f2606276c6e991aebf441b2fc92c517807393f039992a3e0ad873efe4ad" +checksum = "58ed38e59176550214c025ea2bd0eeefd8e86b92d0af6698d5ba95020ec2e07b" dependencies = [ "wast", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "which" version = "4.4.2" @@ -5711,6 +7551,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +dependencies = [ + "memchr", +] + [[package]] name = "wyz" version = "0.5.1" @@ -5720,31 +7569,37 @@ dependencies = [ "tap", ] +[[package]] +name = "yap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4524214bc4629eba08d78ceb1d6507070cc0bcbbed23af74e19e6e924a24cf" + [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5757,5 +7612,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.60", + "syn 2.0.66", ] diff --git a/Cargo.toml b/Cargo.toml index 5332f20..9574398 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,24 +7,18 @@ members = [ [workspace.package] version = "0.1.0" -authors = ["breathx "] edition = "2021" license = "GPL-3.0" [workspace.dependencies] gstd = "1.1.1" gtest = "1.1.1" +gclient = "1.1.1" +gear-core = "1.1.1" gwasm-builder = { package = "gear-wasm-builder", version = "1.1.1" } parity-scale-codec = { version = "3.6", default-features = false } -sails-clientgen = { git = "https://github.com/gear-tech/sails" } -sails-exec-context-gstd = { git = "https://github.com/gear-tech/sails" } -sails-idl-meta ={ git = "https://github.com/gear-tech/sails" } -sails-idlgen = { git = "https://github.com/gear-tech/sails" } -sails-idlparser = { git = "https://github.com/gear-tech/sails" } -sails = { git = "https://github.com/gear-tech/sails" } -sails-rtl = { git = "https://github.com/gear-tech/sails" } -sails-sender = { git = "https://github.com/gear-tech/sails" } -sails-macros = { git = "https://github.com/gear-tech/sails" } +sails-idl-gen = { git = "https://github.com/gear-tech/sails", rev = "51b731ef8f064a23c6c98fa92d06eeafe44d3f9d" } +sails-rtl = { git = "https://github.com/gear-tech/sails", rev = "51b731ef8f064a23c6c98fa92d06eeafe44d3f9d" } scale-info = { version = "2.10", default-features = false } primitive-types = { version = "*", default-features = false } derive-more = { version = "*", default-features = false, features = ["display"] } diff --git a/app/Cargo.toml b/app/Cargo.toml index c7b2db8..0b18b2b 100644 --- a/app/Cargo.toml +++ b/app/Cargo.toml @@ -1,7 +1,6 @@ [package] name = "erc20" version.workspace = true -authors.workspace = true edition.workspace = true license.workspace = true @@ -9,14 +8,16 @@ license.workspace = true gstd.workspace = true primitive-types.workspace = true log.workspace = true -sails-macros.workspace = true sails-rtl.workspace = true -sails-idl-meta.workspace = true parity-scale-codec.workspace = true scale-info.workspace = true [dev-dependencies] env_logger.workspace = true +gclient.workspace = true +gtest.workspace = true +gear-core.workspace = true +tokio = "1" [build-dependencies] gwasm-builder.workspace = true diff --git a/app/src/lib.rs b/app/src/lib.rs index 2cc9cbe..530f5d4 100644 --- a/app/src/lib.rs +++ b/app/src/lib.rs @@ -5,22 +5,25 @@ // TODO (sails): consider sub-services inside (for observing state, for example) // TODO (sails): rename gstd event depositor here to use `notifier`::`Notifier`/`Informer`. -use gstd::{msg, String}; -use sails_macros::{gprogram, groute}; +use gstd::{msg, ActorId, String}; +use sails_rtl::gstd::{gprogram, groute}; use services::{admin, aggregated, erc20, pausable, roles}; pub mod services; -pub struct BreathxProgram(()); +type ServiceOf = ::Exposure; + +pub struct Program(()); // TODO (sails): allow to import all necessary macros at once (gprogram, grout, etc). -// TODO (sails): stop forcing deriving default on `BreathxProgram`. +// TODO (sails): stop forcing deriving default on `Program`. #[gprogram] -impl BreathxProgram { +impl Program { // TODO (sails): fix arguments are unused. // TODO (sails): `#[gconstructor]` pub fn new(name: String, symbol: String, decimals: u8) -> Self { let source = msg::source(); + let program = Self(()); let roles_service = roles::GstdDrivenService::seed(); @@ -29,16 +32,15 @@ impl BreathxProgram { let pausable_service = ::seed(roles_service.clone(), source); let aggregated_service = - ::seed(erc20_service, pausable_service); + ::seed(erc20_service, program.pausable()); - ::seed(roles_service, aggregated_service, source); + ::seed(roles_service, program.pausable(), source); Self(()) } - #[groute] pub fn admin(&self) -> admin::GstdDrivenService { - admin::GstdDrivenService::new(self.roles(), self.aggregated()) + admin::GstdDrivenService::new(self.roles(), self.pausable()) } // TODO (sails): service Erc20: Pausable [pipeline] @@ -48,13 +50,11 @@ impl BreathxProgram { aggregated::GstdDrivenService::new(self.erc20(), self.pausable()) } - #[groute] pub fn pausable(&self) -> pausable::GstdDrivenService { pausable::GstdDrivenService::new(self.roles()) } - #[groute] - pub fn roles(&self) -> roles::GstdDrivenService { + fn roles(&self) -> roles::GstdDrivenService { roles::GstdDrivenService::new() } diff --git a/app/src/services/admin/funcs.rs b/app/src/services/admin/funcs.rs index c234016..5a5ccae 100644 --- a/app/src/services/admin/funcs.rs +++ b/app/src/services/admin/funcs.rs @@ -5,11 +5,20 @@ use crate::services::erc20::{ use gstd::{prelude::*, ActorId}; use primitive_types::U256; -pub fn mint(balances: &mut BalancesMap, to: ActorId, value: U256) -> Result { +pub fn mint( + balances: &mut BalancesMap, + total_supply: &mut U256, + to: ActorId, + value: U256, +) -> Result { if value.is_zero() { return Ok(false); } + let new_total_supply = total_supply + .checked_add(value) + .ok_or(Error::NumericOverflow)?; + let new_to = funcs::balance_of(balances, to) .checked_add(value) .ok_or(Error::NumericOverflow)?; @@ -19,14 +28,21 @@ pub fn mint(balances: &mut BalancesMap, to: ActorId, value: U256) -> Result Result { +pub fn burn( + balances: &mut BalancesMap, + total_supply: &mut U256, + from: ActorId, + value: U256, +) -> Result { if value.is_zero() { return Ok(false); } + let new_total_supply = total_supply.checked_sub(value).ok_or(Error::Underflow)?; let new_from = funcs::balance_of(balances, from) .checked_sub(value) @@ -37,7 +53,7 @@ pub fn burn(balances: &mut BalancesMap, from: ActorId, value: U256) -> Result Vec<(ActorI .map(|(&id, &v)| (id, v)) .collect() } + +#[cfg(test)] +mod tests { + use super::*; + use crate::admin::funcs; + use utils::*; + + macro_rules! assert_ok { + ( $x:expr, $y: expr $(,)? ) => {{ + assert_eq!($x.unwrap(), $y); + }}; + } + + macro_rules! assert_err { + ( $x:expr, $y: expr $(,)? ) => {{ + assert_eq!($x.err().expect("Ran into Ok value"), $y); + }}; + } + + #[test] + fn mint() { + // Initializing thread logger. + let _ = env_logger::try_init(); + + // Creating map + let mut map = balances_map([]); + let mut total_supply: U256 = 100.into(); + let value: U256 = 100.into(); + // # Test case #1. + // Successful Mint + { + assert_ok!( + funcs::mint(&mut map, &mut total_supply, alice(), value), + true + ); + let expected_balance: NonZeroU256 = value.try_into().unwrap(); + assert_eq!(*map.get(&alice()).unwrap(), expected_balance); + assert_eq!(total_supply, 200.into()); + } + // # Test case #2. + // Mint with value equal to 0 + { + assert_ok!( + funcs::mint(&mut map, &mut total_supply, alice(), 0.into()), + false + ); + } + } + + #[test] + fn burn() { + // Initializing thread logger. + let _ = env_logger::try_init(); + + // Creating map + let mut map = balances_map([(dave(), U256::MAX)]); + let mut total_supply: U256 = 100.into(); + let value: U256 = 100.into(); + // # Test case #1. + // Successful Burn + { + assert_ok!( + funcs::burn(&mut map, &mut total_supply, dave(), value), + true + ); + let expected_balance: NonZeroU256 = (U256::MAX - value).try_into().unwrap(); + assert_eq!(*map.get(&dave()).unwrap(), expected_balance); + assert_eq!(total_supply, 0.into()); + } + // # Test case #2. + // Burn with value equal to 0 + { + assert_ok!( + funcs::burn(&mut map, &mut total_supply, dave(), 0.into()), + false + ); + } + + // # Test case #3. + // Burn with Error: Underflow + { + assert_err!( + funcs::burn(&mut map, &mut total_supply, alice(), value), + Error::Underflow + ); + } + } + + mod utils { + use super::{AllowancesMap, BalancesMap}; + use gstd::{ActorId, ToString}; + use primitive_types::U256; + + pub fn allowances_map( + content: [(ActorId, ActorId, U256); N], + ) -> AllowancesMap { + content + .into_iter() + .map(|(k1, k2, v)| ((k1, k2), v.try_into().unwrap())) + .collect() + } + + pub fn balances_map(content: [(ActorId, U256); N]) -> BalancesMap { + content + .into_iter() + .map(|(k, v)| (k, v.try_into().unwrap())) + .collect() + } + + pub fn alice() -> ActorId { + 1u64.into() + } + + pub fn bob() -> ActorId { + 2u64.into() + } + + pub fn charlie() -> ActorId { + 3u64.into() + } + + pub fn dave() -> ActorId { + 4u64.into() + } + } +} diff --git a/app/src/services/admin/mod.rs b/app/src/services/admin/mod.rs index 1064248..6711f9e 100644 --- a/app/src/services/admin/mod.rs +++ b/app/src/services/admin/mod.rs @@ -1,14 +1,14 @@ use self::utils::Role; -use crate::services; use crate::services::admin::roles::{FungibleAdmin, FungibleBurner, FungibleMinter}; +use crate::{services, ServiceOf}; use core::marker::PhantomData; use gstd::{exec, msg, String}; use gstd::{ActorId, Decode, Encode, ToString, TypeInfo, Vec}; use primitive_types::U256; -use sails_macros::gservice; use sails_rtl::gstd::events::{EventTrigger, GStdEventTrigger}; +use sails_rtl::gstd::gservice; -use super::erc20::storage::{AllowancesStorage, BalancesStorage}; +use super::erc20::storage::{AllowancesStorage, BalancesStorage, TotalSupplyStorage}; pub mod funcs; @@ -32,14 +32,14 @@ pub enum Event { // TODO (breathx): once supported in sails impl Clone here pub struct Service { roles_service: services::roles::GstdDrivenService, - aggregated_service: services::aggregated::GstdDrivenService, + pausable_service: ServiceOf, _phantom: PhantomData, } impl> Service { pub fn seed( mut roles_service: services::roles::GstdDrivenService, - aggregated_service: services::aggregated::GstdDrivenService, + pausable_service: ServiceOf, admin: ActorId, ) -> Self { roles_service.register_role::(); @@ -51,7 +51,7 @@ impl> Service { Self { roles_service, - aggregated_service, + pausable_service, _phantom: PhantomData, } } @@ -64,23 +64,34 @@ where { pub fn new( roles_service: services::roles::GstdDrivenService, - aggregated_service: services::aggregated::GstdDrivenService, + pausable_service: ServiceOf, ) -> Self { Self { roles_service, - aggregated_service, + pausable_service, _phantom: PhantomData, } } pub fn mint(&mut self, to: sails_rtl::ActorId, value: U256) -> bool { - services::utils::panicking(|| self.aggregated_service.pausable_service.ensure_unpaused()); - - self.roles_service - .ensure_has_role::(msg::source()); + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); - let mutated = - services::utils::panicking(|| funcs::mint(BalancesStorage::as_mut(), to.into(), value)); + services::utils::panicking(|| { + self.roles_service + .ensure_has_role::(msg::source()) + }); + let mutated = services::utils::panicking(|| { + funcs::mint( + BalancesStorage::as_mut(), + TotalSupplyStorage::as_mut(), + to.into(), + value, + ) + }); if mutated { services::utils::deposit_event(Event::Minted { to, value }); @@ -90,13 +101,24 @@ where } pub fn burn(&mut self, from: sails_rtl::ActorId, value: U256) -> bool { - services::utils::panicking(|| self.aggregated_service.pausable_service.ensure_unpaused()); + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); - self.roles_service - .ensure_has_role::(msg::source()); + services::utils::panicking(|| { + self.roles_service + .ensure_has_role::(msg::source()) + }); let mutated = services::utils::panicking(|| { - funcs::burn(BalancesStorage::as_mut(), from.into(), value) + funcs::burn( + BalancesStorage::as_mut(), + TotalSupplyStorage::as_mut(), + from.into(), + value, + ) }); if mutated { @@ -108,13 +130,21 @@ where // TODO (sails): consider `#[panicking]` and then it expect Result in return type, automatically wrapping closure pub fn allowances_reserve(&mut self, additional: u32) -> () { - services::utils::panicking(|| self.aggregated_service.pausable_service.ensure_unpaused()); + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); funcs::allowances_reserve(AllowancesStorage::as_mut(), additional as usize) } pub fn balances_reserve(&mut self, additional: u32) -> () { - services::utils::panicking(|| self.aggregated_service.pausable_service.ensure_unpaused()); + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); funcs::balances_reserve(BalancesStorage::as_mut(), additional as usize) } @@ -143,9 +173,20 @@ where .map(|(id, v)| (id.into(), v.into())) .collect() } + pub fn has_role(&self, actor: sails_rtl::ActorId, role: String) -> bool { + self.roles_service.has_role(actor, role) + } + + pub fn roles(&self) -> Vec { + self.roles_service.roles() + } pub fn grant_role(&mut self, to: sails_rtl::ActorId, role: Role) -> bool { - services::utils::panicking(|| self.aggregated_service.pausable_service.ensure_unpaused()); + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); services::utils::panicking(|| -> Result { self.roles_service @@ -162,7 +203,11 @@ where } pub fn remove_role(&mut self, from: sails_rtl::ActorId, role: Role) -> bool { - services::utils::panicking(|| self.aggregated_service.pausable_service.ensure_unpaused()); + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); services::utils::panicking(|| -> Result { self.roles_service diff --git a/app/src/services/aggregated/mod.rs b/app/src/services/aggregated/mod.rs index c08c3d5..1a48e0e 100644 --- a/app/src/services/aggregated/mod.rs +++ b/app/src/services/aggregated/mod.rs @@ -1,24 +1,24 @@ -use crate::services; +use crate::{services, ServiceOf}; use core::marker::PhantomData; use gstd::String; use gstd::{ActorId, Decode, Encode, ToString, TypeInfo, Vec}; use primitive_types::U256; -use sails_macros::gservice; use sails_rtl::gstd::events::{EventTrigger, GStdEventTrigger}; +use sails_rtl::gstd::gservice; pub type GstdDrivenService = Service>; // TODO (breathx): once supported in sails impl Clone here pub struct Service { pub erc20_service: services::erc20::GstdDrivenService, - pub pausable_service: services::pausable::GstdDrivenService, + pub pausable_service: ServiceOf, _phantom: PhantomData, } impl Service { pub fn seed( erc20_service: services::erc20::GstdDrivenService, - pausable_service: services::pausable::GstdDrivenService, + pausable_service: ServiceOf, ) -> Self { Self { erc20_service, @@ -35,7 +35,7 @@ where { pub fn new( erc20_service: services::erc20::GstdDrivenService, - pausable_service: services::pausable::GstdDrivenService, + pausable_service: ServiceOf, ) -> Self { Self { erc20_service, @@ -49,8 +49,11 @@ where } pub fn approve(&mut self, spender: sails_rtl::ActorId, value: U256) -> bool { - services::utils::panicking(|| self.pausable_service.ensure_unpaused()); - + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); self.erc20_service.approve(spender, value) } @@ -75,8 +78,11 @@ where } pub fn transfer(&mut self, to: sails_rtl::ActorId, value: U256) -> bool { - services::utils::panicking(|| self.pausable_service.ensure_unpaused()); - + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); self.erc20_service.transfer(to, value) } @@ -86,8 +92,11 @@ where to: sails_rtl::ActorId, value: U256, ) -> bool { - services::utils::panicking(|| self.pausable_service.ensure_unpaused()); - + services::utils::panicking(|| { + (!self.pausable_service.is_paused()) + .then_some(()) + .ok_or(services::pausable::Error::Paused) + }); self.erc20_service.transfer_from(from, to, value) } } diff --git a/app/src/services/erc20/funcs.rs b/app/src/services/erc20/funcs.rs index e0070bc..e8713b6 100644 --- a/app/src/services/erc20/funcs.rs +++ b/app/src/services/erc20/funcs.rs @@ -109,6 +109,7 @@ pub fn transfer_from( #[cfg(test)] mod tests { use super::*; + use crate::erc20::funcs; use utils::*; // TODO (breathx): force macros to assert storage noop. diff --git a/app/src/services/erc20/mod.rs b/app/src/services/erc20/mod.rs index fa8b72e..a2e17ea 100644 --- a/app/src/services/erc20/mod.rs +++ b/app/src/services/erc20/mod.rs @@ -5,8 +5,8 @@ use crate::services; use core::{cmp::Ordering, fmt::Debug, marker::PhantomData}; use gstd::{ext, format, msg, ActorId, Decode, Encode, String, TypeInfo, Vec}; use primitive_types::U256; -use sails_macros::gservice; use sails_rtl::gstd::events::{EventTrigger, GStdEventTrigger}; +use sails_rtl::gstd::gservice; use storage::{AllowancesStorage, BalancesStorage, MetaStorage, TotalSupplyStorage}; pub use utils::*; diff --git a/app/src/services/erc20/utils.rs b/app/src/services/erc20/utils.rs index b569e6b..123d224 100644 --- a/app/src/services/erc20/utils.rs +++ b/app/src/services/erc20/utils.rs @@ -10,6 +10,7 @@ pub enum Error { InsufficientAllowance, InsufficientBalance, NumericOverflow, + Underflow, } #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Decode, Encode, TypeInfo)] diff --git a/app/src/services/pausable/mod.rs b/app/src/services/pausable/mod.rs index 90681ce..18ae906 100644 --- a/app/src/services/pausable/mod.rs +++ b/app/src/services/pausable/mod.rs @@ -1,8 +1,8 @@ use crate::services::{self, pausable::roles::PauseAdmin, roles::storage::RolesStorage}; use core::marker::PhantomData; use gstd::{msg, ActorId, Decode, Encode, String, TypeInfo, Vec}; -use sails_macros::gservice; use sails_rtl::gstd::events::{EventTrigger, GStdEventTrigger}; +use sails_rtl::gstd::gservice; use storage::StateStorage; pub use utils::*; diff --git a/app/src/services/roles/mod.rs b/app/src/services/roles/mod.rs index 467f879..a385d82 100644 --- a/app/src/services/roles/mod.rs +++ b/app/src/services/roles/mod.rs @@ -1,8 +1,8 @@ use crate::services; use core::{any::TypeId, marker::PhantomData}; use gstd::{ActorId, Decode, Encode, String, ToString, TypeInfo, Vec}; -use sails_macros::gservice; use sails_rtl::gstd::events::{EventTrigger, GStdEventTrigger}; +use sails_rtl::gstd::gservice; use storage::{RolesRegistryStorage, RolesStorage}; pub mod funcs; @@ -110,14 +110,6 @@ impl> Service { Ok(res) }); - - if mutated { - services::utils::deposit_event(Event::RoleGranted { - actor: actor.into(), - role: T::name().to_string(), - }) - } - mutated } diff --git a/app/src/services/utils.rs b/app/src/services/utils.rs index 214b987..83e2a27 100644 --- a/app/src/services/utils.rs +++ b/app/src/services/utils.rs @@ -14,12 +14,10 @@ pub fn panic(err: impl Debug) -> ! { ext::panic(&format!("{err:?}")) } -pub fn deposit_event(event: E) -> ! { +pub fn deposit_event(event: E) { if GStdEventTrigger::::new().trigger(event).is_err() { panic("Failed to deposit event"); } - - exec::leave() } #[macro_export] diff --git a/app/tests/node_test.rs b/app/tests/node_test.rs new file mode 100644 index 0000000..ee0010a --- /dev/null +++ b/app/tests/node_test.rs @@ -0,0 +1,170 @@ +use erc20::services::admin::utils::Role; +use gclient::{EventProcessor, GearApi, Result}; +use gstd::{ActorId, Encode}; + +mod utils_gclient; +use sails_rtl::U256; +use utils_gclient::*; + +#[tokio::test] +async fn test_basic_functionality() -> Result<()> { + let api = GearApi::dev_from_path("../target/tmp/gear").await?; + // let api = GearApi::dev().await?; + let mut listener = api.subscribe().await?; + assert!(listener.blocks_running().await?); + + // init + let (message_id, program_id) = init(&api).await; + assert!(listener.message_processed(message_id).await?.succeed()); + + // grant role minter + let user: ActorId = api.get_actor_id(); + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "GrantRole", payload: (user, Role::Minter)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // mint + let value: U256 = 1_000.into(); + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "Mint", payload: (user, value)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let state = get_state_balances(&api, program_id, &mut listener, 0, 1).await; + assert_eq!(state, vec![(user.into(), value)]); + + // grant role burner + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "GrantRole", payload: (user, Role::Burner)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // burn + let value: U256 = 500.into(); + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "Burn", payload: (user, value)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let state = get_state_balances(&api, program_id, &mut listener, 0, 1).await; + assert_eq!(state, vec![(user.into(), value)]); + + // transfer + let to = api.get_specific_actor_id(USERS_STR[0]); + let value: U256 = 250.into(); + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Erc20", action: "Transfer", payload: (to, value)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let state = get_state_balances(&api, program_id, &mut listener, 1, 1).await; + assert_eq!(state, vec![(to.into(), value)]); + + // approve + let spender = api.get_specific_actor_id(USERS_STR[0]); + let value: U256 = 250.into(); + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Erc20", action: "Approve", payload: (spender, value)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // transfer from + let from = user; + let to = api.get_specific_actor_id(USERS_STR[1]); + let new_api = get_new_client(&api, USERS_STR[0]).await; + let value: U256 = 250.into(); + let message_id = send_request!(api: &new_api, program_id: program_id, service_name: "Erc20", action: "TransferFrom", payload: (from, to, value)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let state = get_state_balances(&api, program_id, &mut listener, 0, 3).await; + let user_1 = api.get_actor_id(); + let user_2 = api.get_specific_actor_id(USERS_STR[0]); + let user_3 = api.get_specific_actor_id(USERS_STR[1]); + assert!(!state.contains(&(user_1.into(), 0.into()))); + assert!(state.contains(&(user_2.into(), 250.into()))); + assert!(state.contains(&(user_3.into(), 250.into()))); + + Ok(()) +} + +#[tokio::test] +async fn test_roles() -> Result<()> { + let api = GearApi::dev_from_path("../target/tmp/gear").await?; + + let mut listener = api.subscribe().await?; + assert!(listener.blocks_running().await?); + + // init + let (message_id, program_id) = init(&api).await; + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let user: ActorId = api.get_actor_id(); + let role = "FungibleAdmin".to_string(); + let has_role = get_state_has_role(&api, program_id, &mut listener, user, role).await; + assert!(has_role); + + // grant role minter + let to = api.get_specific_actor_id(USERS_STR[0]); + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "GrantRole", payload: (to, Role::Minter)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let role = "FungibleMinter".to_string(); + let has_role = get_state_has_role(&api, program_id, &mut listener, to, role.clone()).await; + assert!(has_role); + + // remove role minter + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "RemoveRole", payload: (to, Role::Minter)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let has_role = get_state_has_role(&api, program_id, &mut listener, to, role).await; + assert!(!has_role); + + // grant role burner + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "GrantRole", payload: (to, Role::Burner)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let role = "FungibleBurner".to_string(); + let has_role = get_state_has_role(&api, program_id, &mut listener, to, role.clone()).await; + assert!(has_role); + + // remove role burner + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Admin", action: "RemoveRole", payload: (to, Role::Burner)); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let has_role = get_state_has_role(&api, program_id, &mut listener, to, role).await; + assert!(!has_role); + + Ok(()) +} + +#[tokio::test] +async fn test_pausable() -> Result<()> { + let api = GearApi::dev_from_path("../target/tmp/gear").await?; + + let mut listener = api.subscribe().await?; + assert!(listener.blocks_running().await?); + + // init + let (message_id, program_id) = init(&api).await; + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let paused = get_state_is_paused(&api, program_id, &mut listener).await; + assert!(!paused); + + // pause + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Pausable", action: "Pause", payload: ()); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let paused = get_state_is_paused(&api, program_id, &mut listener).await; + assert!(paused); + + // unpause + let message_id = send_request!(api: &api, program_id: program_id, service_name: "Pausable", action: "Unpause", payload: ()); + assert!(listener.message_processed(message_id).await?.succeed()); + + // check state + let paused = get_state_is_paused(&api, program_id, &mut listener).await; + assert!(!paused); + + Ok(()) +} diff --git a/app/tests/test.rs b/app/tests/test.rs new file mode 100644 index 0000000..6295a0a --- /dev/null +++ b/app/tests/test.rs @@ -0,0 +1,116 @@ +use erc20::services::admin::utils::Role; +use gstd::{ActorId, Encode}; +use gtest::System; +use sails_rtl::U256; + +mod utils; +use utils::*; + +#[test] +fn test_roles() { + let sys = System::new(); + sys.init_logger(); + + let ft = init(&sys); + let admin_user: ActorId = USERS[0].into(); + let user: ActorId = USERS[1].into(); + + // failed mint + let value: U256 = 1_000.into(); + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Mint", payload: (admin_user, value)); + assert!(res.main_failed()); + + // failed grant role + let res = send_request!(ft: ft, user: USERS[1], service_name: "Admin", action: "GrantRole", payload: (user, Role::Minter)); + assert!(res.main_failed()); + + // success grant role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "GrantRole", payload: (admin_user, Role::Minter)); + assert!(!res.main_failed()); + + // success mint + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Mint", payload: (admin_user, value)); + assert!(!res.main_failed()); + + // remove role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "RemoveRole", payload: (admin_user, Role::Minter)); + assert!(!res.main_failed()); + + // failed mint + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Burn", payload: (admin_user, value)); + assert!(res.main_failed()); + + // failed burn + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Burn", payload: (admin_user, value)); + assert!(res.main_failed()); + + // grant role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "GrantRole", payload: (admin_user, Role::Burner)); + assert!(!res.main_failed()); + + // success burn + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Burn", payload: (admin_user, value / 2)); + assert!(!res.main_failed()); + + // remove role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "RemoveRole", payload: (admin_user, Role::Burner)); + assert!(!res.main_failed()); + + // failed burn + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Burn", payload: (admin_user, value)); + assert!(res.main_failed()); + + // failed pause + let res = send_request!(ft: ft, user: USERS[1], service_name: "Pausable", action: "Pause", payload: ()); + assert!(res.main_failed()); + + // delegate admin + let res = send_request!(ft: ft, user: USERS[0], service_name: "Pausable", action: "DelegateAdmin", payload: (user)); + assert!(!res.main_failed()); + + // success pause + let res = send_request!(ft: ft, user: USERS[1], service_name: "Pausable", action: "Pause", payload: ()); + assert!(!res.main_failed()); + + // failed kill + let res = send_request!(ft: ft, user: USERS[1], service_name: "Admin", action: "Kill", payload: (user)); + assert!(res.main_failed()); + + // success kill + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Kill", payload: (user)); + assert!(!res.main_failed()); +} + +#[test] +fn test_pausable() { + let sys = System::new(); + sys.init_logger(); + + let ft = init(&sys); + let admin_user: ActorId = USERS[0].into(); + + // success grant role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "GrantRole", payload: (admin_user, Role::Minter)); + assert!(!res.main_failed()); + + // success grant role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "GrantRole", payload: (admin_user, Role::Burner)); + assert!(!res.main_failed()); + + // success pause + let res = send_request!(ft: ft, user: USERS[0], service_name: "Pausable", action: "Pause", payload: ()); + assert!(!res.main_failed()); + + // failed grant role + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "GrantRole", payload: (admin_user, Role::Minter)); + assert!(res.main_failed()); + + // failed mint + let value: U256 = 1_000.into(); + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Mint", payload: (admin_user, value)); + assert!(res.main_failed()); + + // failed burn + let res = send_request!(ft: ft, user: USERS[0], service_name: "Admin", action: "Burn", payload: (admin_user, value)); + assert!(res.main_failed()); +} diff --git a/app/tests/utils/mod.rs b/app/tests/utils/mod.rs new file mode 100644 index 0000000..ec60bd5 --- /dev/null +++ b/app/tests/utils/mod.rs @@ -0,0 +1,36 @@ +use gtest::{Program, System}; +use gstd::Encode; + +pub const USERS: &[u64] = &[3, 4, 5]; + +#[macro_export] +macro_rules! send_request { + (ft: $ft: expr, user: $user: expr, service_name: $name: literal, action: $action: literal, payload: ($($val: expr),*)) => { + { + let request = [ + $name.encode(), + $action.to_string().encode(), + ( $( $val, )*).encode(), + ] + .concat(); + + $ft.send_bytes($user, request) + + } + + }; +} + +pub fn init(sys: &System) -> Program { + let ft = Program::from_file( + sys, + "../target/wasm32-unknown-unknown/release/erc20_wasm.opt.wasm", + ); + + let init = ("TokenName".to_owned(), "TokenSymbol".to_owned(), 10_u8); + let request = ["New".encode(), init.encode()].concat(); + let res = ft.send_bytes(USERS[0], request); + assert!(!res.main_failed()); + + ft +} diff --git a/app/tests/utils_gclient/mod.rs b/app/tests/utils_gclient/mod.rs new file mode 100644 index 0000000..8afd115 --- /dev/null +++ b/app/tests/utils_gclient/mod.rs @@ -0,0 +1,211 @@ +use gclient::{EventProcessor, GearApi, Result}; +use gear_core::ids::{MessageId, ProgramId}; +use gstd::{ActorId, Decode, Encode}; +use sails_rtl::U256; + +pub const USERS_STR: &[&str] = &["//John", "//Mike", "//Dan"]; + +pub trait ApiUtils { + fn get_actor_id(&self) -> ActorId; + fn get_specific_actor_id(&self, value: impl AsRef) -> ActorId; +} + +impl ApiUtils for GearApi { + fn get_actor_id(&self) -> ActorId { + ActorId::new( + self.account_id() + .encode() + .try_into() + .expect("Unexpected invalid account id length."), + ) + } + + fn get_specific_actor_id(&self, value: impl AsRef) -> ActorId { + let api_temp = self + .clone() + .with(value) + .expect("Unable to build `GearApi` instance with provided signer."); + api_temp.get_actor_id() + } +} + +#[macro_export] +macro_rules! send_request { + (api: $api: expr, program_id: $program_id: expr, service_name: $name: literal, action: $action: literal, payload: ($($val: expr),*)) => { + { + let request = [ + $name.encode(), + $action.to_string().encode(), + ( $( $val, )*).encode(), + ] + .concat(); + + let gas_info = $api + .calculate_handle_gas(None, $program_id, request.clone(), 0, true) + .await?; + + + let (message_id, _) = $api + .send_message_bytes($program_id, request.clone(), gas_info.min_limit, 0) + .await?; + + message_id + } + + }; +} + +pub async fn init(api: &GearApi) -> (MessageId, ProgramId) { + let init = ("TokenName".to_owned(), "TokenSymbol".to_owned(), 10_u8); + let request = ["New".encode(), init.encode()].concat(); + let path = "../target/wasm32-unknown-unknown/release/erc20_wasm.opt.wasm"; + let gas_info = api + .calculate_upload_gas( + None, + gclient::code_from_os(path).unwrap(), + request.clone(), + 0, + true, + ) + .await + .expect("Error calculate upload gas"); + + let (message_id, program_id, _hash) = api + .upload_program_bytes( + gclient::code_from_os(path).unwrap(), + gclient::now_micros().to_le_bytes(), + request, + gas_info.min_limit, + 0, + ) + .await + .expect("Error upload program bytes"); + + (message_id, program_id) +} + +fn decode(payload: Vec) -> Result { + Ok(T::decode(&mut payload.as_slice())?) +} + +pub async fn get_state_balances( + api: &GearApi, + program_id: ProgramId, + listener: &mut gclient::EventListener, + skip: u32, + take: u32, +) -> Vec<(sails_rtl::ActorId, U256)> { + let request = [ + "Admin".encode(), + "Balances".to_string().encode(), + (skip, take).encode(), + ] + .concat(); + + let gas_info = api + .calculate_handle_gas(None, program_id, request.clone(), 0, true) + .await + .expect("Error calculate handle gas"); + + let (message_id, _) = api + .send_message_bytes(program_id, request.clone(), gas_info.min_limit, 0) + .await + .expect("Error send message bytes"); + + let (_, raw_reply, _) = listener + .reply_bytes_on(message_id) + .await + .expect("Error listen reply"); + + let decoded_reply: (String, String, Vec<(sails_rtl::ActorId, U256)>) = match raw_reply { + Ok(raw_reply) => decode(raw_reply).expect("Erroe decode reply"), + Err(_error) => gstd::panic!("Error in getting reply"), + }; + decoded_reply.2 +} + +pub async fn get_state_is_paused( + api: &GearApi, + program_id: ProgramId, + listener: &mut gclient::EventListener, +) -> bool { + let request = ["Pausable".encode(), "IsPaused".to_string().encode()].concat(); + + let gas_info = api + .calculate_handle_gas(None, program_id, request.clone(), 0, true) + .await + .expect("Error calculate handle gas"); + + let (message_id, _) = api + .send_message_bytes(program_id, request.clone(), gas_info.min_limit, 0) + .await + .expect("Error send message bytes"); + + let (_, raw_reply, _) = listener + .reply_bytes_on(message_id) + .await + .expect("Error listen reply"); + + let decoded_reply: (String, String, bool) = match raw_reply { + Ok(raw_reply) => decode(raw_reply).expect("Erroe decode reply"), + Err(_error) => gstd::panic!("Error in getting reply"), + }; + decoded_reply.2 +} + +pub async fn get_state_has_role( + api: &GearApi, + program_id: ProgramId, + listener: &mut gclient::EventListener, + user: ActorId, + role: String, +) -> bool { + let request = [ + "Admin".encode(), + "HasRole".to_string().encode(), + (user, role).encode(), + ] + .concat(); + + let gas_info = api + .calculate_handle_gas(None, program_id, request.clone(), 0, true) + .await + .expect("Error calculate handle gas"); + + let (message_id, _) = api + .send_message_bytes(program_id, request.clone(), gas_info.min_limit, 0) + .await + .expect("Error send message bytes"); + + let (_, raw_reply, _) = listener + .reply_bytes_on(message_id) + .await + .expect("Error listen reply"); + + let decoded_reply: (String, String, bool) = match raw_reply { + Ok(raw_reply) => decode(raw_reply).expect("Erroe decode reply"), + Err(_error) => gstd::panic!("Error in getting reply"), + }; + decoded_reply.2 +} + +pub async fn get_new_client(api: &GearApi, name: &str) -> GearApi { + let alice_balance = api + .total_balance(api.account_id()) + .await + .expect("Error total balance"); + let amount = alice_balance / 10; + + api.transfer_keep_alive( + api.get_specific_actor_id(name) + .encode() + .as_slice() + .try_into() + .expect("Unexpected invalid `ProgramId`."), + amount, + ) + .await + .expect("Error transfer"); + + api.clone().with(name).expect("Unable to change signer.") +} diff --git a/erc20_wasm.opt.wasm b/erc20_wasm.opt.wasm index 6f288988c1ca29a4884fb4359fc0c83e6b071342..f10e64a7740a5512dd048ed4ca64165353e1f078 100644 GIT binary patch literal 140093 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 literal 124269 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 diff --git a/wasm/.binpath b/wasm/.binpath index 5a9634b..0125a1b 100644 --- a/wasm/.binpath +++ b/wasm/.binpath @@ -1 +1 @@ -../target/wasm32-unknown-unknown/release/erc20_wasm \ No newline at end of file +../target/wasm32-unknown-unknown/debug/erc20_wasm \ No newline at end of file diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index 2539bf0..688c64d 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -1,11 +1,6 @@ - - - - [package] name = "erc20-wasm" version.workspace = true -authors.workspace = true edition.workspace = true license.workspace = true @@ -14,5 +9,5 @@ erc20 = { path = "../app" } [build-dependencies] gwasm-builder.workspace = true -sails-idlgen.workspace = true +sails-idl-gen.workspace = true erc20 = { path = "../app" } diff --git a/wasm/build.rs b/wasm/build.rs index f6c54fc..21e8f51 100644 --- a/wasm/build.rs +++ b/wasm/build.rs @@ -1,5 +1,5 @@ -use erc20::BreathxProgram; -use sails_idlgen::program; +use erc20::Program; +use sails_idl_gen::program; use std::{env, fs::File, path::PathBuf}; fn main() { @@ -7,9 +7,9 @@ fn main() { let manifest_dir_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); - let idl_file_path = manifest_dir_path.join("erc20.idl"); + let idl_file_path = manifest_dir_path.join("ft.idl"); let idl_file = File::create(idl_file_path).unwrap(); - program::generate_idl::(idl_file).unwrap(); + program::generate_idl::(idl_file).unwrap(); } diff --git a/wasm/erc20.idl b/wasm/ft.idl similarity index 92% rename from wasm/erc20.idl rename to wasm/ft.idl index 2a1507a..17d36a7 100644 --- a/wasm/erc20.idl +++ b/wasm/ft.idl @@ -18,7 +18,9 @@ service Admin { RemoveRole : (from: actor_id, role: Role) -> bool; query Allowances : (skip: u32, take: u32) -> vec struct { struct { actor_id, actor_id }, u256 }; query Balances : (skip: u32, take: u32) -> vec struct { actor_id, u256 }; + query HasRole : (actor: actor_id, role: str) -> bool; query MapsData : () -> struct { struct { u32, u32 }, struct { u32, u32 } }; + query Roles : () -> vec str; events { Minted: struct { to: actor_id, value: u256 }; @@ -56,13 +58,3 @@ service Pausable { } }; -service Roles { - query HasRole : (actor: actor_id, role: str) -> bool; - query Roles : () -> vec str; - - events { - RoleGranted: struct { actor: actor_id, role: str }; - RoleRemoved: struct { actor: actor_id, role: str }; - } -}; -