diff --git a/Cargo.lock b/Cargo.lock index b9646cc55..d4236e699 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,7 +27,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.28.0", + "gimli 0.28.1", ] [[package]] @@ -266,7 +266,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41ed9d5715c2d329bf1b4da8d60455b99b187f27ba726df2883799af9af60997" dependencies = [ - "async-lock 3.1.1", + "async-lock", "cfg-if", "concurrent-queue", "futures-io", @@ -282,20 +282,11 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.8.0" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "dea8b3453dd7cc96711834b75400d671b73e3656975fa68d9f277163b7f7e316" dependencies = [ - "event-listener 2.5.3", -] - -[[package]] -name = "async-lock" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b9c7fe787d3b25cc0f804a1a8401790f0c5bc395beb5a64dc77d8de079105" -dependencies = [ - "event-listener 3.1.0", + "event-listener 4.0.0", "event-listener-strategy", "pin-project-lite 0.2.13", ] @@ -391,12 +382,6 @@ 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 = "base58-monero" version = "2.0.0" @@ -954,9 +939,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.8" +version = "4.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "46ca43acc1b21c6cc2d1d3129c19e323a613935b5bc28fb3b33b5b2e5fb00030" dependencies = [ "clap_builder", "clap_derive", @@ -964,9 +949,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1" dependencies = [ "anstream", "anstyle", @@ -1391,76 +1376,6 @@ dependencies = [ "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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.39", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core 0.20.3", - "quote", - "syn 2.0.39", -] - [[package]] name = "data-encoding" version = "2.5.0" @@ -1530,17 +1445,6 @@ dependencies = [ "serde", ] -[[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" @@ -1807,7 +1711,7 @@ checksum = "7d9ce6874da5d4415896cd45ffbc4d1cfc0c4f9c079427bd870742c30f2f65a9" dependencies = [ "curve25519-dalek", "ed25519", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "hex", "rand_core", "sha2", @@ -2126,9 +2030,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.1.0" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +checksum = "770d968249b5d99410d61f5bf89057f3199a077a04d087092f58e7d10692baae" dependencies = [ "concurrent-queue", "parking", @@ -2137,11 +2041,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96b852f1345da36d551b9473fa1e2b1eb5c5195585c6c018118bc92a8d91160" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 3.1.0", + "event-listener 4.0.0", "pin-project-lite 0.2.13", ] @@ -2378,18 +2282,6 @@ dependencies = [ "sp-tracing", ] -[[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", - "serde", -] - [[package]] name = "frame-metadata" version = "16.0.0" @@ -2409,7 +2301,7 @@ source = "git+https://github.com/serai-dex/substrate#49b7d20ef96b6ad42ea0266ea27 dependencies = [ "bitflags 1.3.2", "environmental", - "frame-metadata 16.0.0", + "frame-metadata", "frame-support-procedural", "impl-trait-for-tuples", "log", @@ -2757,10 +2649,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -2786,9 +2676,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -2798,15 +2688,15 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759c97c1e17c55525b57192c06a267cda0ac5210b222d6b82189a2338fa1c13d" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -2883,9 +2773,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", "allocator-api2", @@ -3067,7 +2957,6 @@ dependencies = [ "rustls-native-certs", "tokio", "tokio-rustls", - "webpki-roots", ] [[package]] @@ -3106,12 +2995,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.2.3" @@ -3243,7 +3126,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "serde", ] @@ -3336,9 +3219,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -3349,36 +3232,13 @@ version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "367a292944c07385839818bb71c8d76611138e2dedb0677d035b8da21d29c78b" dependencies = [ - "jsonrpsee-client-transport", "jsonrpsee-core", - "jsonrpsee-http-client", "jsonrpsee-proc-macros", "jsonrpsee-server", "jsonrpsee-types", "tracing", ] -[[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", - "jsonrpsee-types", - "pin-project", - "rustls-native-certs", - "soketto", - "thiserror", - "tokio", - "tokio-rustls", - "tokio-util", - "tracing", - "webpki-roots", -] - [[package]] name = "jsonrpsee-core" version = "0.16.3" @@ -3387,11 +3247,9 @@ checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" dependencies = [ "anyhow", "arrayvec", - "async-lock 2.8.0", "async-trait", "beef", "futures-channel", - "futures-timer", "futures-util", "globset", "hyper", @@ -3407,25 +3265,6 @@ dependencies = [ "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", - "jsonrpsee-types", - "rustc-hash", - "serde", - "serde_json", - "thiserror", - "tokio", - "tracing", -] - [[package]] name = "jsonrpsee-proc-macros" version = "0.16.3" @@ -4151,11 +3990,11 @@ dependencies = [ [[package]] name = "lru" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" dependencies = [ - "hashbrown 0.14.2", + "hashbrown 0.14.3", ] [[package]] @@ -5317,9 +5156,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" @@ -5579,9 +5418,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -7210,73 +7049,6 @@ dependencies = [ "sp-arithmetic", ] -[[package]] -name = "scale-bits" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dd7aca73785181cc41f0bbe017263e682b585ca660540ba569133901d013ecf" -dependencies = [ - "parity-scale-codec", - "scale-info", - "serde", -] - -[[package]] -name = "scale-decode" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0459d00b0dbd2e765009924a78ef36b2ff7ba116292d732f00eb0ed8e465d15" -dependencies = [ - "parity-scale-codec", - "primitive-types", - "scale-bits", - "scale-decode-derive", - "scale-info", - "smallvec", - "thiserror", -] - -[[package]] -name = "scale-decode-derive" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4391f0dfbb6690f035f6d2a15d6a12f88cc5395c36bcc056db07ffa2a90870ec" -dependencies = [ - "darling 0.14.4", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "scale-encode" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0401b7cdae8b8aa33725f3611a051358d5b32887ecaa0fda5953a775b2d4d76" -dependencies = [ - "parity-scale-codec", - "primitive-types", - "scale-bits", - "scale-encode-derive", - "scale-info", - "smallvec", - "thiserror", -] - -[[package]] -name = "scale-encode-derive" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "316e0fb10ec0fee266822bd641bab5e332a4ab80ef8c5b5ff35e5401a394f5a6" -dependencies = [ - "darling 0.14.4", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "scale-info" version = "2.10.0" @@ -7303,26 +7075,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "scale-value" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2096d36e94ce9bf87d8addb752423b6b19730dc88edd7cc452bb2b90573f7a7" -dependencies = [ - "base58", - "blake2", - "either", - "frame-metadata 15.1.0", - "parity-scale-codec", - "scale-bits", - "scale-decode", - "scale-encode", - "scale-info", - "serde", - "thiserror", - "yap", -] - [[package]] name = "schannel" version = "0.1.22" @@ -7516,18 +7268,18 @@ dependencies = [ "ciphersuite", "dockertest", "frost-schnorrkel", - "futures", "hex", "modular-frost", "monero-serai", "parity-scale-codec", "rand_core", - "scale-info", "serai-docker-tests", "serai-runtime", + "serde", + "serde_json", + "simple-request", "sp-core", "sp-runtime", - "subxt", "thiserror", "tokio", "zeroize", @@ -8614,7 +8366,7 @@ name = "sp-metadata-ir" version = "0.1.0" source = "git+https://github.com/serai-dex/substrate#49b7d20ef96b6ad42ea0266ea27f128e0ef3214d" dependencies = [ - "frame-metadata 16.0.0", + "frame-metadata", "parity-scale-codec", "scale-info", "sp-std", @@ -8811,7 +8563,7 @@ source = "git+https://github.com/serai-dex/substrate#49b7d20ef96b6ad42ea0266ea27 dependencies = [ "ahash", "hash-db", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "lazy_static", "memory-db", "nohash-hasher", @@ -8970,7 +8722,7 @@ dependencies = [ name = "std-shims" version = "0.1.1" dependencies = [ - "hashbrown 0.14.2", + "hashbrown 0.14.3", "spin 0.9.8", ] @@ -9106,83 +8858,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "subxt" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31a734d66fa935fbda56ba6a71d7e969f424c8c5608d416ba8499d71d8cbfc1f" -dependencies = [ - "base58", - "blake2", - "derivative", - "either", - "frame-metadata 15.1.0", - "futures", - "getrandom", - "hex", - "impl-serde", - "jsonrpsee", - "parity-scale-codec", - "primitive-types", - "scale-bits", - "scale-decode", - "scale-encode", - "scale-info", - "scale-value", - "serde", - "serde_json", - "sp-core-hashing", - "subxt-macro", - "subxt-metadata", - "thiserror", - "tracing", -] - -[[package]] -name = "subxt-codegen" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e2f231d97c145c564bd544212c0cc0c29c09ff516af199f4ce00c8e055f8138" -dependencies = [ - "frame-metadata 15.1.0", - "heck", - "hex", - "jsonrpsee", - "parity-scale-codec", - "proc-macro2", - "quote", - "scale-info", - "subxt-metadata", - "syn 2.0.39", - "thiserror", - "tokio", -] - -[[package]] -name = "subxt-macro" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e544e41e1c84b616632cd2f86862342868f62e11e4cd9062a9e3dbf5fc871f64" -dependencies = [ - "darling 0.20.3", - "proc-macro-error", - "subxt-codegen", - "syn 2.0.39", -] - -[[package]] -name = "subxt-metadata" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01ce5044c81db3404d38c56f1e69d72eff72c54e5913c9bba4c0b58d376031f" -dependencies = [ - "frame-metadata 15.1.0", - "parity-scale-codec", - "scale-info", - "sp-core-hashing", - "thiserror", -] - [[package]] name = "syn" version = "1.0.109" @@ -9997,9 +9672,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -10007,9 +9682,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -10022,9 +9697,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if", "js-sys", @@ -10034,9 +9709,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -10044,9 +9719,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -10057,9 +9732,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-encoder" @@ -10374,9 +10049,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "which" @@ -10637,12 +10312,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "yap" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2a7eb6d82a11e4d0b8e6bda8347169aff4ccd8235d039bba7c47482d977dcf7" - [[package]] name = "yasna" version = "0.5.2" diff --git a/coordinator/src/cosign_evaluator.rs b/coordinator/src/cosign_evaluator.rs index 5c45d4143..12c6a698d 100644 --- a/coordinator/src/cosign_evaluator.rs +++ b/coordinator/src/cosign_evaluator.rs @@ -75,7 +75,7 @@ impl CosignEvaluator { } async fn update_stakes(&self) -> Result<(), SeraiError> { - let serai = self.serai.as_of(self.serai.latest_block_hash().await?); + let serai = self.serai.as_of_latest_finalized_block().await?; let mut stakes = HashMap::new(); for network in NETWORKS { @@ -112,13 +112,13 @@ impl CosignEvaluator { } // If this an old cosign (older than a day), drop it - let latest_block = self.serai.latest_block().await?; + let latest_block = self.serai.latest_finalized_block().await?; if (cosign.block_number + (24 * 60 * 60 / 6)) < latest_block.number() { log::debug!("received old cosign supposedly signed by {:?}", cosign.network); return Ok(()); } - let Some(block) = self.serai.block_by_number(cosign.block_number).await? else { + let Some(block) = self.serai.finalized_block_by_number(cosign.block_number).await? else { log::warn!("received cosign with a block number which doesn't map to a block"); return Ok(()); }; diff --git a/coordinator/src/main.rs b/coordinator/src/main.rs index f766d5240..4734b5194 100644 --- a/coordinator/src/main.rs +++ b/coordinator/src/main.rs @@ -1222,8 +1222,8 @@ async fn main() { let serai = || async { loop { - let Ok(serai) = Serai::new(&format!( - "ws://{}:9944", + let Ok(serai) = Serai::new(format!( + "http://{}:9944", serai_env::var("SERAI_HOSTNAME").expect("Serai hostname wasn't provided") )) .await diff --git a/coordinator/src/substrate/mod.rs b/coordinator/src/substrate/mod.rs index d304db704..c961dca62 100644 --- a/coordinator/src/substrate/mod.rs +++ b/coordinator/src/substrate/mod.rs @@ -24,7 +24,6 @@ use serai_db::DbTxn; use processor_messages::SubstrateContext; -use futures::stream::StreamExt; use tokio::{sync::mpsc, time::sleep}; use crate::{ @@ -81,7 +80,7 @@ async fn handle_new_set( assert_eq!(block.number(), 0); // Use the next block's time loop { - let Ok(Some(res)) = serai.block_by_number(1).await else { + let Ok(Some(res)) = serai.finalized_block_by_number(1).await else { sleep(Duration::from_secs(5)).await; continue; }; @@ -340,7 +339,7 @@ async fn handle_new_blocks( next_block: &mut u64, ) -> Result<(), SeraiError> { // Check if there's been a new Substrate block - let latest_number = serai.latest_block().await?.number(); + let latest_number = serai.latest_finalized_block().await?.number(); // TODO: If this block directly builds off a cosigned block *and* doesn't contain events, mark // cosigned, @@ -369,7 +368,7 @@ async fn handle_new_blocks( None => { let serai = serai.as_of( serai - .block_by_number(block) + .finalized_block_by_number(block) .await? .expect("couldn't get block which should've been finalized") .hash(), @@ -432,7 +431,7 @@ async fn handle_new_blocks( skipped_block.map(|skipped_block| skipped_block + COSIGN_DISTANCE); for block in (last_intended_to_cosign_block + 1) ..= latest_number { let actual_block = serai - .block_by_number(block) + .finalized_block_by_number(block) .await? .expect("couldn't get block which should've been finalized"); SeraiBlockNumber::set(&mut txn, actual_block.hash(), &block); @@ -535,7 +534,7 @@ async fn handle_new_blocks( processors, serai, serai - .block_by_number(b) + .finalized_block_by_number(b) .await? .expect("couldn't get block before the latest finalized block"), ) @@ -561,6 +560,7 @@ pub async fn scan_task( let mut db = SubstrateDb::new(db); let mut next_substrate_block = db.next_block(); + /* let new_substrate_block_notifier = { let serai = &serai; move || async move { @@ -575,31 +575,55 @@ pub async fn scan_task( } } }; - let mut substrate_block_notifier = new_substrate_block_notifier().await; + */ + // TODO: Restore the above subscription-based system + let new_substrate_block_notifier = { + let serai = &serai; + move |next_substrate_block| async move { + loop { + match serai.latest_finalized_block().await { + Ok(latest) => { + if latest.header().number >= next_substrate_block { + return latest; + } else { + sleep(Duration::from_secs(3)).await; + } + } + Err(e) => { + log::error!("couldn't communicate with serai node: {e}"); + sleep(Duration::from_secs(5)).await; + } + } + } + } + }; loop { // await the next block, yet if our notifier had an error, re-create it { - let Ok(next_block) = - tokio::time::timeout(Duration::from_secs(60), substrate_block_notifier.next()).await + let Ok(_) = tokio::time::timeout( + Duration::from_secs(60), + new_substrate_block_notifier(next_substrate_block), + ) + .await else { // Timed out, which may be because Serai isn't finalizing or may be some issue with the // notifier - if serai.latest_block().await.map(|block| block.number()).ok() == + if serai.latest_finalized_block().await.map(|block| block.number()).ok() == Some(next_substrate_block.saturating_sub(1)) { log::info!("serai hasn't finalized a block in the last 60s..."); - } else { - substrate_block_notifier = new_substrate_block_notifier().await; } continue; }; + /* // next_block is a Option if next_block.and_then(Result::ok).is_none() { - substrate_block_notifier = new_substrate_block_notifier().await; + substrate_block_notifier = new_substrate_block_notifier(next_substrate_block); continue; } + */ } match handle_new_blocks( @@ -632,12 +656,10 @@ pub(crate) async fn get_expected_next_batch(serai: &Serai, network: NetworkId) - } first = false; - let Ok(latest_block) = serai.latest_block().await else { + let Ok(serai) = serai.as_of_latest_finalized_block().await else { continue; }; - let Ok(last) = - serai.as_of(latest_block.hash()).in_instructions().last_batch_for_network(network).await - else { + let Ok(last) = serai.in_instructions().last_batch_for_network(network).await else { continue; }; break if let Some(last) = last { last + 1 } else { 0 }; diff --git a/coordinator/src/tests/tributary/dkg.rs b/coordinator/src/tests/tributary/dkg.rs index 83ec99118..104a8e1d3 100644 --- a/coordinator/src/tests/tributary/dkg.rs +++ b/coordinator/src/tests/tributary/dkg.rs @@ -321,13 +321,22 @@ async fn dkg_test() { async move { // Version, Pallet, Call, Network, Key Pair, Signature let expected_len = 1 + 1 + 1 + 1 + 32 + 1 + key_pair.1.len() + 64; - assert_eq!(tx.len(), expected_len); + // It's length prefixed + assert_eq!(tx.len(), 2 + expected_len); + let expected_len = u16::try_from(expected_len).unwrap(); + + // Check the encoded length + // This is the compact encoding from SCALE, specifically the two-byte length encoding case + let bottom_six = expected_len & 0b111111; + let upper_eight = expected_len >> 6; + assert_eq!(u8::try_from((bottom_six << 2) | 1).unwrap(), tx[0]); + assert_eq!(u8::try_from(upper_eight).unwrap(), tx[1]); // Version - assert_eq!(tx[0], 4); + assert_eq!(tx[2], 4); // Call - let tx = serai_client::runtime::RuntimeCall::decode(&mut &tx[1 ..]).unwrap(); + let tx = serai_client::runtime::RuntimeCall::decode(&mut &tx[3 ..]).unwrap(); match tx { serai_client::runtime::RuntimeCall::ValidatorSets( serai_client::runtime::validator_sets::Call::set_keys { diff --git a/coordinator/src/tributary/scanner.rs b/coordinator/src/tributary/scanner.rs index 8873de38b..8c8653d60 100644 --- a/coordinator/src/tributary/scanner.rs +++ b/coordinator/src/tributary/scanner.rs @@ -240,7 +240,7 @@ pub(crate) async fn scan_tributaries_task< // creation // TODO2: Differentiate connection errors from invariants Err(e) => { - if let Ok(serai) = serai.with_current_latest_block().await { + if let Ok(serai) = serai.as_of_latest_finalized_block().await { let serai = serai.validator_sets(); // Check if this failed because the keys were already set by someone // else diff --git a/substrate/client/Cargo.toml b/substrate/client/Cargo.toml index 3208470ba..31e142e78 100644 --- a/substrate/client/Cargo.toml +++ b/substrate/client/Cargo.toml @@ -17,17 +17,15 @@ rustdoc-args = ["--cfg", "docsrs"] zeroize = "^1.5" thiserror = { version = "1", optional = true } -futures = "0.3" - hex = "0.4" scale = { package = "parity-scale-codec", version = "3" } -scale-info = { version = "2", optional = true } +serde = { version = "1", features = ["derive"] } +serde_json = "1" sp-core = { git = "https://github.com/serai-dex/substrate" } sp-runtime = { git = "https://github.com/serai-dex/substrate" } serai-runtime = { path = "../runtime", version = "0.1" } - -subxt = { version = "0.29", default-features = false, features = ["jsonrpsee-ws"], optional = true } +simple-request = { path = "../../common/request", version = "0.1" } bitcoin = { version = "0.31", optional = true } @@ -50,7 +48,7 @@ dockertest = "0.4" serai-docker-tests = { path = "../../tests/docker" } [features] -serai = ["thiserror", "scale-info", "subxt"] +serai = ["thiserror"] networks = [] bitcoin = ["networks", "dep:bitcoin"] diff --git a/substrate/client/src/serai/coins.rs b/substrate/client/src/serai/coins.rs index 3c91a2859..755751190 100644 --- a/substrate/client/src/serai/coins.rs +++ b/substrate/client/src/serai/coins.rs @@ -1,11 +1,13 @@ +use scale::Encode; + use serai_runtime::{ - primitives::{SeraiAddress, SubstrateAmount, Amount, Coin, Balance}, - coins, Coins, Runtime, + primitives::{SeraiAddress, Amount, Coin, Balance}, + coins, Runtime, }; pub use coins::primitives; use primitives::OutInstructionWithBalance; -use crate::{TemporalSerai, SeraiError, scale_value}; +use crate::{TemporalSerai, SeraiError}; const PALLET: &str = "Coins"; @@ -19,21 +21,33 @@ impl<'a> SeraiCoins<'a> { } pub async fn mint_events(&self) -> Result, SeraiError> { - self.0.events::(|event| matches!(event, CoinsEvent::Mint { .. })).await + self + .0 + .events(|event| { + if let serai_runtime::RuntimeEvent::Coins(event) = event { + Some(event).filter(|event| matches!(event, CoinsEvent::Mint { .. })) + } else { + None + } + }) + .await } pub async fn burn_with_instruction_events(&self) -> Result, SeraiError> { - self.0.events::(|event| matches!(event, CoinsEvent::BurnWithInstruction { .. })).await + self + .0 + .events(|event| { + if let serai_runtime::RuntimeEvent::Coins(event) = event { + Some(event).filter(|event| matches!(event, CoinsEvent::BurnWithInstruction { .. })) + } else { + None + } + }) + .await } pub async fn coin_supply(&self, coin: Coin) -> Result { - Ok(Amount( - self - .0 - .storage::(PALLET, "Supply", Some(vec![scale_value(coin)])) - .await? - .unwrap_or(0), - )) + Ok(self.0.storage(PALLET, "Supply", coin).await?.unwrap_or(Amount(0))) } pub async fn coin_balance( @@ -41,17 +55,17 @@ impl<'a> SeraiCoins<'a> { coin: Coin, address: SeraiAddress, ) -> Result { - Ok(Amount( + Ok( self .0 - .storage::( + .storage( PALLET, "Balances", - Some(vec![scale_value(address), scale_value(coin)]), + (sp_core::hashing::blake2_128(&address.encode()), &address.0, coin), ) .await? - .unwrap_or(0), - )) + .unwrap_or(Amount(0)), + ) } pub fn transfer(to: SeraiAddress, balance: Balance) -> serai_runtime::RuntimeCall { diff --git a/substrate/client/src/serai/dex.rs b/substrate/client/src/serai/dex.rs index 685e2f49d..a01a9a8a1 100644 --- a/substrate/client/src/serai/dex.rs +++ b/substrate/client/src/serai/dex.rs @@ -1,7 +1,7 @@ use sp_core::bounded_vec::BoundedVec; use serai_runtime::{ primitives::{SeraiAddress, Amount, Coin}, - dex, Dex, Runtime, + dex, Runtime, }; use crate::{SeraiError, TemporalSerai}; @@ -11,8 +11,19 @@ pub type DexEvent = dex::Event; #[derive(Clone, Copy)] pub struct SeraiDex<'a>(pub(crate) TemporalSerai<'a>); impl<'a> SeraiDex<'a> { - pub async fn all_events(&self) -> Result, SeraiError> { - self.0.events::(|_| true).await + pub async fn events(&self) -> Result, SeraiError> { + self + .0 + .events( + |event| { + if let serai_runtime::RuntimeEvent::Dex(event) = event { + Some(event) + } else { + None + } + }, + ) + .await } pub fn add_liquidity( diff --git a/substrate/client/src/serai/in_instructions.rs b/substrate/client/src/serai/in_instructions.rs index bfcfc521e..f15a007d3 100644 --- a/substrate/client/src/serai/in_instructions.rs +++ b/substrate/client/src/serai/in_instructions.rs @@ -1,10 +1,10 @@ -use serai_runtime::{in_instructions, InInstructions, Runtime}; +use serai_runtime::{in_instructions, Runtime}; pub use in_instructions::primitives; use primitives::SignedBatch; use crate::{ primitives::{BlockHash, NetworkId}, - SeraiError, Serai, TemporalSerai, scale_value, + SeraiError, Serai, TemporalSerai, }; pub type InInstructionsEvent = in_instructions::Event; @@ -22,20 +22,26 @@ impl<'a> SeraiInInstructions<'a> { &self, network: NetworkId, ) -> Result, SeraiError> { - self.0.storage(PALLET, "LatestNetworkBlock", Some(vec![scale_value(network)])).await + self.0.storage(PALLET, "LatestNetworkBlock", network).await } pub async fn last_batch_for_network( &self, network: NetworkId, ) -> Result, SeraiError> { - self.0.storage(PALLET, "LastBatch", Some(vec![scale_value(network)])).await + self.0.storage(PALLET, "LastBatch", network).await } pub async fn batch_events(&self) -> Result, SeraiError> { self .0 - .events::(|event| matches!(event, InInstructionsEvent::Batch { .. })) + .events(|event| { + if let serai_runtime::RuntimeEvent::InInstructions(event) = event { + Some(event).filter(|event| matches!(event, InInstructionsEvent::Batch { .. })) + } else { + None + } + }) .await } diff --git a/substrate/client/src/serai/mod.rs b/substrate/client/src/serai/mod.rs index 320569f2f..b725c02a1 100644 --- a/substrate/client/src/serai/mod.rs +++ b/substrate/client/src/serai/mod.rs @@ -1,36 +1,20 @@ -use core::ops::Deref; - use thiserror::Error; -use futures::stream::{Stream, StreamExt}; +use simple_request::{hyper, Request, Client}; use scale::{Encode, Decode, Compact}; -mod scale_value; -pub(crate) use scale_value::{Value, scale_value}; +use serde::{Serialize, Deserialize, de::DeserializeOwned}; pub use sp_core::{ Pair as PairTrait, sr25519::{Public, Pair}, }; -use subxt::{ - error::Error as SubxtError, - config::{ - Header as HeaderTrait, - substrate::{BlakeTwo256, SubstrateHeader}, - extrinsic_params::BaseExtrinsicParams, - }, - rpc::types::{ChainBlock, ChainBlockExtrinsic}, - Config as SubxtConfig, OnlineClient, -}; - pub use serai_runtime::primitives; pub use primitives::{SeraiAddress, Signature, Amount}; pub use serai_runtime as runtime; -use serai_runtime::{ - system::Config, support::traits::PalletInfo as PalletInfoTrait, PalletInfo, Runtime, -}; +use serai_runtime::{Header, Block as SeraiBlock}; pub mod coins; pub use coins::SeraiCoins; @@ -41,42 +25,11 @@ pub use in_instructions::SeraiInInstructions; pub mod validator_sets; pub use validator_sets::SeraiValidatorSets; -#[derive(Clone, Copy, PartialEq, Eq, Default, Debug, Encode, Decode)] -pub struct Tip { - #[codec(compact)] - pub tip: u64, -} - -pub type Header = SubstrateHeader; - -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct SeraiConfig; -impl SubxtConfig for SeraiConfig { - type Hash = ::Hash; - type Hasher = BlakeTwo256; - - type Index = serai_runtime::Nonce; - type AccountId = ::AccountId; - // TODO: Bech32m - type Address = SeraiAddress; - - type Header = Header; - type Signature = Signature; +pub type Transaction = serai_runtime::UncheckedExtrinsic; - type ExtrinsicParams = BaseExtrinsicParams; -} - -#[derive(Debug)] -pub struct Block(ChainBlock); +#[derive(Clone, Debug)] +pub struct Block(SeraiBlock); impl Block { - fn new(block: ChainBlock) -> Result { - for extrinsic in &block.extrinsics { - if extrinsic.0.len() < 3 { - Err(SeraiError::InvalidNode)?; - } - } - Ok(Block(block)) - } pub fn hash(&self) -> [u8; 32] { self.0.header.hash().into() } @@ -87,74 +40,134 @@ impl Block { /// Returns the time of this block, set by its producer, in milliseconds since the epoch. pub fn time(&self) -> Result { for extrinsic in &self.0.extrinsics { - // Inherent/unsigned - let inherent = (extrinsic.0[0] >> 7) == 0; - - // To timestamp pallet - use serai_runtime::Timestamp; - let timestamp = - extrinsic.0[1] == u8::try_from(PalletInfo::index::().unwrap()).unwrap(); - - // set call - let set = extrinsic.0[2] == 0; - - if inherent && timestamp && set { - if extrinsic.0.len() < 4 { - Err(SeraiError::InvalidNode)?; - } - return Ok( - Compact::::decode(&mut &extrinsic.0[3 ..]).map_err(|_| SeraiError::InvalidNode)?.0, - ); + if let serai_runtime::RuntimeCall::Timestamp(serai_runtime::timestamp::Call::set { now }) = + &extrinsic.function + { + return Ok(*now); } } - Err(SeraiError::InvalidNode) + Err(SeraiError::InvalidNode("no time was present in block".to_string())) } pub fn header(&self) -> &Header { &self.0.header } - pub fn transactions(&self) -> &[ChainBlockExtrinsic] { + pub fn transactions(&self) -> &[Transaction] { &self.0.extrinsics } } -impl Clone for Block { - fn clone(&self) -> Block { - Block(ChainBlock:: { - header: self.0.header.clone(), - extrinsics: self.0.extrinsics.clone(), - }) - } -} - #[derive(Error, Debug)] pub enum SeraiError { - #[error("failed to communicate with serai: {0}")] - RpcError(SubxtError), - #[error("serai-client library was intended for a different runtime version")] - InvalidRuntime, - #[error("node is faulty")] - InvalidNode, + #[error("failed to communicate with serai")] + ConnectionError, + #[error("node is faulty: {0}")] + InvalidNode(String), + #[error("error in response: {0}")] + ErrorInResponse(String), + #[error("serai-client library was intended for a different runtime version: {0}")] + InvalidRuntime(String), } #[derive(Clone)] -pub struct Serai(OnlineClient); +pub struct Serai { + url: String, + client: Client, + genesis: [u8; 32], +} #[derive(Clone, Copy)] pub struct TemporalSerai<'a>(pub(crate) &'a Serai, pub(crate) [u8; 32]); impl Serai { - pub async fn new(url: &str) -> Result { - Ok(Serai(OnlineClient::::from_url(url).await.map_err(SeraiError::RpcError)?)) + pub async fn call( + &self, + method: &str, + params: Req, + ) -> Result { + let request = Request::from( + hyper::Request::post(&self.url) + .header("Content-Type", "application/json") + .body( + serde_json::to_vec( + &serde_json::json!({ "jsonrpc": "2.0", "id": 1, "method": method, "params": params }), + ) + .unwrap() + .into(), + ) + .unwrap(), + ); + + #[derive(Deserialize)] + pub struct Error { + message: String, + } + + #[derive(Deserialize)] + #[serde(untagged)] + enum RpcResponse { + Ok { result: T }, + Err { error: Error }, + } + + let mut res = self + .client + .request(request) + .await + .map_err(|_| SeraiError::ConnectionError)? + .body() + .await + .map_err(|_| SeraiError::ConnectionError)?; + + let res: RpcResponse = serde_json::from_reader(&mut res).map_err(|e| { + SeraiError::InvalidRuntime(format!( + "response was a different type than expected: {:?}", + e.classify() + )) + })?; + match res { + RpcResponse::Ok { result } => Ok(result), + RpcResponse::Err { error } => Err(SeraiError::ErrorInResponse(error.message)), + } + } + + fn hex_decode(str: String) -> Result, SeraiError> { + (if let Some(stripped) = str.strip_prefix("0x") { + hex::decode(stripped) + } else { + hex::decode(str) + }) + .map_err(|_| SeraiError::InvalidNode("expected hex from node wasn't hex".to_string())) + } + + pub async fn block_hash(&self, number: u64) -> Result, SeraiError> { + let hash: Option = self.call("chain_getBlockHash", [number]).await?; + let Some(hash) = hash else { return Ok(None) }; + Self::hex_decode(hash)? + .try_into() + .map_err(|_| SeraiError::InvalidNode("didn't respond to getBlockHash with hash".to_string())) + .map(Some) + } + + pub async fn new(url: String) -> Result { + let client = Client::with_connection_pool(); + let mut res = Serai { url, client, genesis: [0xfe; 32] }; + res.genesis = res.block_hash(0).await?.ok_or_else(|| { + SeraiError::InvalidNode("node didn't have the first block's hash".to_string()) + })?; + Ok(res) } fn unsigned(call: &serai_runtime::RuntimeCall) -> Vec { // TODO: Should Serai purge the old transaction code AND set this to 0/1? const EXTRINSIC_FORMAT_VERSION: u8 = 4; - let mut bytes = vec![EXTRINSIC_FORMAT_VERSION]; - bytes.extend(call.encode()); - bytes + let mut tx = vec![EXTRINSIC_FORMAT_VERSION]; + tx.extend(call.encode()); + + let mut length_prefixed = Compact(u32::try_from(tx.len()).unwrap()).encode(); + length_prefixed.extend(tx); + length_prefixed } pub fn sign( @@ -162,15 +175,15 @@ impl Serai { signer: &Pair, call: &serai_runtime::RuntimeCall, nonce: u32, - tip: Tip, + tip: u64, ) -> Vec { const SPEC_VERSION: u32 = 1; const TX_VERSION: u32 = 1; const EXTRINSIC_FORMAT_VERSION: u8 = 4; let era = sp_runtime::generic::Era::Immortal; - let extra = (era, Compact(nonce), tip); - let genesis = self.0.genesis_hash(); + let extra = (era, Compact(nonce), Compact(tip)); + let genesis = self.genesis; let mortality_checkpoint = genesis; let mut signature_payload = (call, extra, SPEC_VERSION, TX_VERSION, genesis, mortality_checkpoint).encode(); @@ -180,115 +193,104 @@ impl Serai { let signature = signer.sign(&signature_payload); let signed = 1 << 7; - (signed + EXTRINSIC_FORMAT_VERSION, signer.public(), signature, extra, call).encode() - } + let tx = (signed + EXTRINSIC_FORMAT_VERSION, signer.public(), signature, extra, call).encode(); - pub async fn publish(&self, tx: &[u8]) -> Result<(), SeraiError> { let mut length_prefixed = Compact(u32::try_from(tx.len()).unwrap()).encode(); length_prefixed.extend(tx); - self - .0 - .rpc() - .deref() - .request::( - "author_submitExtrinsic", - subxt::rpc::rpc_params![hex::encode(length_prefixed)], - ) - .await - // Drop the hash, which is the hash of the raw extrinsic, as extrinsics are allowed to share - // hashes and this hash is accordingly useless/unsafe - // If we are to return something, it should be block included in and position within block - .map(|_| ()) - .map_err(SeraiError::RpcError) + length_prefixed } - pub async fn latest_block_hash(&self) -> Result<[u8; 32], SeraiError> { - Ok(self.0.rpc().finalized_head().await.map_err(SeraiError::RpcError)?.into()) + // TODO: Move this to take in Transaction + pub async fn publish(&self, tx: &[u8]) -> Result<(), SeraiError> { + // Drop the returned hash, which is the hash of the raw extrinsic, as extrinsics are allowed + // to share hashes and this hash is accordingly useless/unsafe + // If we are to return something, it should be block included in and position within block + let _: String = self.call("author_submitExtrinsic", [hex::encode(tx)]).await?; + Ok(()) } - pub async fn latest_block(&self) -> Result { - Block::new( - self - .0 - .rpc() - .block(Some(self.0.rpc().finalized_head().await.map_err(SeraiError::RpcError)?)) - .await - .map_err(SeraiError::RpcError)? - .ok_or(SeraiError::InvalidNode)? - .block, - ) + pub async fn latest_finalized_block_hash(&self) -> Result<[u8; 32], SeraiError> { + let hash: String = self.call("chain_getFinalizedHead", ()).await?; + Self::hex_decode(hash)?.try_into().map_err(|_| { + SeraiError::InvalidNode("didn't respond to getFinalizedHead with hash".to_string()) + }) + } + + pub async fn header(&self, hash: [u8; 32]) -> Result, SeraiError> { + self.call("chain_getHeader", [hex::encode(hash)]).await + } + + pub async fn block(&self, hash: [u8; 32]) -> Result, SeraiError> { + // TODO: Remove this wrapping from Serai? + #[derive(Deserialize)] + struct WrappedBlock { + block: SeraiBlock, + } + let block: Option = self.call("chain_getBlock", [hex::encode(hash)]).await?; + let Some(block) = block else { return Ok(None) }; + Ok(Some(Block(block.block))) + } + + pub async fn latest_finalized_block(&self) -> Result { + let latest = self.latest_finalized_block_hash().await?; + let Some(block) = self.block(latest).await? else { + Err(SeraiError::InvalidNode("node didn't have a latest block".to_string()))? + }; + Ok(block) } // There is no provided method for this // TODO: Add one to Serai - pub async fn is_finalized(&self, header: &Header) -> Result, SeraiError> { + pub async fn is_finalized(&self, header: &Header) -> Result { // Get the latest finalized block - let finalized = self.latest_block_hash().await?.into(); + let finalized = self.latest_finalized_block_hash().await?; // If the latest finalized block is this block, return true - if finalized == header.hash() { - return Ok(Some(true)); + if finalized == header.hash().as_ref() { + return Ok(true); } - let Some(finalized) = - self.0.rpc().header(Some(finalized)).await.map_err(SeraiError::RpcError)? - else { - return Ok(None); + let Some(finalized) = self.header(finalized).await? else { + Err(SeraiError::InvalidNode("couldn't get finalized header".to_string()))? }; // If the finalized block has a lower number, this block can't be finalized - if finalized.number() < header.number() { - return Ok(Some(false)); + if finalized.number < header.number { + return Ok(false); } // This block, if finalized, comes before the finalized block // If we request the hash of this block's number, Substrate will return the hash on the main // chain // If that hash is this hash, this block is finalized - let Some(hash) = - self.0.rpc().block_hash(Some(header.number().into())).await.map_err(SeraiError::RpcError)? - else { - // This is an error since there is a block at this index - Err(SeraiError::InvalidNode)? + let Some(hash) = self.block_hash(header.number).await? else { + // This is an error since there is a finalized block at this index + Err(SeraiError::InvalidNode( + "couldn't get block hash for a block number below the finalized block".to_string(), + ))? }; - Ok(Some(header.hash() == hash)) + Ok(header.hash().as_ref() == hash) } - pub async fn block(&self, hash: [u8; 32]) -> Result, SeraiError> { - let Some(res) = self.0.rpc().block(Some(hash.into())).await.map_err(SeraiError::RpcError)? - else { - return Ok(None); - }; - - // Only return finalized blocks - if self.is_finalized(&res.block.header).await? != Some(true) { + pub async fn finalized_block_by_number(&self, number: u64) -> Result, SeraiError> { + let hash = self.block_hash(number).await?; + let Some(hash) = hash else { return Ok(None) }; + let Some(block) = self.block(hash).await? else { return Ok(None) }; + if !self.is_finalized(&block.0.header).await? { return Ok(None); } - - Ok(Some(Block::new(res.block)?)) - } - - // Ideally, this would be block_hash, not block_by_number - // Unfortunately, in order to only operate over only finalized data, we have to check the - // returned hash is for a finalized block. We can only do that by calling the extensive - // is_finalized method, which at least requires the header - // In practice, the block is likely more useful than the header - pub async fn block_by_number(&self, number: u64) -> Result, SeraiError> { - let Some(hash) = - self.0.rpc().block_hash(Some(number.into())).await.map_err(SeraiError::RpcError)? - else { - return Ok(None); - }; - self.block(hash.into()).await + Ok(Some(block)) } + /* /// A stream which yields whenever new block(s) have been finalized. pub async fn newly_finalized_block( &self, ) -> Result>, SeraiError> { - Ok(self.0.rpc().subscribe_finalized_block_headers().await.map_err(SeraiError::RpcError)?.map( + Ok(self.0.rpc().subscribe_finalized_block_headers().await + .map_err(|_| SeraiError::ConnectionError)?.map( |next| { - next.map_err(SeraiError::RpcError)?; + next.map_err(|_| SeraiError::ConnectionError)?; Ok(()) }, )) @@ -300,12 +302,16 @@ impl Serai { .rpc() .system_account_next_index(&sp_core::sr25519::Public(address.0).to_string()) .await - .map_err(SeraiError::RpcError) + .map_err(|_| SeraiError::ConnectionError) } - - /// Create a TemporalSerai using whatever is currently the latest block. - pub async fn with_current_latest_block(&self) -> Result { - let latest = self.latest_block_hash().await?; + */ + + /// Create a TemporalSerai bound to whatever is currently the latest finalized block. + /// + /// The binding occurs at time of call. This does not track the latest finalized block and update + /// itself. + pub async fn as_of_latest_finalized_block(&self) -> Result { + let latest = self.latest_finalized_block_hash().await?; Ok(TemporalSerai(self, latest)) } @@ -320,43 +326,41 @@ impl<'a> TemporalSerai<'a> { self.0 } - async fn events( + async fn events( &self, - filter: impl Fn(&E) -> bool, + filter_map: impl Fn(serai_runtime::RuntimeEvent) -> Option, ) -> Result, SeraiError> { let mut res = vec![]; - for event in self.0 .0.events().at(self.1.into()).await.map_err(SeraiError::RpcError)?.iter() { - let event = event.map_err(|_| SeraiError::InvalidRuntime)?; - if PalletInfo::index::

().unwrap() == usize::from(event.pallet_index()) { - let mut with_variant: &[u8] = - &[[event.variant_index()].as_ref(), event.field_bytes()].concat(); - let event = E::decode(&mut with_variant).map_err(|_| SeraiError::InvalidRuntime)?; - if filter(&event) { - res.push(event); - } + let all_events: Option< + Vec>, + > = self.storage("System", "Events", ()).await?; + #[allow(clippy::unwrap_or_default)] + for event in all_events.unwrap_or(vec![]) { + if let Some(event) = filter_map(event.event) { + res.push(event); } } Ok(res) } - async fn storage( + async fn storage( &self, pallet: &'static str, name: &'static str, - keys: Option>, + key: K, ) -> Result, SeraiError> { - let storage = self.0 .0.storage(); - #[allow(clippy::unwrap_or_default)] - let address = subxt::dynamic::storage(pallet, name, keys.unwrap_or(vec![])); - debug_assert!(storage.validate(&address).is_ok(), "invalid storage address"); - - storage - .at(self.1.into()) - .fetch(&address) - .await - .map_err(SeraiError::RpcError)? - .map(|res| R::decode(&mut res.encoded()).map_err(|_| SeraiError::InvalidRuntime)) - .transpose() + // TODO: Make this const? + let mut full_key = sp_core::hashing::twox_128(pallet.as_bytes()).to_vec(); + full_key.extend(sp_core::hashing::twox_128(name.as_bytes())); + full_key.extend(key.encode()); + + let res: Option = + self.0.call("state_getStorage", [hex::encode(full_key), hex::encode(self.1)]).await?; + let Some(res) = res else { return Ok(None) }; + let res = Serai::hex_decode(res)?; + Ok(Some(R::decode(&mut res.as_slice()).map_err(|_| { + SeraiError::InvalidRuntime("different type present at storage location".to_string()) + })?)) } pub fn coins(self) -> SeraiCoins<'a> { diff --git a/substrate/client/src/serai/scale_value.rs b/substrate/client/src/serai/scale_value.rs deleted file mode 100644 index 9e310a312..000000000 --- a/substrate/client/src/serai/scale_value.rs +++ /dev/null @@ -1,13 +0,0 @@ -use ::scale::Encode; -use scale_info::{MetaType, TypeInfo, Registry, PortableRegistry}; - -use subxt::ext::scale_value; -pub(crate) use scale_value::Value; -use scale_value::scale; - -pub(crate) fn scale_value(value: V) -> Value { - let mut registry = Registry::new(); - let id = registry.register_type(&MetaType::new::()).id; - let registry = PortableRegistry::from(registry); - scale::decode_as_type(&mut value.encode().as_ref(), id, ®istry).unwrap().remove_context() -} diff --git a/substrate/client/src/serai/validator_sets.rs b/substrate/client/src/serai/validator_sets.rs index b33a5f1aa..ecd8b5eec 100644 --- a/substrate/client/src/serai/validator_sets.rs +++ b/substrate/client/src/serai/validator_sets.rs @@ -1,10 +1,12 @@ +use scale::Encode; + use sp_core::sr25519::{Public, Signature}; -use serai_runtime::{primitives::Amount, validator_sets, ValidatorSets, Runtime}; +use serai_runtime::{primitives::Amount, validator_sets, Runtime}; pub use validator_sets::primitives; use primitives::{Session, ValidatorSet, KeyPair}; -use crate::{primitives::NetworkId, Serai, TemporalSerai, SeraiError, scale_value}; +use crate::{primitives::NetworkId, Serai, TemporalSerai, SeraiError}; const PALLET: &str = "ValidatorSets"; @@ -20,47 +22,65 @@ impl<'a> SeraiValidatorSets<'a> { pub async fn new_set_events(&self) -> Result, SeraiError> { self .0 - .events::(|event| matches!(event, ValidatorSetsEvent::NewSet { .. })) + .events(|event| { + if let serai_runtime::RuntimeEvent::ValidatorSets(event) = event { + Some(event).filter(|event| matches!(event, ValidatorSetsEvent::NewSet { .. })) + } else { + None + } + }) .await } pub async fn key_gen_events(&self) -> Result, SeraiError> { self .0 - .events::(|event| matches!(event, ValidatorSetsEvent::KeyGen { .. })) + .events(|event| { + if let serai_runtime::RuntimeEvent::ValidatorSets(event) = event { + Some(event).filter(|event| matches!(event, ValidatorSetsEvent::KeyGen { .. })) + } else { + None + } + }) .await } pub async fn set_retired_events(&self) -> Result, SeraiError> { self .0 - .events::(|event| matches!(event, ValidatorSetsEvent::SetRetired { .. })) + .events(|event| { + if let serai_runtime::RuntimeEvent::ValidatorSets(event) = event { + Some(event).filter(|event| matches!(event, ValidatorSetsEvent::SetRetired { .. })) + } else { + None + } + }) .await } pub async fn session(&self, network: NetworkId) -> Result, SeraiError> { - self.0.storage(PALLET, "CurrentSession", Some(vec![scale_value(network)])).await + self.0.storage(PALLET, "CurrentSession", network).await } pub async fn participants( &self, network: NetworkId, ) -> Result>, SeraiError> { - self.0.storage(PALLET, "Participants", Some(vec![scale_value(network)])).await + self.0.storage(PALLET, "Participants", network).await } pub async fn allocation_per_key_share( &self, network: NetworkId, ) -> Result, SeraiError> { - self.0.storage(PALLET, "AllocationPerKeyShare", Some(vec![scale_value(network)])).await + self.0.storage(PALLET, "AllocationPerKeyShare", network).await } pub async fn total_allocated_stake( &self, network: NetworkId, ) -> Result, SeraiError> { - self.0.storage(PALLET, "TotalAllocatedStake", Some(vec![scale_value(network)])).await + self.0.storage(PALLET, "TotalAllocatedStake", network).await } pub async fn allocation( @@ -68,16 +88,23 @@ impl<'a> SeraiValidatorSets<'a> { network: NetworkId, key: Public, ) -> Result, SeraiError> { - self.0.storage(PALLET, "Allocations", Some(vec![scale_value(network), scale_value(key)])).await + self + .0 + .storage( + PALLET, + "Allocations", + (sp_core::hashing::blake2_128(&(network, key).encode()), (network, key)), + ) + .await } pub async fn musig_key(&self, set: ValidatorSet) -> Result, SeraiError> { - self.0.storage(PALLET, "MuSigKeys", Some(vec![scale_value(set)])).await + self.0.storage(PALLET, "MuSigKeys", (sp_core::hashing::twox_64(&set.encode()), set)).await } // TODO: Store these separately since we almost never need both at once? pub async fn keys(&self, set: ValidatorSet) -> Result, SeraiError> { - self.0.storage(PALLET, "Keys", Some(vec![scale_value(set)])).await + self.0.storage(PALLET, "Keys", (sp_core::hashing::twox_64(&set.encode()), set)).await } pub fn set_keys(network: NetworkId, key_pair: KeyPair, signature: Signature) -> Vec { diff --git a/substrate/client/tests/batch.rs b/substrate/client/tests/batch.rs index 8ff61a071..08a5249ad 100644 --- a/substrate/client/tests/batch.rs +++ b/substrate/client/tests/batch.rs @@ -50,7 +50,8 @@ serai_test!( let serai = serai.as_of(block); { let serai = serai.in_instructions(); - assert_eq!(serai.latest_block_for_network(network).await.unwrap(), Some(block_hash)); + let latest_finalized = serai.latest_block_for_network(network).await.unwrap(); + assert_eq!(latest_finalized, Some(block_hash)); let batches = serai.batch_events().await.unwrap(); assert_eq!( batches, diff --git a/substrate/client/tests/burn.rs b/substrate/client/tests/burn.rs index 4638f9426..bf46ffd2e 100644 --- a/substrate/client/tests/burn.rs +++ b/substrate/client/tests/burn.rs @@ -94,7 +94,7 @@ serai_test!( &pair, &SeraiCoins::burn_with_instruction(instruction.clone()), 0, - Default::default(), + 0, ) ) .await; diff --git a/substrate/client/tests/common/dex.rs b/substrate/client/tests/common/dex.rs index 4597238d1..79970cd73 100644 --- a/substrate/client/tests/common/dex.rs +++ b/substrate/client/tests/common/dex.rs @@ -20,7 +20,7 @@ pub async fn add_liquidity( &pair, &SeraiDex::add_liquidity(coin, coin_amount, sri_amount, Amount(1), Amount(1), address.into()), nonce, - Default::default(), + 0, ); publish_tx(serai, &tx).await diff --git a/substrate/client/tests/common/in_instructions.rs b/substrate/client/tests/common/in_instructions.rs index e7f27cd8c..0435b6194 100644 --- a/substrate/client/tests/common/in_instructions.rs +++ b/substrate/client/tests/common/in_instructions.rs @@ -26,7 +26,7 @@ pub async fn provide_batch(serai: &Serai, batch: Batch) -> [u8; 32] { let set = ValidatorSet { session: Session(0), network: batch.network }; let pair = insecure_pair_from_name(&format!("ValidatorSet {:?}", set)); let keys = if let Some(keys) = - serai.with_current_latest_block().await.unwrap().validator_sets().keys(set).await.unwrap() + serai.as_of_latest_finalized_block().await.unwrap().validator_sets().keys(set).await.unwrap() { keys } else { diff --git a/substrate/client/tests/common/mod.rs b/substrate/client/tests/common/mod.rs index 0624ca0c0..73fe52cbf 100644 --- a/substrate/client/tests/common/mod.rs +++ b/substrate/client/tests/common/mod.rs @@ -42,18 +42,18 @@ macro_rules! serai_test { test.run_async(|ops| async move { // Sleep until the Substrate RPC starts let serai_rpc = ops.handle(handle).host_port(9944).unwrap(); - let serai_rpc = format!("ws://{}:{}", serai_rpc.0, serai_rpc.1); + let serai_rpc = format!("http://{}:{}", serai_rpc.0, serai_rpc.1); // Bound execution to 60 seconds for _ in 0 .. 60 { tokio::time::sleep(core::time::Duration::from_secs(1)).await; - let Ok(client) = Serai::new(&serai_rpc).await else { continue }; - if client.latest_block_hash().await.is_err() { + let Ok(client) = Serai::new(serai_rpc.clone()).await else { continue }; + if client.latest_finalized_block_hash().await.is_err() { continue; } break; } #[allow(clippy::redundant_closure_call)] - $test(Serai::new(&serai_rpc).await.unwrap()).await; + $test(Serai::new(serai_rpc).await.unwrap()).await; }).await; } )* diff --git a/substrate/client/tests/common/tx.rs b/substrate/client/tests/common/tx.rs index a8e94de41..4d7b103a3 100644 --- a/substrate/client/tests/common/tx.rs +++ b/substrate/client/tests/common/tx.rs @@ -2,12 +2,18 @@ use core::time::Duration; use tokio::time::sleep; +use scale::Encode; + use serai_client::Serai; #[allow(dead_code)] pub async fn publish_tx(serai: &Serai, tx: &[u8]) -> [u8; 32] { - let mut latest = - serai.block(serai.latest_block_hash().await.unwrap()).await.unwrap().unwrap().number(); + let mut latest = serai + .block(serai.latest_finalized_block_hash().await.unwrap()) + .await + .unwrap() + .unwrap() + .number(); serai.publish(tx).await.unwrap(); @@ -20,7 +26,7 @@ pub async fn publish_tx(serai: &Serai, tx: &[u8]) -> [u8; 32] { let block = { let mut block; while { - block = serai.block_by_number(latest).await.unwrap(); + block = serai.finalized_block_by_number(latest).await.unwrap(); block.is_none() } { sleep(Duration::from_secs(1)).await; @@ -34,7 +40,7 @@ pub async fn publish_tx(serai: &Serai, tx: &[u8]) -> [u8; 32] { }; for transaction in block.transactions() { - if transaction.0 == tx { + if transaction.encode() == tx { return block.hash(); } } diff --git a/substrate/client/tests/common/validator_sets.rs b/substrate/client/tests/common/validator_sets.rs index 4e519d87a..057742dbe 100644 --- a/substrate/client/tests/common/validator_sets.rs +++ b/substrate/client/tests/common/validator_sets.rs @@ -28,7 +28,7 @@ pub async fn set_keys(serai: &Serai, set: ValidatorSet, key_pair: KeyPair) -> [u let public_key = ::read_G::<&[u8]>(&mut public.0.as_ref()).unwrap(); assert_eq!( serai - .with_current_latest_block() + .as_of_latest_finalized_block() .await .unwrap() .validator_sets() @@ -48,7 +48,7 @@ pub async fn set_keys(serai: &Serai, set: ValidatorSet, key_pair: KeyPair) -> [u musig::(&musig_context(set), &Zeroizing::new(secret_key), &[public_key]).unwrap(); assert_eq!( serai - .with_current_latest_block() + .as_of_latest_finalized_block() .await .unwrap() .validator_sets() @@ -69,7 +69,7 @@ pub async fn set_keys(serai: &Serai, set: ValidatorSet, key_pair: KeyPair) -> [u &set_keys_message(&set, &key_pair), ); - // Vote in a key pair + // Set the key pair let block = publish_tx( serai, &SeraiValidatorSets::set_keys(set.network, key_pair.clone(), Signature(sig.to_bytes())), diff --git a/substrate/client/tests/dex.rs b/substrate/client/tests/dex.rs index fc576db0c..ddf742ea1 100644 --- a/substrate/client/tests/dex.rs +++ b/substrate/client/tests/dex.rs @@ -29,8 +29,8 @@ use common::{ // TODO: Check Transfer events serai_test!( create_pool: (|serai: Serai| async move { - let block = serai.block_by_number(0).await.unwrap().unwrap().hash(); - let events = serai.as_of(block).dex().all_events().await.unwrap(); + let block = serai.finalized_block_by_number(0).await.unwrap().unwrap().hash(); + let events = serai.as_of(block).dex().events().await.unwrap(); assert_eq!( events, @@ -85,7 +85,7 @@ serai_test!( pair.clone() ).await; // get only the add liq events - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::LiquidityAdded { .. })); assert_eq!( @@ -133,7 +133,7 @@ serai_test!( .await; // get only the swap events - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::SwapExecuted { .. })); let mut path = BoundedVec::try_from(vec![coin, Coin::Serai]).unwrap(); @@ -153,7 +153,7 @@ serai_test!( block = common_swap(&serai, Coin::Serai, coin, amount_in, Amount(1), 2, pair.clone()).await; // get only the swap events - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::SwapExecuted { .. })); path = BoundedVec::try_from(vec![Coin::Serai, coin]).unwrap(); @@ -213,7 +213,7 @@ serai_test!( let block = common_swap(&serai, coin1, coin2, amount_in, Amount(1), 2, pair.clone()).await; // get only the swap events - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::SwapExecuted { .. })); let path = BoundedVec::try_from(vec![coin1, Coin::Serai, coin2]).unwrap(); @@ -270,7 +270,7 @@ serai_test!( }; let block = provide_batch(&serai, batch).await; - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::LiquidityAdded { .. })); assert_eq!( events, @@ -356,7 +356,7 @@ serai_test!( let block = provide_batch(&serai, batch).await; coin1_batch_id += 1; - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::SwapExecuted { .. })); let path = BoundedVec::try_from(vec![coin1, Coin::Serai, coin2]).unwrap(); @@ -395,7 +395,7 @@ serai_test!( }; let block = provide_batch(&serai, batch).await; - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::SwapExecuted { .. })); let path = BoundedVec::try_from(vec![coin2, Coin::Serai, coin1]).unwrap(); @@ -433,7 +433,7 @@ serai_test!( }; let block = provide_batch(&serai, batch).await; - let mut events = serai.as_of(block).dex().all_events().await.unwrap(); + let mut events = serai.as_of(block).dex().events().await.unwrap(); events.retain(|e| matches!(e, DexEvent::SwapExecuted { .. })); let path = BoundedVec::try_from(vec![coin1, Coin::Serai]).unwrap(); diff --git a/substrate/client/tests/time.rs b/substrate/client/tests/time.rs index 85e3e941d..0a8764dd2 100644 --- a/substrate/client/tests/time.rs +++ b/substrate/client/tests/time.rs @@ -8,11 +8,11 @@ mod common; serai_test!( time: (|serai: Serai| async move { - let mut number = serai.latest_block().await.unwrap().number(); + let mut number = serai.latest_finalized_block().await.unwrap().number(); let mut done = 0; while done < 3 { // Wait for the next block - let block = serai.latest_block().await.unwrap(); + let block = serai.latest_finalized_block().await.unwrap(); if block.number() == number { sleep(Duration::from_secs(1)).await; continue; diff --git a/substrate/client/tests/validator_sets.rs b/substrate/client/tests/validator_sets.rs index ca165b9a1..7f66cf11c 100644 --- a/substrate/client/tests/validator_sets.rs +++ b/substrate/client/tests/validator_sets.rs @@ -33,7 +33,7 @@ serai_test!( // Make sure the genesis is as expected assert_eq!( serai - .as_of(serai.block_by_number(0).await.unwrap().unwrap().hash()) + .as_of(serai.finalized_block_by_number(0).await.unwrap().unwrap().hash()) .validator_sets() .new_set_events() .await @@ -48,7 +48,7 @@ serai_test!( ); { - let vs_serai = serai.with_current_latest_block().await.unwrap().validator_sets(); + let vs_serai = serai.as_of_latest_finalized_block().await.unwrap().validator_sets(); let participants = vs_serai.participants(set.network).await .unwrap() .unwrap() diff --git a/substrate/in-instructions/pallet/src/lib.rs b/substrate/in-instructions/pallet/src/lib.rs index 0e61f2be9..1bf010a8e 100644 --- a/substrate/in-instructions/pallet/src/lib.rs +++ b/substrate/in-instructions/pallet/src/lib.rs @@ -58,23 +58,23 @@ pub mod pallet { // The ID of the last executed Batch for a network. #[pallet::storage] #[pallet::getter(fn batches)] - pub(crate) type LastBatch = StorageMap<_, Blake2_256, NetworkId, u32, OptionQuery>; + pub(crate) type LastBatch = StorageMap<_, Identity, NetworkId, u32, OptionQuery>; // The last Serai block in which this validator set included a batch #[pallet::storage] #[pallet::getter(fn last_batch_block)] pub(crate) type LastBatchBlock = - StorageMap<_, Blake2_256, NetworkId, BlockNumberFor, OptionQuery>; + StorageMap<_, Identity, NetworkId, BlockNumberFor, OptionQuery>; // Halted networks. #[pallet::storage] - pub(crate) type Halted = StorageMap<_, Blake2_256, NetworkId, (), OptionQuery>; + pub(crate) type Halted = StorageMap<_, Identity, NetworkId, (), OptionQuery>; // The latest block a network has acknowledged as finalized #[pallet::storage] #[pallet::getter(fn latest_network_block)] pub(crate) type LatestNetworkBlock = - StorageMap<_, Blake2_256, NetworkId, BlockHash, OptionQuery>; + StorageMap<_, Identity, NetworkId, BlockHash, OptionQuery>; impl Pallet { // Use a dedicated transaction layer when executing this InInstruction diff --git a/tests/coordinator/src/lib.rs b/tests/coordinator/src/lib.rs index d26000928..a07d7ea40 100644 --- a/tests/coordinator/src/lib.rs +++ b/tests/coordinator/src/lib.rs @@ -213,12 +213,12 @@ impl Processor { // Sleep until the Substrate RPC starts let serai_rpc = ops.handle(&handles.0).host_port(9944).unwrap(); - let serai_rpc = format!("ws://{}:{}", serai_rpc.0, serai_rpc.1); + let serai_rpc = format!("http://{}:{}", serai_rpc.0, serai_rpc.1); // Bound execution to 60 seconds for _ in 0 .. 60 { tokio::time::sleep(Duration::from_secs(1)).await; - let Ok(client) = Serai::new(&serai_rpc).await else { continue }; - if client.latest_block_hash().await.is_err() { + let Ok(client) = Serai::new(serai_rpc.clone()).await else { continue }; + if client.latest_finalized_block_hash().await.is_err() { continue; } break; @@ -371,7 +371,7 @@ impl Processor { } pub async fn serai(&self) -> Serai { - Serai::new(&self.serai_rpc).await.unwrap() + Serai::new(self.serai_rpc.clone()).await.unwrap() } /// Send a message to the coordinator as a processor. diff --git a/tests/coordinator/src/tests/batch.rs b/tests/coordinator/src/tests/batch.rs index a3024c590..501cdc0a4 100644 --- a/tests/coordinator/src/tests/batch.rs +++ b/tests/coordinator/src/tests/batch.rs @@ -176,7 +176,7 @@ pub async fn batch( let batch = SignedBatch { batch, signature }; let serai = processors[0].serai().await; - let mut last_serai_block = serai.latest_block().await.unwrap().number(); + let mut last_serai_block = serai.latest_finalized_block().await.unwrap().number(); for (i, processor) in processors.iter_mut().enumerate() { if i == excluded_signer { @@ -194,9 +194,9 @@ pub async fn batch( tokio::time::sleep(Duration::from_secs(6)).await; } - while last_serai_block <= serai.latest_block().await.unwrap().number() { + while last_serai_block <= serai.latest_finalized_block().await.unwrap().number() { let batch_events = serai - .as_of(serai.block_by_number(last_serai_block).await.unwrap().unwrap().hash()) + .as_of(serai.finalized_block_by_number(last_serai_block).await.unwrap().unwrap().hash()) .in_instructions() .batch_events() .await @@ -220,7 +220,7 @@ pub async fn batch( } // Verify the coordinator sends SubstrateBlock to all processors - let last_block = serai.block_by_number(last_serai_block).await.unwrap().unwrap(); + let last_block = serai.finalized_block_by_number(last_serai_block).await.unwrap().unwrap(); for processor in processors { assert_eq!( processor.recv_message().await, diff --git a/tests/coordinator/src/tests/key_gen.rs b/tests/coordinator/src/tests/key_gen.rs index 59b1fbf51..7e90ba1ff 100644 --- a/tests/coordinator/src/tests/key_gen.rs +++ b/tests/coordinator/src/tests/key_gen.rs @@ -109,7 +109,7 @@ pub async fn key_gen( let network_key = (C::generator() * *network_priv_key).to_bytes().as_ref().to_vec(); let serai = processors[0].serai().await; - let mut last_serai_block = serai.latest_block().await.unwrap().number(); + let mut last_serai_block = serai.latest_finalized_block().await.unwrap().number(); wait_for_tributary().await; for (i, processor) in processors.iter_mut().enumerate() { @@ -151,9 +151,9 @@ pub async fn key_gen( tokio::time::sleep(Duration::from_secs(6)).await; } - while last_serai_block <= serai.latest_block().await.unwrap().number() { + while last_serai_block <= serai.latest_finalized_block().await.unwrap().number() { if !serai - .as_of(serai.block_by_number(last_serai_block).await.unwrap().unwrap().hash()) + .as_of(serai.finalized_block_by_number(last_serai_block).await.unwrap().unwrap().hash()) .validator_sets() .key_gen_events() .await @@ -199,7 +199,7 @@ pub async fn key_gen( } assert_eq!( serai - .as_of(serai.block_by_number(last_serai_block).await.unwrap().unwrap().hash()) + .as_of(serai.finalized_block_by_number(last_serai_block).await.unwrap().unwrap().hash()) .validator_sets() .keys(set) .await diff --git a/tests/coordinator/src/tests/sign.rs b/tests/coordinator/src/tests/sign.rs index ce4b09189..fb1eecb72 100644 --- a/tests/coordinator/src/tests/sign.rs +++ b/tests/coordinator/src/tests/sign.rs @@ -241,7 +241,7 @@ async fn sign_test() { { let block_included_in_hash = - serai.block_by_number(block_included_in).await.unwrap().unwrap().hash(); + serai.finalized_block_by_number(block_included_in).await.unwrap().unwrap().hash(); let serai = serai.as_of(block_included_in_hash).coins(); assert_eq!( @@ -284,9 +284,9 @@ async fn sign_test() { tokio::time::sleep(Duration::from_secs(6)).await; } - while last_serai_block <= serai.latest_block().await.unwrap().number() { + while last_serai_block <= serai.latest_finalized_block().await.unwrap().number() { let burn_events = serai - .as_of(serai.block_by_number(last_serai_block).await.unwrap().unwrap().hash()) + .as_of(serai.finalized_block_by_number(last_serai_block).await.unwrap().unwrap().hash()) .coins() .burn_with_instruction_events() .await @@ -307,7 +307,8 @@ async fn sign_test() { } } - let last_serai_block = serai.block_by_number(last_serai_block).await.unwrap().unwrap(); + let last_serai_block = + serai.finalized_block_by_number(last_serai_block).await.unwrap().unwrap(); let last_serai_block_hash = last_serai_block.hash(); let serai = serai.as_of(last_serai_block_hash).coins(); assert_eq!(serai.coin_supply(Coin::Bitcoin).await.unwrap(), Amount(0)); diff --git a/tests/full-stack/src/lib.rs b/tests/full-stack/src/lib.rs index 7a9bbe8a6..def23519c 100644 --- a/tests/full-stack/src/lib.rs +++ b/tests/full-stack/src/lib.rs @@ -132,13 +132,13 @@ pub fn full_stack(name: &str) -> (Handles, Vec) { impl Handles { pub async fn serai(&self, ops: &DockerOperations) -> Serai { let serai_rpc = ops.handle(&self.serai).host_port(9944).unwrap(); - let serai_rpc = format!("ws://{}:{}", serai_rpc.0, serai_rpc.1); + let serai_rpc = format!("http://{}:{}", serai_rpc.0, serai_rpc.1); // If the RPC server has yet to start, sleep for up to 60s until it does for _ in 0 .. 60 { tokio::time::sleep(Duration::from_secs(1)).await; - let Ok(client) = Serai::new(&serai_rpc).await else { continue }; - if client.latest_block_hash().await.is_err() { + let Ok(client) = Serai::new(serai_rpc.clone()).await else { continue }; + if client.latest_finalized_block_hash().await.is_err() { continue; } return client; diff --git a/tests/full-stack/src/tests/mint_and_burn.rs b/tests/full-stack/src/tests/mint_and_burn.rs index 3a5252f54..617b6385e 100644 --- a/tests/full-stack/src/tests/mint_and_burn.rs +++ b/tests/full-stack/src/tests/mint_and_burn.rs @@ -201,7 +201,7 @@ async fn mint_and_burn_test() { let print_at = halt_at / 2; for i in 0 .. halt_at { if let Some(key_pair) = serai - .with_current_latest_block() + .as_of_latest_finalized_block() .await .unwrap() .validator_sets() @@ -417,7 +417,7 @@ async fn mint_and_burn_test() { let print_at = halt_at / 2; for i in 0 .. halt_at { if serai - .with_current_latest_block() + .as_of_latest_finalized_block() .await .unwrap() .in_instructions()