diff --git a/Cargo.lock b/Cargo.lock index 1727da5a38..e9d06368f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -50,9 +50,9 @@ dependencies = [ [[package]] name = "aes" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", @@ -61,9 +61,9 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209b47e8954a928e1d72e86eca7000ebb6655fe1436d33eefc2201cad027e237" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", "aes", @@ -84,8 +84,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", - "cw-utils 1.0.1", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", "error-stack", "integration-tests", "report", @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -107,20 +107,21 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.1.1" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -153,7 +154,7 @@ dependencies = [ "async-trait", "axelar-wasm-std", "axum 0.7.5", - "base64 0.21.4", + "base64 0.21.7", "bcs", "clap", "config", @@ -188,7 +189,7 @@ dependencies = [ "reqwest", "serde", "serde_json", - "serde_with 3.3.0", + "serde_with 3.7.0", "service-registry", "sha3 0.10.8", "sui-json-rpc-types", @@ -198,7 +199,7 @@ dependencies = [ "thiserror", "tokio", "tokio-stream", - "tokio-util 0.7.9", + "tokio-util 0.7.10", "toml 0.5.11", "tonic 0.8.3", "tonic-build", @@ -209,6 +210,8 @@ dependencies = [ "valuable", "valuable-serde", "voting-verifier", + "xrpl-multisig-prover", + "xrpl_http_client", ] [[package]] @@ -238,7 +241,7 @@ dependencies = [ "ed25519 1.5.3", "futures", "hex", - "http 0.2.9", + "http 0.2.12", "matchit 0.5.0", "pin-project-lite", "pkcs8 0.9.0", @@ -246,16 +249,16 @@ dependencies = [ "quinn-proto", "rand", "rcgen", - "ring", - "rustls 0.21.7", - "rustls-webpki 0.101.5", + "ring 0.16.20", + "rustls 0.21.11", + "rustls-webpki", "serde", "serde_json", - "socket2 0.5.4", + "socket2 0.5.6", "tap", "thiserror", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.10", "tower", "tracing", "x509-parser", @@ -263,9 +266,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -277,43 +280,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.3" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "ark-bls12-381" @@ -353,7 +356,7 @@ dependencies = [ "blake2", "derivative", "digest 0.10.7", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -399,7 +402,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] @@ -411,8 +414,8 @@ checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint 0.4.4", "num-traits", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -484,8 +487,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -523,6 +526,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" +dependencies = [ + "serde", +] + [[package]] name = "ascii-canvas" version = "3.0.0" @@ -554,8 +566,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "synstructure", ] @@ -566,8 +578,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -602,9 +614,9 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -614,13 +626,13 @@ source = "git+https://github.com/mystenmark/async-task?rev=4e45b26e11126b191701b [[package]] name = "async-trait" -version = "0.1.73" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -636,14 +648,13 @@ dependencies = [ [[package]] name = "auto_impl" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 1.0.109", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -654,9 +665,9 @@ checksum = "7460f7dd8e100147b82a63afca1a20eb6c231ee36b90ba7272e14951cb58af59" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axelar-wasm-std" @@ -666,7 +677,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "flagset", "hex", @@ -690,9 +701,9 @@ version = "0.1.0" dependencies = [ "axelar-wasm-std", "error-stack", - "quote 1.0.33", + "quote 1.0.36", "report", - "syn 2.0.37", + "syn 2.0.60", "thiserror", ] @@ -704,16 +715,16 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core 0.3.4", - "base64 0.21.4", + "base64 0.21.7", "bitflags 1.3.2", "bytes", "futures-util", "headers", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "itoa", - "matchit 0.7.2", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", @@ -745,10 +756,10 @@ dependencies = [ "http 1.1.0", "http-body 1.0.0", "http-body-util", - "hyper 1.3.0", + "hyper 1.3.1", "hyper-util", "itoa", - "matchit 0.7.2", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", @@ -775,8 +786,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -806,9 +817,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -839,9 +850,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -851,9 +862,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bcs" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd3ffe8b19a604421a5d461d4a70346223e535903fbc3067138bddbebddcf77" +checksum = "85b6598a2f5d564fb7855dc6b06fd1c38cff5a72bd8b863a4d021938497b440a" dependencies = [ "serde", "thiserror", @@ -910,13 +921,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.15", - "proc-macro2 1.0.67", - "quote 1.0.33", + "prettyplease 0.2.19", + "proc-macro2 1.0.81", + "quote 1.0.36", "regex", "rustc-hash", "shlex", - "syn 2.0.37", + "syn 2.0.60", ] [[package]] @@ -926,13 +937,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ "bs58 0.5.1", - "hmac", + "hmac 0.12.1", "k256", "once_cell", "pbkdf2 0.12.2", "rand_core 0.6.4", "ripemd", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", "zeroize", ] @@ -975,9 +986,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bitmaps" @@ -1045,16 +1056,15 @@ dependencies = [ [[package]] name = "blake3" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "199c42ab6972d92c9f8995f086273d25c42fc0f7b2a1fcefba465c1352d25ba5" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq 0.3.0", - "digest 0.10.7", ] [[package]] @@ -1122,15 +1132,15 @@ dependencies = [ [[package]] name = "bnum" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" [[package]] name = "brotli" -version = "3.3.4" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1139,9 +1149,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "2.3.4" +version = "2.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -1159,7 +1169,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.7", + "sha2 0.10.8", "tinyvec", ] @@ -1185,9 +1195,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -1197,27 +1207,27 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] @@ -1254,18 +1264,18 @@ dependencies = [ [[package]] name = "cargo-platform" -version = "0.1.3" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] [[package]] name = "cargo_metadata" -version = "0.17.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" dependencies = [ "camino", "cargo-platform", @@ -1286,12 +1296,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" dependencies = [ "jobserver", "libc", + "once_cell", ] [[package]] @@ -1311,15 +1322,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -1334,9 +1345,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -1345,9 +1356,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.4" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -1355,33 +1366,33 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.4" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "heck 0.5.0", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "clear_on_drop" @@ -1432,10 +1443,10 @@ dependencies = [ "bs58 0.5.1", "coins-core", "digest 0.10.7", - "hmac", + "hmac 0.12.1", "k256", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", ] @@ -1447,11 +1458,11 @@ checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" dependencies = [ "bitvec 1.0.1", "coins-bip32", - "hmac", + "hmac 0.12.1", "once_cell", "pbkdf2 0.12.2", "rand", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", ] @@ -1461,7 +1472,7 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bech32", "bs58 0.5.1", "digest 0.10.7", @@ -1470,7 +1481,7 @@ dependencies = [ "ripemd", "serde", "serde_derive", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.10.8", "thiserror", ] @@ -1489,20 +1500,19 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "colored" -version = "2.0.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" dependencies = [ - "is-terminal", "lazy_static", "windows-sys 0.48.0", ] [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "json5", @@ -1527,7 +1537,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "flagset", "gateway-api", @@ -1547,7 +1557,7 @@ dependencies = [ "axelar-wasm-std-derive", "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "flagset", "hex", @@ -1563,33 +1573,34 @@ dependencies = [ [[package]] name = "console" -version = "0.15.7" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" dependencies = [ "encode_unicode", "lazy_static", "libc", - "windows-sys 0.45.0", + "windows-sys 0.52.0", ] [[package]] name = "const-hex" -version = "1.8.0" +version = "1.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08849ed393c907c90016652a01465a12d86361cd38ad2a7de026c56a520cc259" +checksum = "5ba00838774b4ab0233e355d26710fbfc8327a05c017f6dc4873f876d1f79f78" dependencies = [ "cfg-if", "cpufeatures", "hex", + "proptest", "serde", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" @@ -1620,9 +1631,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1630,9 +1641,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -1688,9 +1699,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" dependencies = [ "digest 0.10.7", "ecdsa", @@ -1711,9 +1722,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce34a08020433989af5cc470104f6bd22134320fe0221bd8aeb919fd5ec92d5" +checksum = "ac3e3a2136e2a60e8b6582f5dffca5d1a683ed77bf38537d330bc1dfccd69010" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -1724,22 +1735,23 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.4.0" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96694ec781a7dd6dea1f968a2529ade009c21ad999c88b5f53d6cc495b3b96f7" +checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "cosmwasm-std" -version = "1.3.4" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0837f920e0ebdb6eed95f2899e39db632f7de8fb68034464a5cee925a2dffdfd" +checksum = "ad011ae7447188e26e4a7dbca2fcd0fc186aa21ae5c86df0503ea44c78f9e469" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", + "bech32", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -1749,15 +1761,16 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", - "sha2 0.10.7", + "sha2 0.10.8", + "static_assertions", "thiserror", ] [[package]] name = "cosmwasm-storage" -version = "1.3.4" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f73fc6766006aef09dea5db0c0728446e8c0e22b26eeb33c83ae70a500894ff3" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -1765,64 +1778,55 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -1832,9 +1836,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] name = "crypto-bigint" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -1853,6 +1857,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + [[package]] name = "ct-logs" version = "0.8.0" @@ -1886,9 +1900,9 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" dependencies = [ "cfg-if", "cpufeatures", @@ -1907,9 +1921,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -1958,9 +1972,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -1984,13 +1998,13 @@ dependencies = [ [[package]] name = "cw-utils" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +checksum = "1c4a657e5caacc3a0d00ee96ca8618745d050b8f757c709babafb81208d4239c" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw2 1.1.0", + "cw2 1.1.2", "schemars", "semver", "serde", @@ -2012,14 +2026,15 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "schemars", + "semver", "serde", "thiserror", ] @@ -2036,12 +2051,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.8", + "darling_macro 0.20.8", ] [[package]] @@ -2052,24 +2067,24 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.67", - "quote 1.0.33", - "strsim", + "proc-macro2 1.0.81", + "quote 1.0.36", + "strsim 0.10.0", "syn 1.0.109", ] [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.67", - "quote 1.0.33", - "strsim", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "strsim 0.10.0", + "syn 2.0.60", ] [[package]] @@ -2079,19 +2094,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core 0.14.4", - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "darling_core 0.20.3", - "quote 1.0.33", - "syn 2.0.37", + "darling_core 0.20.8", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2101,7 +2116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core", @@ -2109,15 +2124,15 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "data-encoding-macro" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c904b33cc60130e1aeea4956ab803d08a3f4a0ca82d64ed757afac3891f2bb99" +checksum = "20c01c06f5f429efdf2bae21eb67c28b3df3cf85b7dd2d8ef09c0838dac5d33e" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2125,9 +2140,9 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fdf3fce3ce863539ec1d7fd1b6dcc3c645663376b43ed376bbf887733e4f772" +checksum = "0047d07f2c89b17dd631c80450d69841a6b5d7fb17278cbc43d7e4cfcf2576f3" dependencies = [ "data-encoding", "syn 1.0.109", @@ -2146,9 +2161,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "der_derive", @@ -2176,17 +2191,18 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "deranged" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ + "powerfmt", "serde", ] @@ -2196,8 +2212,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4255bb7dd538590188bd0aea52e48bd699b19bd90b0d069ec2ced8461fe23273" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -2207,8 +2223,8 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -2228,8 +2244,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -2250,18 +2266,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case 0.4.0", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustc_version", "syn 1.0.109", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "difference" version = "2.0.0" @@ -2343,9 +2353,9 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2362,9 +2372,9 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dunce" @@ -2374,9 +2384,9 @@ checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ec-gpu" @@ -2386,16 +2396,16 @@ checksum = "bd63582de2b59ea1aa48d7c1941b5d87618d95484397521b3acdfa0e1e9f5e45" [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der 0.7.9", "digest 0.10.7", "elliptic-curve", "rfc6979", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2411,12 +2421,12 @@ dependencies = [ [[package]] name = "ed25519" -version = "2.2.2" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ "pkcs8 0.10.2", - "signature 2.1.0", + "signature 2.2.0", ] [[package]] @@ -2440,12 +2450,12 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519 2.2.2", + "curve25519-dalek 4.1.2", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "zeroize", ] @@ -2467,15 +2477,15 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" -version = "0.13.5" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", @@ -2508,20 +2518,20 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "enr" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe81b5c06ecfdbc71dd845216f225f53b62a10cb8a16c946836a3467f701d05b" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "hex", "k256", @@ -2547,21 +2557,42 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "enum_dispatch" -version = "0.3.12" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ "once_cell", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", +] + +[[package]] +name = "enumflags2" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" +dependencies = [ + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2582,23 +2613,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -2622,13 +2642,13 @@ dependencies = [ "ctr", "digest 0.10.7", "hex", - "hmac", + "hmac 0.12.1", "pbkdf2 0.11.0", "rand", "scrypt", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.10.8", "thiserror", "uuid 0.8.2", @@ -2677,16 +2697,16 @@ dependencies = [ "impl-codec 0.6.0", "impl-rlp", "impl-serde 0.4.0", - "primitive-types 0.12.1", + "primitive-types 0.12.2", "scale-info", "uint", ] [[package]] name = "ethers" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad13497f6e0a24292fc7b408e30d22fe9dc262da1f40d7b542c3a44e7fc0476" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" dependencies = [ "ethers-addressbook", "ethers-contract", @@ -2700,9 +2720,9 @@ dependencies = [ [[package]] name = "ethers-addressbook" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6e9e8acd0ed348403cc73a670c24daba3226c40b98dc1a41903766b3ab6240a" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" dependencies = [ "ethers-core", "once_cell", @@ -2712,9 +2732,9 @@ dependencies = [ [[package]] name = "ethers-contract" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79269278125006bb0552349c03593ffa9702112ca88bc7046cc669f148fb47c" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" dependencies = [ "const-hex", "ethers-contract-abigen", @@ -2731,9 +2751,9 @@ dependencies = [ [[package]] name = "ethers-contract-abigen" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce95a43c939b2e4e2f3191c5ad4a1f279780b8a39139c9905b43a7433531e2ab" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" dependencies = [ "Inflector", "const-hex", @@ -2741,39 +2761,39 @@ dependencies = [ "ethers-core", "ethers-etherscan", "eyre", - "prettyplease 0.2.15", - "proc-macro2 1.0.67", - "quote 1.0.33", + "prettyplease 0.2.19", + "proc-macro2 1.0.81", + "quote 1.0.36", "regex", "reqwest", "serde", "serde_json", - "syn 2.0.37", - "toml 0.7.8", + "syn 2.0.60", + "toml 0.8.12", "walkdir", ] [[package]] name = "ethers-contract-derive" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9ce44906fc871b3ee8c69a695ca7ec7f70e50cb379c9b9cb5e532269e492f6" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" dependencies = [ "Inflector", "const-hex", "ethers-contract-abigen", "ethers-core", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "serde_json", - "syn 2.0.37", + "syn 2.0.60", ] [[package]] name = "ethers-core" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0a17f0708692024db9956b31d7a20163607d2745953f5ae8125ab368ba280ad" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" dependencies = [ "arrayvec", "bytes", @@ -2791,8 +2811,8 @@ dependencies = [ "rlp", "serde", "serde_json", - "strum 0.25.0", - "syn 2.0.37", + "strum 0.26.2", + "syn 2.0.60", "tempfile", "thiserror", "tiny-keccak", @@ -2801,10 +2821,11 @@ dependencies = [ [[package]] name = "ethers-etherscan" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e53451ea4a8128fbce33966da71132cf9e1040dcfd2a2084fd7733ada7b2045" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" dependencies = [ + "chrono", "ethers-core", "reqwest", "semver", @@ -2816,9 +2837,9 @@ dependencies = [ [[package]] name = "ethers-middleware" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "473f1ccd0c793871bbc248729fa8df7e6d2981d6226e4343e3bbaa9281074d5d" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" dependencies = [ "async-trait", "auto_impl", @@ -2843,13 +2864,13 @@ dependencies = [ [[package]] name = "ethers-providers" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6838fa110e57d572336178b7c79e94ff88ef976306852d8cb87d9e5b1fc7c0b5" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" dependencies = [ "async-trait", "auto_impl", - "base64 0.21.4", + "base64 0.21.7", "bytes", "const-hex", "enr", @@ -2858,7 +2879,7 @@ dependencies = [ "futures-timer", "futures-util", "hashers", - "http 0.2.9", + "http 0.2.12", "instant", "jsonwebtoken", "once_cell", @@ -2880,9 +2901,9 @@ dependencies = [ [[package]] name = "ethers-signers" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea44bec930f12292866166f9ddbea6aa76304850e4d8dcd66dc492b43d00ff1" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" dependencies = [ "async-trait", "coins-bip32", @@ -2892,16 +2913,16 @@ dependencies = [ "eth-keystore", "ethers-core", "rand", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "tracing", ] [[package]] name = "ethers-solc" -version = "2.0.10" +version = "2.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de34e484e7ae3cab99fbfd013d6c5dc7f9013676a4e0e414d8b12e1213e8b3ba" +checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" dependencies = [ "cfg-if", "const-hex", @@ -2931,16 +2952,16 @@ dependencies = [ [[package]] name = "ethnum" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8ff382b2fa527fb7fb06eeebfc5bbb3f17e3cc6b9d70b006c41daa8824adac" +checksum = "b90ca2580b73ab6a1f724b76ca11ab632df820fd6040c336200d2c1df7b3c82c" [[package]] name = "events" version = "0.1.0" dependencies = [ "axelar-wasm-std", - "base64 0.21.4", + "base64 0.21.7", "cosmrs", "error-stack", "serde_json", @@ -2954,17 +2975,17 @@ version = "0.1.0" dependencies = [ "error-stack", "events", - "quote 1.0.33", + "quote 1.0.36", "serde", "serde_json", - "syn 2.0.37", + "syn 2.0.60", ] [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", @@ -3016,9 +3037,9 @@ dependencies = [ "serde_bytes", "serde_json", "serde_with 2.3.3", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.10.8", - "signature 2.1.0", + "signature 2.2.0", "static_assertions", "thiserror", "tokio", @@ -3032,8 +3053,8 @@ version = "0.1.3" source = "git+https://github.com/MystenLabs/fastcrypto?rev=69180dc7275f5f0efb69e11e9d03f6db338d1dd6#69180dc7275f5f0efb69e11e9d03f6db338d1dd6" dependencies = [ "convert_case 0.6.0", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -3084,7 +3105,7 @@ dependencies = [ "once_cell", "regex", "reqwest", - "rustls-webpki 0.101.5", + "rustls-webpki", "schemars", "serde", "serde_json", @@ -3102,9 +3123,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.0.0" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fdlimit" @@ -3139,16 +3160,16 @@ dependencies = [ "num-bigint 0.3.3", "num-integer", "num-traits", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" [[package]] name = "fixed-hash" @@ -3188,18 +3209,18 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flagset" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a7e408202050813e6f1d9addadcaafef3dca7530c7ddfb005d4081cce6779" +checksum = "cdeb3aa5e95cf9aabc17f060cfa0ced7b83f042390760ca53bf09df9968acaa1" dependencies = [ "serde", ] [[package]] name = "flate2" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" dependencies = [ "crc32fast", "miniz_oxide", @@ -3230,11 +3251,26 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -3275,9 +3311,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -3290,9 +3326,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -3300,15 +3336,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -3317,9 +3353,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-locks" @@ -3333,32 +3369,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" dependencies = [ "gloo-timers", "send_wrapper 0.4.0", @@ -3366,9 +3402,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -3403,7 +3439,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "gateway-api", "itertools 0.11.0", @@ -3435,9 +3471,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "js-sys", @@ -3448,9 +3484,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -3458,9 +3494,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" @@ -3495,20 +3531,20 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.9", - "indexmap 2.0.0", + "http 0.2.12", + "indexmap 2.2.6", "slab", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.10", "tracing", ] @@ -3518,7 +3554,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", ] [[package]] @@ -3527,14 +3563,14 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.11", ] [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" [[package]] name = "hashers" @@ -3547,11 +3583,11 @@ dependencies = [ [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", "byteorder", "crossbeam-channel", "flate2", @@ -3565,10 +3601,10 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "headers-core", - "http 0.2.9", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -3580,7 +3616,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http 0.2.9", + "http 0.2.12", ] [[package]] @@ -3598,11 +3634,17 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -3615,11 +3657,21 @@ dependencies = [ [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" dependencies = [ - "hmac", + "crypto-mac", + "digest 0.9.0", ] [[package]] @@ -3631,20 +3683,31 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "http" -version = "0.2.9" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -3664,12 +3727,12 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.9", + "http 0.2.12", "pin-project-lite", ] @@ -3732,22 +3795,22 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "socket2 0.5.6", "tokio", "tower-service", "tracing", @@ -3756,9 +3819,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f24ce812868d86d19daa79bf3bf9175bc44ea323391147a5e3abde2a283871b" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", @@ -3782,8 +3845,8 @@ dependencies = [ "bytes", "futures", "headers", - "http 0.2.9", - "hyper 0.14.27", + "http 0.2.12", + "hyper 0.14.28", "hyper-rustls 0.22.1", "rustls-native-certs", "tokio", @@ -3800,7 +3863,7 @@ checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" dependencies = [ "ct-logs", "futures-util", - "hyper 0.14.27", + "hyper 0.14.28", "log", "rustls 0.19.1", "rustls-native-certs", @@ -3812,14 +3875,14 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http 0.2.9", - "hyper 0.14.27", - "rustls 0.21.7", + "http 0.2.12", + "hyper 0.14.28", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", ] @@ -3830,12 +3893,25 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.27", + "hyper 0.14.28", "pin-project-lite", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.28", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyper-util" version = "0.1.3" @@ -3846,24 +3922,24 @@ dependencies = [ "futures-util", "http 1.1.0", "http-body 1.0.0", - "hyper 1.3.0", + "hyper 1.3.1", "pin-project-lite", - "socket2 0.5.4", + "socket2 0.5.6", "tokio", ] [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -3883,9 +3959,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -3920,7 +3996,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "parity-scale-codec 3.6.5", + "parity-scale-codec 3.6.9", ] [[package]] @@ -3956,8 +4032,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -3980,12 +4056,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "serde", ] @@ -4001,9 +4077,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.31.0" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a" +checksum = "3eab73f58e59ca6526037208f0e98851159ec1633cf17b6cd2e1f2c3fd5d53cc" dependencies = [ "console", "lazy_static", @@ -4012,7 +4088,6 @@ dependencies = [ "pest_derive", "serde", "similar", - "yaml-rust", ] [[package]] @@ -4048,6 +4123,7 @@ dependencies = [ "sha3 0.10.8", "tofn", "voting-verifier", + "xrpl-multisig-prover", ] [[package]] @@ -4056,7 +4132,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ab388864246d58a276e60e7569a833d9cc4cd75c66e5ca77c177dad38e59996" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", "dashmap", "hashbrown 0.12.3", "once_cell", @@ -4065,9 +4141,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "iri-string" @@ -4079,54 +4155,52 @@ dependencies = [ ] [[package]] -name = "is-terminal" -version = "0.4.9" +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.48.0", + "either", ] [[package]] name = "itertools" -version = "0.10.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.26" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -4157,9 +4231,9 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -4167,54 +4241,56 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", ] [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] [[package]] name = "lalrpop" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" dependencies = [ "ascii-canvas", "bit-set", - "diff", "ena", - "is-terminal", - "itertools 0.10.5", + "itertools 0.11.0", "lalrpop-util", "petgraph 0.6.4", "regex", - "regex-syntax 0.7.5", + "regex-syntax", "string_cache", "term", "tiny-keccak", "unicode-xid 0.2.4", + "walkdir", ] [[package]] name = "lalrpop-util" -version = "0.20.0" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata", +] [[package]] name = "lazy_static" @@ -4222,7 +4298,7 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" dependencies = [ - "spin", + "spin 0.5.2", ] [[package]] @@ -4239,19 +4315,29 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "winapi", + "windows-targets 0.52.5", ] [[package]] name = "libm" -version = "0.2.7" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] [[package]] name = "librocksdb-sys" @@ -4270,10 +4356,58 @@ dependencies = [ ] [[package]] -name = "libz-sys" -version = "1.1.12" +name = "libsecp256k1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libz-sys" +version = "1.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" dependencies = [ "cc", "pkg-config", @@ -4288,15 +4422,15 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -4304,9 +4438,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" dependencies = [ "serde", ] @@ -4335,33 +4469,25 @@ checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" [[package]] name = "matchit" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "md-5" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ + "cfg-if", "digest 0.10.7", ] [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "merlin" @@ -4399,18 +4525,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", @@ -4440,8 +4566,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -4455,7 +4581,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "integration-tests", "multisig", @@ -4772,8 +4898,8 @@ version = "0.1.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ "enum-compat-util", - "quote 1.0.33", - "syn 2.0.37", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -4837,7 +4963,7 @@ name = "msim" version = "0.1.0" source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.8", "async-task", "bincode", "bytes", @@ -4853,7 +4979,7 @@ dependencies = [ "rand", "real_tokio", "serde", - "socket2 0.4.9", + "socket2 0.4.10", "tap", "tokio-util 0.7.7", "toml 0.5.11", @@ -4867,8 +4993,8 @@ version = "0.1.0" source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -4919,10 +5045,10 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ - "proc-macro-crate", + "proc-macro-crate 1.1.3", "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "synstructure", ] @@ -4943,9 +5069,9 @@ dependencies = [ "cosmwasm-crypto", "cosmwasm-schema", "cosmwasm-std", - "curve25519-dalek 4.1.1", + "curve25519-dalek 4.1.2", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "ed25519-dalek", "enum-display-derive", "error-stack", @@ -4972,8 +5098,8 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", - "cw-utils 1.0.1", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", "elliptic-curve", "error-stack", "ethabi", @@ -5011,7 +5137,7 @@ dependencies = [ "tap", "tokio", "tracing", - "uuid 1.4.1", + "uuid 1.8.0", "workspace-hack", ] @@ -5025,7 +5151,7 @@ dependencies = [ "bytes", "eyre", "futures", - "http 0.2.9", + "http 0.2.12", "multiaddr", "serde", "snap", @@ -5064,7 +5190,7 @@ name = "mysten-util-mem-derive" version = "0.1.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ - "proc-macro2 1.0.67", + "proc-macro2 1.0.81", "syn 1.0.109", "synstructure", "workspace-hack", @@ -5122,6 +5248,24 @@ dependencies = [ "workspace-hack", ] +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "neptune" version = "13.0.0" @@ -5143,9 +5287,9 @@ dependencies = [ [[package]] name = "new_debug_unreachable" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nexus-gateway" @@ -5156,7 +5300,7 @@ dependencies = [ "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "hex", "mockall", @@ -5195,9 +5339,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" dependencies = [ "num-bigint 0.4.4", "num-complex", @@ -5249,39 +5393,44 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -5302,9 +5451,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -5322,30 +5471,30 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70bf6736f74634d299d00086f02986875b3c2d924781a6a2cb6c201e73da0ceb" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ea360eafe1022f7cc56cd7b869ed57330fb2453d0c7831d99b74c65d2f5597" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -5361,15 +5510,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "open-fastrlp" @@ -5391,17 +5540,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ "bytes", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -5437,9 +5624,9 @@ checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -5457,7 +5644,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -5496,15 +5683,15 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" dependencies = [ "arrayvec", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", - "parity-scale-codec-derive 3.6.5", + "parity-scale-codec-derive 3.6.9", "serde", ] @@ -5514,21 +5701,21 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro-crate 2.0.0", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -5544,13 +5731,13 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets 0.48.5", ] @@ -5609,9 +5796,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", "password-hash", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -5621,7 +5808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", ] [[package]] @@ -5647,8 +5834,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" dependencies = [ "peg-runtime", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", ] [[package]] @@ -5686,15 +5873,15 @@ 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 = "pest" -version = "2.7.3" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -5703,9 +5890,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.3" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" dependencies = [ "pest", "pest_generator", @@ -5713,26 +5900,26 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.3" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "pest_meta" -version = "2.7.3" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" dependencies = [ "once_cell", "pest", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -5752,7 +5939,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset 0.4.2", - "indexmap 2.0.0", + "indexmap 2.2.6", ] [[package]] @@ -5793,9 +5980,9 @@ checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", "phf_shared 0.11.2", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -5818,29 +6005,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -5876,27 +6063,27 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", - "spki 0.7.2", + "der 0.7.9", + "spki 0.7.3", ] [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "platforms" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "polyval" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", "cpufeatures", @@ -5904,6 +6091,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -5952,25 +6145,25 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ - "proc-macro2 1.0.67", + "proc-macro2 1.0.81", "syn 1.0.109", ] [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ - "proc-macro2 1.0.67", - "syn 2.0.37", + "proc-macro2 1.0.81", + "syn 2.0.60", ] [[package]] name = "primeorder" -version = "0.13.2" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2fcef82c0ec6eefcc179b978446c399b3cdf73c392c35604e399eee6df1ee3" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ "elliptic-curve", ] @@ -5989,9 +6182,9 @@ dependencies = [ [[package]] name = "primitive-types" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash 0.8.0", "impl-codec 0.6.0", @@ -6011,6 +6204,24 @@ dependencies = [ "toml 0.5.11", ] +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -6018,8 +6229,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "version_check", ] @@ -6030,8 +6241,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "version_check", ] @@ -6046,9 +6257,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.67" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -6081,19 +6292,19 @@ dependencies = [ [[package]] name = "proptest" -version = "1.2.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e35c06b98bf36aba164cc17cb25f7e232f5c4aeea73baa14b8a9f0d92dbfa65" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", - "bitflags 1.3.2", - "byteorder", + "bit-vec", + "bitflags 2.5.0", "lazy_static", "num-traits", "rand", "rand_chacha", "rand_xorshift", - "regex-syntax 0.6.29", + "regex-syntax", "rusty-fork", "tempfile", "unarray", @@ -6132,12 +6343,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.4", ] [[package]] @@ -6170,8 +6381,8 @@ checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -6183,22 +6394,22 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.11.0", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "itertools 0.12.1", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6237,7 +6448,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.11", "thiserror", "tokio", "tracing", @@ -6245,15 +6456,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13f81c9a9d574310b8351f8666f5a93ac3b0069c45c28ad52c10291389a7cf9" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand", - "ring", + "ring 0.16.20", "rustc-hash", - "rustls 0.21.7", + "rustls 0.21.11", "slab", "thiserror", "tinyvec", @@ -6268,7 +6479,7 @@ checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" dependencies = [ "bytes", "libc", - "socket2 0.5.4", + "socket2 0.5.6", "tracing", "windows-sys 0.48.0", ] @@ -6284,11 +6495,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "proc-macro2 1.0.67", + "proc-macro2 1.0.81", ] [[package]] @@ -6359,18 +6570,18 @@ dependencies = [ [[package]] name = "random-string" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e63111ec5292d8af9c220f06fe3bb87991cc78b6f1f7e291d1ae6b8a60817" +checksum = "f70fd13c3024ae3f17381bb5c4d409c6dc9ea6895c08fa2147aba305bea3c4af" dependencies = [ "fastrand 1.9.0", ] [[package]] name = "rayon" -version = "1.7.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -6378,14 +6589,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] @@ -6395,20 +6604,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", - "ring", + "ring 0.16.20", "time", "yasna", ] [[package]] name = "readonly" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8f439da1766942fe069954da6058b2e6c1760eb878bae76f5be9fc29f56f574" +checksum = "a25d631e41bfb5fdcde1d4e2215f62f7f0afa3ff11e26563765bd6ea1d229aeb" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6424,100 +6633,79 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.4.9", - "tokio-macros 2.1.0 (git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45)", + "socket2 0.4.10", + "tokio-macros 2.1.0", "windows-sys 0.48.0", ] [[package]] name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ "getrandom", - "redox_syscall 0.2.16", + "libredox", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acde58d073e9c79da00f2b5b84eed919c8326832648a5b109b3fce1bb1175280" +checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" +checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" - -[[package]] -name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "report" @@ -6532,28 +6720,30 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.25" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eea5a9eb898d3783f17c6407670e3592fd174cb81a10e51d4c37f49450b9946" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", - "hyper-rustls 0.24.1", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls 0.24.2", + "hyper-tls", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.7", + "rustls 0.21.11", "rustls-pemfile", "serde", "serde_json", @@ -6561,22 +6751,17 @@ dependencies = [ "sync_wrapper 0.1.2", "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", "winreg", ] -[[package]] -name = "retain_mut" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c31b5c4033f8fdde8700e4657be2c497e7288f01515be52168c631e2e4d4086" - [[package]] name = "rewards" version = "0.1.0" @@ -6587,7 +6772,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "itertools 0.11.0", "report", @@ -6600,7 +6785,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] @@ -6613,12 +6798,27 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + [[package]] name = "ripemd" version = "0.1.3" @@ -6645,20 +6845,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "roaring" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6106b5cf8587f5834158895e9715a3c6c9716c8aefab57f1f7680917191c7873" +checksum = "a1c77081a55300e016cb86f2864415b7518741879db925b8d488a0ee0d2da6bf" dependencies = [ "bytemuck", "byteorder", - "retain_mut", ] [[package]] @@ -6697,8 +6896,8 @@ dependencies = [ "pkcs1", "pkcs8 0.9.0", "rand_core 0.6.4", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "zeroize", ] @@ -6751,15 +6950,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.14" +version = "0.38.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f" +checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -6770,21 +6969,21 @@ checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ "base64 0.13.1", "log", - "ring", + "ring 0.16.20", "sct 0.6.1", "webpki", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", - "ring", - "rustls-webpki 0.101.5", - "sct 0.7.0", + "ring 0.17.8", + "rustls-webpki", + "sct 0.7.1", ] [[package]] @@ -6801,38 +7000,28 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" -dependencies = [ - "base64 0.21.4", -] - -[[package]] -name = "rustls-webpki" -version = "0.100.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "ring", - "untrusted", + "base64 0.21.7", ] [[package]] name = "rustls-webpki" -version = "0.101.5" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a27e3b59326c16e23d30aeb7a36a24cc0d29e71d68ff611cdfb4a01d013bed" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "rusty-fork" @@ -6848,9 +7037,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "salsa20" @@ -6872,42 +7061,42 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.9.0" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" dependencies = [ "cfg-if", "derive_more", - "parity-scale-codec 3.6.5", + "parity-scale-codec 3.6.9", "scale-info-derive", ] [[package]] name = "scale-info-derive" -version = "2.9.0" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" dependencies = [ - "proc-macro-crate", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro-crate 1.1.3", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "either", @@ -6918,12 +7107,12 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "serde_derive_internals", "syn 1.0.109", ] @@ -6940,10 +7129,10 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" dependencies = [ - "hmac", + "hmac 0.12.1", "pbkdf2 0.11.0", "salsa20", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -6952,18 +7141,18 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -6973,7 +7162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der 0.7.8", + "der 0.7.9", "generic-array", "pkcs8 0.10.2", "subtle", @@ -7002,9 +7191,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -7015,9 +7204,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -7025,9 +7214,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] @@ -7046,9 +7235,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] @@ -7085,22 +7274,22 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -7109,18 +7298,18 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", "itoa", "ryu", "serde", @@ -7128,9 +7317,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -7138,20 +7327,20 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -7186,18 +7375,19 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.3.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca3b16a3d82c4088f343b7480a93550b3eabe1a358569c2dfe38bbcead07237" +checksum = "ee80b0e361bbf88fd2f6e242ccd19cfda072cb0faa6ae694ecee08199938569a" dependencies = [ - "base64 0.21.4", + "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.0.0", + "indexmap 2.2.6", "serde", + "serde_derive", "serde_json", - "serde_with_macros 3.3.0", + "serde_with_macros 3.7.0", "time", ] @@ -7207,22 +7397,22 @@ version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "darling 0.20.3", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "darling 0.20.8", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "serde_with_macros" -version = "3.3.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" +checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655" dependencies = [ - "darling 0.20.3", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "darling 0.20.8", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -7247,7 +7437,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "integration-tests", "report", @@ -7258,9 +7448,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -7282,9 +7472,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -7325,9 +7515,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -7347,9 +7537,9 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" @@ -7368,9 +7558,9 @@ checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "signature" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", "rand_core 0.6.4", @@ -7388,9 +7578,9 @@ dependencies = [ [[package]] name = "similar" -version = "2.2.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" [[package]] name = "simple_asn1" @@ -7437,15 +7627,15 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snap" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.4.9" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" dependencies = [ "libc", "winapi", @@ -7453,19 +7643,19 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "solang-parser" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb9fa2fa2fa6837be8a2495486ff92e3ffe68a99b6eeba288e139efdd842457" +checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" dependencies = [ "itertools 0.11.0", "lalrpop", @@ -7481,6 +7671,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "spki" version = "0.6.0" @@ -7493,12 +7689,12 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.9", ] [[package]] @@ -7526,6 +7722,12 @@ 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 = "strum" version = "0.24.1" @@ -7541,7 +7743,16 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" dependencies = [ - "strum_macros 0.25.2", + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros 0.26.2", ] [[package]] @@ -7551,30 +7762,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustversion", "syn 1.0.109", ] [[package]] name = "strum_macros" -version = "0.25.2" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.81", + "quote 1.0.36", + "rustversion", + "syn 2.0.60", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustversion", - "syn 2.0.37", + "syn 2.0.60", ] [[package]] name = "subtle" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "subtle-encoding" @@ -7708,10 +7932,10 @@ version = "0.7.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ "msim-macros", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "sui-enum-compat-util", - "syn 2.0.37", + "syn 2.0.60", "workspace-hack", ] @@ -7735,8 +7959,8 @@ name = "sui-protocol-config-macros" version = "0.1.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "workspace-hack", ] @@ -7817,9 +8041,9 @@ dependencies = [ [[package]] name = "svm-rs" -version = "0.3.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597e3a746727984cb7ea2487b6a40726cad0dbe86628e7d429aa6b8c4c153db4" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" dependencies = [ "dirs", "fs2", @@ -7829,7 +8053,7 @@ dependencies = [ "semver", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "url", "zip", @@ -7852,19 +8076,19 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.37" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "unicode-ident", ] @@ -7886,28 +8110,28 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "unicode-xid 0.2.4", ] [[package]] name = "system-configuration" -version = "0.6.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bc6ee10a9b4fcf576e9b0819d95ec16f4d2c02d39fd83ac1c8789785c4a42" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags 2.4.0", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] [[package]] name = "system-configuration-sys" -version = "0.6.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" dependencies = [ "core-foundation-sys", "libc", @@ -7932,8 +8156,8 @@ checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -7945,15 +8169,14 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", - "fastrand 2.0.0", - "redox_syscall 0.3.5", + "fastrand 2.0.2", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -7964,7 +8187,7 @@ checksum = "3f0a7d05cf78524782337f8edd55cbc578d159a16ad4affe2135c92f7dbac7f0" dependencies = [ "bytes", "digest 0.10.7", - "ed25519 2.2.2", + "ed25519 2.2.3", "ed25519-consensus", "flex-error", "futures", @@ -7978,8 +8201,8 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "subtle-encoding", "tendermint-proto 0.32.2", @@ -7994,7 +8217,7 @@ source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x# dependencies = [ "bytes", "digest 0.10.7", - "ed25519 2.2.2", + "ed25519 2.2.3", "ed25519-consensus", "flex-error", "futures", @@ -8006,8 +8229,8 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "subtle-encoding", "tendermint-proto 0.33.0", @@ -8091,8 +8314,8 @@ dependencies = [ "flex-error", "futures", "getrandom", - "http 0.2.9", - "hyper 0.14.27", + "http 0.2.12", + "hyper 0.14.28", "hyper-proxy", "hyper-rustls 0.22.1", "peg", @@ -8128,9 +8351,9 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.1.3" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -8143,29 +8366,29 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -8182,12 +8405,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.28" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -8195,16 +8420,17 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.14" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -8239,25 +8465,25 @@ source = "git+https://github.com/axelarnetwork/tofn.git?branch=update-deps#88285 dependencies = [ "bincode", "crypto-bigint", - "der 0.7.8", + "der 0.7.9", "ecdsa", - "ed25519 2.2.2", + "ed25519 2.2.3", "ed25519-dalek", - "hmac", + "hmac 0.12.1", "k256", "rand", "rand_chacha", "serde", - "sha2 0.10.7", + "sha2 0.10.8", "tracing", "zeroize", ] [[package]] name = "tokio" -version = "1.32.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -8267,8 +8493,8 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.4", - "tokio-macros 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "socket2 0.5.6", + "tokio-macros 2.2.0", "windows-sys 0.48.0", ] @@ -8285,22 +8511,32 @@ dependencies = [ [[package]] name = "tokio-macros" version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "tokio-macros" -version = "2.1.0" -source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "native-tls", + "tokio", ] [[package]] @@ -8320,35 +8556,35 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.11", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.10", ] [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.7", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", "tungstenite", - "webpki-roots 0.23.1", + "webpki-roots 0.25.4", ] [[package]] @@ -8370,9 +8606,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.9" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -8393,36 +8629,58 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.12", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", + "toml_datetime", + "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.22.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" +dependencies = [ + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.6", ] [[package]] @@ -8439,9 +8697,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-timeout", "percent-encoding", "pin-project", @@ -8449,7 +8707,7 @@ dependencies = [ "prost-derive 0.11.9", "tokio", "tokio-stream", - "tokio-util 0.7.9", + "tokio-util 0.7.10", "tower", "tower-layer", "tower-service", @@ -8466,17 +8724,17 @@ dependencies = [ "async-stream", "async-trait", "axum 0.6.20", - "base64 0.21.4", + "base64 0.21.7", "bytes", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.12.3", - "rustls 0.21.7", + "prost 0.12.4", + "rustls 0.21.11", "rustls-pemfile", "tokio", "tokio-rustls 0.24.1", @@ -8494,9 +8752,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" dependencies = [ "prettyplease 0.1.25", - "proc-macro2 1.0.67", + "proc-macro2 1.0.81", "prost-build", - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] @@ -8507,7 +8765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f80db390246dfb46553481f6024f0082ba00178ea495dbb99e70ba9a4fafb5e1" dependencies = [ "async-stream", - "prost 0.12.3", + "prost 0.12.4", "tokio", "tokio-stream", "tonic 0.10.2", @@ -8528,7 +8786,7 @@ dependencies = [ "rand", "slab", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.10", "tower-layer", "tower-service", "tracing", @@ -8546,8 +8804,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 0.2.9", - "http-body 0.4.5", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "httpdate", "iri-string", @@ -8556,12 +8814,12 @@ dependencies = [ "percent-encoding", "pin-project-lite", "tokio", - "tokio-util 0.7.9", + "tokio-util 0.7.10", "tower", "tower-layer", "tower-service", "tracing", - "uuid 1.4.1", + "uuid 1.8.0", ] [[package]] @@ -8578,11 +8836,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -8591,20 +8848,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -8622,12 +8879,12 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -8645,9 +8902,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "nu-ansi-term", "serde", @@ -8668,8 +8925,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b79e2e9c9ab44c6d7c20d5976961b47e8f49ac199154daa514b77cd1ab536625" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -8681,24 +8938,24 @@ checksum = "a7f741b240f1a48843f9b8e0444fb55fb2a4ff67293b50a9179dfd5ea67f8d41" [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.9", + "http 0.2.12", "httparse", "log", "rand", - "rustls 0.21.7", + "rustls 0.21.11", "sha1", "thiserror", "url", @@ -8774,9 +9031,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -8786,18 +9043,18 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" @@ -8839,11 +9096,17 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -8874,9 +9137,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.4.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "getrandom", "rand", @@ -8897,8 +9160,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d44690c645190cfce32f91a1582281654b2338c6073fa250b0949fd25c55b32" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -8918,7 +9181,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" dependencies = [ - "quote 1.0.33", + "quote 1.0.36", "syn 1.0.109", ] @@ -8944,7 +9207,7 @@ dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-multi-test", - "cw-storage-plus 1.1.0", + "cw-storage-plus 1.2.0", "error-stack", "integration-tests", "report", @@ -8965,9 +9228,9 @@ dependencies = [ [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -8988,11 +9251,17 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -9000,24 +9269,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.37" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -9027,38 +9296,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ - "quote 1.0.33", + "quote 1.0.36", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -9070,8 +9339,8 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -9085,18 +9354,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.3", -] - -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "which" @@ -9112,11 +9372,12 @@ dependencies = [ [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ - "wasm-bindgen", + "redox_syscall", + "wasite", "web-sys", ] @@ -9158,21 +9419,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -9185,18 +9437,12 @@ dependencies = [ ] [[package]] -name = "windows-targets" -version = "0.42.2" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.52.5", ] [[package]] @@ -9215,10 +9461,20 @@ dependencies = [ ] [[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" +name = "windows-targets" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] [[package]] name = "windows_aarch64_gnullvm" @@ -9227,10 +9483,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" +name = "windows_aarch64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -9239,10 +9495,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.42.2" +name = "windows_aarch64_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -9251,10 +9507,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.42.2" +name = "windows_i686_gnu" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -9263,10 +9525,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" +name = "windows_i686_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -9275,10 +9537,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" +name = "windows_x86_64_gnu" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -9287,10 +9549,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" +name = "windows_x86_64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -9298,11 +9560,26 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" -version = "0.5.15" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" dependencies = [ "memchr", ] @@ -9375,6 +9652,105 @@ dependencies = [ "time", ] +[[package]] +name = "xrpl-multisig-prover" +version = "0.1.0" +dependencies = [ + "anyhow", + "ascii", + "axelar-wasm-std", + "axelar-wasm-std-derive", + "bs58 0.5.1", + "connection-router-api", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "cw-storage-plus 1.2.0", + "cw-utils 1.0.3", + "elliptic-curve", + "error-stack", + "gateway", + "gateway-api", + "generic-array", + "hex", + "itertools 0.11.0", + "k256", + "monitoring", + "multisig", + "report", + "ripemd", + "serde_json", + "service-registry", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", + "voting-verifier", +] + +[[package]] +name = "xrpl_api" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4576f242134156dea2cf7ead1ea2e2efe890a4588d9b1564a5256f0ffb8f246" +dependencies = [ + "enumflags2", + "serde", + "serde_json", + "xrpl_types", +] + +[[package]] +name = "xrpl_binary_codec" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b963e7cacf52dec89c6333984dfee9d1495cfa5b65cb867846fd4582e09af59" +dependencies = [ + "ascii", + "bs58 0.5.1", + "enumflags2", + "hex", + "libsecp256k1", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "xrpl_types", +] + +[[package]] +name = "xrpl_http_client" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e60c050783dbb46974d508a45c4b292ecc2b8de0e4db11180a27de6d25581e" +dependencies = [ + "libsecp256k1", + "reqwest", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "tokio", + "tracing", + "xrpl_api", + "xrpl_binary_codec", + "xrpl_types", +] + +[[package]] +name = "xrpl_types" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d2955eacb8e921944c530d30daa941af3e93750b88d95dff3702dd9711f044b" +dependencies = [ + "ascii", + "bs58 0.5.1", + "enumflags2", + "hex", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "yaml-rust" version = "0.4.5" @@ -9399,11 +9775,31 @@ dependencies = [ "time", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -9414,9 +9810,9 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 2.0.37", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -9432,7 +9828,7 @@ dependencies = [ "crc32fast", "crossbeam-utils", "flate2", - "hmac", + "hmac 0.12.1", "pbkdf2 0.11.0", "sha1", "time", @@ -9460,11 +9856,10 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +version = "2.0.10+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" dependencies = [ "cc", - "libc", "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index ba0e51ce0a..c16254f548 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ axelar-wasm-std-derive = { version = "^0.1.0", path = "packages/axelar-wasm-std- integration-tests = { version = "^0.1.0", path = "integration-tests" } itertools = "0.11.0" voting-verifier = { version = "^0.1.0", path = "contracts/voting-verifier" } +xrpl-multisig-prover = { version = "^0.1.0", path = "contracts/xrpl-multisig-prover" } monitoring = { version = "^0.1.0", path = "contracts/monitoring" } multisig = { version = "^0.1.0", path = "contracts/multisig" } multisig-prover = { version = "^0.1.0", path = "contracts/multisig-prover" } diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index a838e34811..48c204a722 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -65,6 +65,8 @@ url = "2.3.1" valuable = { version = "0.1.0", features = ["derive"] } valuable-serde = { version = "0.1.0", features = ["std"] } voting-verifier = { workspace = true } +xrpl-multisig-prover = { workspace = true } +xrpl_http_client = { version = "0.15.0" } [dev-dependencies] elliptic-curve = "0.13.5" diff --git a/ampd/src/handlers/config.rs b/ampd/src/handlers/config.rs index 22a8a09bf4..fc6e52daa6 100644 --- a/ampd/src/handlers/config.rs +++ b/ampd/src/handlers/config.rs @@ -37,6 +37,10 @@ pub enum Config { MultisigSigner { cosmwasm_contract: TMAddress, }, + XRPLMultisigSigner { + multisig_prover_contract: TMAddress, + multisig_contract: TMAddress, + }, SuiMsgVerifier { cosmwasm_contract: TMAddress, rpc_url: Url, @@ -47,6 +51,11 @@ pub enum Config { rpc_url: Url, rpc_timeout: Option, }, + XRPLMsgVerifier { + cosmwasm_contract: TMAddress, + rpc_url: Url, + rpc_timeout: Option, + } } fn validate_multisig_signer_config<'de, D>(configs: &[Config]) -> Result<(), D::Error> diff --git a/ampd/src/handlers/errors.rs b/ampd/src/handlers/errors.rs index b926714f8d..905b99b8cd 100644 --- a/ampd/src/handlers/errors.rs +++ b/ampd/src/handlers/errors.rs @@ -12,4 +12,8 @@ pub enum Error { Sign, #[error("failed to get transaction receipts")] TxReceipts, + #[error("failed to parse public key")] + PublicKey, + #[error("failed to prepare message for signing")] + MessageToSign, } diff --git a/ampd/src/handlers/mod.rs b/ampd/src/handlers/mod.rs index e87db65734..016ccc3094 100644 --- a/ampd/src/handlers/mod.rs +++ b/ampd/src/handlers/mod.rs @@ -5,8 +5,10 @@ mod errors; pub mod evm_verify_msg; pub mod evm_verify_worker_set; pub mod multisig; +pub mod xrpl_multisig; pub mod sui_verify_msg; pub mod sui_verify_worker_set; +pub mod xrpl_verify_msg; #[cfg(test)] mod tests { diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 8a47e92f9c..ce17d6b6bd 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -1,7 +1,9 @@ use std::collections::HashMap; use std::convert::TryInto; +use std::str::FromStr; use async_trait::async_trait; +use connection_router_api::ChainName; use cosmrs::cosmwasm::MsgExecuteContract; use cosmwasm_std::{HexBinary, Uint64}; use ecdsa::VerifyingKey; @@ -34,6 +36,7 @@ struct SigningStartedEvent { #[serde(with = "hex")] msg: MessageDigest, expires_at: u64, + chain: ChainName, } fn deserialize_public_keys<'de, D>( @@ -139,6 +142,7 @@ where pub_keys, msg, expires_at, + chain, } = match event.try_into() as error_stack::Result<_, _> { Err(report) if matches!(report.current_context(), EventTypeMismatch(_)) => { return Ok(()); @@ -146,6 +150,14 @@ where result => result.change_context(DeserializeEvent)?, }; + if chain.eq(&ChainName::from_str("XRPL").unwrap()) { + info!( + session_id = session_id.to_string(), + "skipping XRP signing session" + ); + return Ok(()); + } + info!( session_id = session_id, msg = encode(&msg), diff --git a/ampd/src/handlers/xrpl_multisig.rs b/ampd/src/handlers/xrpl_multisig.rs new file mode 100644 index 0000000000..fda8c545b8 --- /dev/null +++ b/ampd/src/handlers/xrpl_multisig.rs @@ -0,0 +1,428 @@ +use std::collections::HashMap; +use std::convert::TryInto; + +use async_trait::async_trait; +use cosmrs::cosmwasm::MsgExecuteContract; +use cosmwasm_std::{HexBinary, Uint64}; +use ecdsa::VerifyingKey; +use error_stack::ResultExt; +use hex::encode; +use serde::de::Error as DeserializeError; +use serde::{Deserialize, Deserializer}; +use tokio::sync::watch::Receiver; +use tracing::info; + +use events::Error::EventTypeMismatch; +use events_derive; +use events_derive::try_from; +use multisig::msg::ExecuteMsg; +use crate::types::*; +use xrpl_multisig_prover::types::*; + +use crate::event_processor::EventHandler; +use crate::handlers::errors::Error::{self, DeserializeEvent}; +use crate::queue::queued_broadcaster::BroadcasterClient; +use crate::tofnd::grpc::SharableEcdsaClient; +use crate::tofnd::MessageDigest; + +#[derive(Debug, Deserialize)] +#[try_from("wasm-xrpl_signing_started")] +struct XRPLSigningStartedEvent { + session_id: u64, + #[serde(deserialize_with = "deserialize_public_keys")] + pub_keys: HashMap, + unsigned_tx: HexBinary, + expires_at: u64, +} + +fn deserialize_public_keys<'de, D>( + deserializer: D, +) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let keys_by_address: HashMap = + HashMap::deserialize(deserializer)?; + + keys_by_address + .into_iter() + .map(|(address, pk)| match pk { + multisig::key::PublicKey::Ecdsa(hex) => Ok(( + address, + VerifyingKey::from_sec1_bytes(hex.as_ref()) + .map_err(D::Error::custom)? + .into(), + )), + + multisig::key::PublicKey::Ed25519(hex) => { + let pk: cosmrs::tendermint::PublicKey = + cosmrs::tendermint::crypto::ed25519::VerificationKey::try_from(hex.as_ref()) + .map_err(D::Error::custom)? + .into(); + Ok((address, pk.into())) + } + }) + .collect() +} + +pub struct Handler +where + B: BroadcasterClient, +{ + worker: TMAddress, + multisig_prover: TMAddress, + multisig: TMAddress, + broadcaster: B, + signer: SharableEcdsaClient, + latest_block_height: Receiver, +} + +impl Handler +where + B: BroadcasterClient, +{ + pub fn new( + worker: TMAddress, + multisig: TMAddress, + multisig_prover: TMAddress, + broadcaster: B, + signer: SharableEcdsaClient, + latest_block_height: Receiver, + ) -> Self { + Self { + worker, + multisig, + multisig_prover, + broadcaster, + signer, + latest_block_height, + } + } + + async fn broadcast_signature( + &self, + session_id: impl Into, + signature: impl Into, + ) -> error_stack::Result<(), Error> { + let msg = serde_json::to_vec(&ExecuteMsg::SubmitSignature { + session_id: session_id.into(), + signature: signature.into(), + }) + .expect("submit signature msg should serialize"); + + let tx = MsgExecuteContract { + sender: self.worker.as_ref().clone(), + contract: self.multisig.as_ref().clone(), + msg, + funds: vec![], + }; + + self.broadcaster + .broadcast(tx) + .await + .change_context(Error::Broadcaster) + } +} + +#[async_trait] +impl EventHandler for Handler +where + B: BroadcasterClient + Send + Sync, +{ + type Err = Error; + + async fn handle(&self, event: &events::Event) -> error_stack::Result<(), Error> { + if !event.is_from_contract(self.multisig_prover.as_ref()) { + return Ok(()); + } + + let XRPLSigningStartedEvent { + session_id, + pub_keys, + unsigned_tx, + expires_at, + } = match event.try_into() as error_stack::Result<_, _> { + Err(report) if matches!(report.current_context(), EventTypeMismatch(_)) => { + return Ok(()); + } + result => result.change_context(DeserializeEvent)?, + }; + + info!( + session_id = session_id, + msg = encode(&unsigned_tx), + "get xrpl signing request", + ); + + let latest_block_height = *self.latest_block_height.borrow(); + if latest_block_height >= expires_at { + info!( + session_id = session_id.to_string(), + "skipping expired signing session" + ); + return Ok(()); + } + + match pub_keys.get(&self.worker) { + Some(pub_key) => { + let pub_key_hex = HexBinary::from(pub_key.to_bytes()); + let multisig_pub_key = multisig::key::PublicKey::try_from((multisig::key::KeyType::Ecdsa, pub_key_hex)).map_err(|_e| Error::PublicKey)?; + let xrpl_address = XRPLAccountId::from(&multisig_pub_key); + + let msg_digest = MessageDigest::from(xrpl_multisig_prover::xrpl_multisig::message_to_sign(&unsigned_tx, &xrpl_address).map_err(|_e| Error::MessageToSign)?); + + let signature = self + .signer + .sign(self.multisig.to_string().as_str(), msg_digest, pub_key) + .await + .change_context(Error::Sign)?; + + println!("signature: {:?}", signature); + + info!(signature = encode(&signature), "ready to submit signature"); + + self.broadcast_signature(session_id, signature).await?; + + Ok(()) + } + None => { + info!("worker is not a participant"); + Ok(()) + } + } + } +} + +#[cfg(test)] +mod test { + use std::collections::HashMap; + use std::convert::{TryFrom, TryInto}; + use std::time::Duration; + + use base64::engine::general_purpose::STANDARD; + use base64::Engine; + use cosmos_sdk_proto::cosmos::base::abci::v1beta1::TxResponse; + use cosmrs::{AccountId, Gas}; + use cosmwasm_std::{HexBinary, Uint64}; + use ecdsa::SigningKey; + use error_stack::{Report, Result}; + use rand::rngs::OsRng; + use tendermint::abci; + use tokio::sync::watch; + + use xrpl_multisig_prover::events::Event::XRPLSigningStarted; + use multisig::key::PublicKey; + + use crate::broadcaster::MockBroadcaster; + use crate::queue::queued_broadcaster::{QueuedBroadcaster, QueuedBroadcasterClient}; + use crate::tofnd; + use crate::tofnd::grpc::{MockEcdsaClient, SharableEcdsaClient}; + use crate::types; + + use super::*; + + const MULTISIG_PROVER_ADDRESS: &str = "axelarvaloper1zh9wrak6ke4n6fclj5e8yk397czv430ygs5jz7"; + + fn rand_account() -> TMAddress { + types::PublicKey::from(SigningKey::random(&mut OsRng).verifying_key()) + .account_id("axelar") + .unwrap() + .into() + } + + fn rand_public_key() -> multisig::key::PublicKey { + multisig::key::PublicKey::Ecdsa(HexBinary::from( + types::PublicKey::from(SigningKey::random(&mut OsRng).verifying_key()).to_bytes(), + )) + } + + fn rand_unsigned_tx() -> HexBinary { + let digest: [u8; 32] = rand::random(); + HexBinary::from(digest.as_slice()) + } + + fn signing_started_event() -> events::Event { + let pub_keys = (0..10) + .map(|_| (rand_account().to_string(), rand_public_key())) + .collect::>(); + + let poll_started = XRPLSigningStarted { + session_id: Uint64::one(), + worker_set_id: "worker_set_id".to_string(), + pub_keys, + unsigned_tx: rand_unsigned_tx(), + expires_at: 100u64, + }; + + let mut event: cosmwasm_std::Event = poll_started.into(); + event.ty = format!("wasm-{}", event.ty); + event = event.add_attribute("_contract_address", MULTISIG_PROVER_ADDRESS); + + events::Event::try_from(abci::Event::new( + event.ty, + event + .attributes + .into_iter() + .map(|cosmwasm_std::Attribute { key, value }| { + (STANDARD.encode(key), STANDARD.encode(value)) + }), + )) + .unwrap() + } + + fn get_handler( + worker: TMAddress, + multisig: TMAddress, + multisig_prover: TMAddress, + signer: SharableEcdsaClient, + latest_block_height: u64, + ) -> Handler { + let mut broadcaster = MockBroadcaster::new(); + broadcaster + .expect_broadcast() + .returning(|_| Ok(TxResponse::default())); + + let (broadcaster, _) = + QueuedBroadcaster::new(broadcaster, Gas::default(), 100, Duration::from_secs(5)); + + let (_tx, rx) = watch::channel(latest_block_height); + + Handler::new(worker, multisig, multisig_prover, broadcaster.client(), signer, rx) + } + + #[test] + fn should_not_deserialize_incorrect_event_type() { + // incorrect event type + let mut event: events::Event = signing_started_event(); + match event { + events::Event::Abci { + ref mut event_type, .. + } => { + *event_type = "incorrect".into(); + } + _ => panic!("incorrect event type"), + } + let event: Result = (&event).try_into(); + + assert!(matches!( + event.unwrap_err().current_context(), + events::Error::EventTypeMismatch(_) + )); + } + + #[test] + fn should_not_deserialize_invalid_pub_key() { + let mut event = signing_started_event(); + + let invalid_pub_key: [u8; 32] = rand::random(); + let mut map: HashMap = HashMap::new(); + map.insert( + rand_account().to_string(), + PublicKey::Ecdsa(HexBinary::from(invalid_pub_key.as_slice())), + ); + match event { + events::Event::Abci { + ref mut attributes, .. + } => { + attributes.insert("pub_keys".into(), serde_json::to_value(map).unwrap()); + } + _ => panic!("incorrect event type"), + } + + let event: Result = (&event).try_into(); + + assert!(matches!( + event.unwrap_err().current_context(), + events::Error::DeserializationFailed(_, _) + )); + } + + #[test] + fn should_deserialize_event() { + let event: Result = + (&signing_started_event()).try_into(); + + assert!(event.is_ok()); + } + + #[tokio::test] + async fn should_not_handle_event_if_multisig_prover_address_does_not_match() { + let mut client = MockEcdsaClient::new(); + client + .expect_sign() + .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + + let handler = get_handler( + rand_account(), + rand_account(), + rand_account(), + SharableEcdsaClient::new(client), + 100u64, + ); + + assert!(handler.handle(&signing_started_event()).await.is_ok()); + } + + #[tokio::test] + async fn should_not_handle_event_if_worker_is_not_a_participant() { + let mut client = MockEcdsaClient::new(); + client + .expect_sign() + .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + + let handler = get_handler( + rand_account(), + rand_account(), + TMAddress::from(MULTISIG_PROVER_ADDRESS.parse::().unwrap()), + SharableEcdsaClient::new(client), + 100u64, + ); + + assert!(handler.handle(&signing_started_event()).await.is_ok()); + } + + #[tokio::test] + async fn should_not_handle_event_if_sign_failed() { + let mut client = MockEcdsaClient::new(); + client + .expect_sign() + .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + + let event = signing_started_event(); + let signing_started: XRPLSigningStartedEvent = ((&event).try_into() as Result<_, _>).unwrap(); + let worker = signing_started.pub_keys.keys().next().unwrap().clone(); + let handler = get_handler( + worker, + rand_account(), + TMAddress::from(MULTISIG_PROVER_ADDRESS.parse::().unwrap()), + SharableEcdsaClient::new(client), + 99u64, + ); + + assert!(matches!( + *handler.handle(&event).await.unwrap_err().current_context(), + Error::Sign + )); + } + + #[tokio::test] + async fn should_not_handle_event_if_session_expired() { + let mut client = MockEcdsaClient::new(); + client + .expect_sign() + .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + + let event = signing_started_event(); + let signing_started: XRPLSigningStartedEvent = ((&event).try_into() as Result<_, _>).unwrap(); + let worker = signing_started.pub_keys.keys().next().unwrap().clone(); + let handler = get_handler( + worker, + rand_account(), + TMAddress::from(MULTISIG_PROVER_ADDRESS.parse::().unwrap()), + SharableEcdsaClient::new(client), + 101u64, + ); + + assert!(handler.handle(&signing_started_event()).await.is_ok()); + } +} diff --git a/ampd/src/handlers/xrpl_verify_msg.rs b/ampd/src/handlers/xrpl_verify_msg.rs new file mode 100644 index 0000000000..cbdd42d957 --- /dev/null +++ b/ampd/src/handlers/xrpl_verify_msg.rs @@ -0,0 +1,155 @@ +use std::collections::{HashMap, HashSet}; +use std::convert::TryInto; + +use async_trait::async_trait; +use cosmrs::cosmwasm::MsgExecuteContract; +use error_stack::ResultExt; +use serde::Deserialize; +use axelar_wasm_std::voting::{PollId, Vote}; +use tokio::sync::watch::Receiver; + +use events_derive::try_from; +use voting_verifier::msg::ExecuteMsg; +use events::{Error::EventTypeMismatch, Event}; +use tracing::info; + +use crate::event_processor::EventHandler; +use crate::handlers::errors::Error; +use crate::queue::queued_broadcaster::BroadcasterClient; +use crate::types::{Hash, TMAddress}; +use crate::xrpl::json_rpc::XRPLClient; +use crate::xrpl::verifier::verify_message; +use crate::xrpl::types::{TransactionId, XRPLAddress}; + +type Result = error_stack::Result; + +#[derive(Deserialize, Debug)] +pub struct Message { + pub tx_id: TransactionId, + pub event_index: u64, + pub destination_address: String, + pub destination_chain: connection_router_api::ChainName, + pub source_address: XRPLAddress, + pub payload_hash: Hash, +} + +#[derive(Deserialize, Debug)] +#[try_from("wasm-messages_poll_started")] +struct PollStartedEvent { + poll_id: PollId, + source_gateway_address: XRPLAddress, + messages: Vec, + participants: Vec, + expires_at: u64, +} + +pub struct Handler +where + C: XRPLClient, + B: BroadcasterClient, +{ + worker: TMAddress, + voting_verifier: TMAddress, + rpc_client: C, + broadcast_client: B, + latest_block_height: Receiver, +} + +impl Handler +where + C: XRPLClient, + B: BroadcasterClient, +{ + pub fn new( + worker: TMAddress, + voting_verifier: TMAddress, + rpc_client: C, + broadcast_client: B, + latest_block_height: Receiver, + ) -> Self { + Self { + worker, + voting_verifier, + rpc_client, + broadcast_client, + latest_block_height, + } + } + async fn broadcast_votes(&self, poll_id: PollId, votes: Vec) -> Result<()> { + let msg = serde_json::to_vec(&ExecuteMsg::Vote { poll_id, votes }) + .expect("vote msg should serialize"); + let tx = MsgExecuteContract { + sender: self.worker.as_ref().clone(), + contract: self.voting_verifier.as_ref().clone(), + msg, + funds: vec![], + }; + + self.broadcast_client + .broadcast(tx) + .await + .change_context(Error::Broadcaster) + } +} + +#[async_trait] +impl EventHandler for Handler +where + C: XRPLClient + Send + Sync, + B: BroadcasterClient + Send + Sync, +{ + type Err = Error; + + async fn handle(&self, event: &Event) -> Result<()> { + if !event.is_from_contract(self.voting_verifier.as_ref()) { + return Ok(()); + } + + let PollStartedEvent { + poll_id, + source_gateway_address, + messages, + participants, + expires_at, + } = match event.try_into() as error_stack::Result<_, _> { + Err(report) if matches!(report.current_context(), EventTypeMismatch(_)) => { + return Ok(()); + } + event => event.change_context(Error::DeserializeEvent)?, + }; + + if !participants.contains(&self.worker) { + return Ok(()); + } + + let latest_block_height = *self.latest_block_height.borrow(); + if latest_block_height >= expires_at { + info!(poll_id = poll_id.to_string(), "skipping expired poll"); + return Ok(()); + } + + // Does not assume voting verifier emits unique tx ids. + // RPC will throw an error if the input contains any duplicate, deduplicate tx ids to avoid unnecessary failures. + let deduplicated_tx_ids: HashSet<_> = messages.iter().map(|msg| msg.tx_id.clone()).collect(); + + let mut tx_responses = HashMap::new(); + + for tx_id in deduplicated_tx_ids { + match self.rpc_client.fetch_tx(&tx_id).await { + Ok(res) => { tx_responses.insert(tx_id, res); }, + Err(e) => return Err(e.change_context(Error::TxReceipts)) + } + } + + let votes: Vec<_> = messages + .iter() + .map(|msg| tx_responses + .get(&msg.tx_id) + .and_then(|tx_response| tx_response.as_ref().map(|tx| verify_message(&source_gateway_address, &tx.tx, msg))) + .unwrap_or(Vote::NotFound) + ) + .collect(); + + self.broadcast_votes(poll_id, votes).await + } +} \ No newline at end of file diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index df1e861428..d93b7f57f3 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -47,6 +47,7 @@ mod tm_client; mod tofnd; mod types; mod url; +mod xrpl; const PREFIX: &str = "axelar"; const DEFAULT_RPC_TIMEOUT: Duration = Duration::from_secs(3); @@ -296,6 +297,19 @@ where ), stream_timeout, ), + handlers::config::Config::XRPLMultisigSigner { multisig_contract, multisig_prover_contract } => self + .create_handler_task( + "xrpl-multisig-signer", + handlers::xrpl_multisig::Handler::new( + worker.clone(), + multisig_contract, + multisig_prover_contract, + self.broadcaster.client(), + self.ecdsa_client.clone(), + self.block_height_monitor.latest_block_height(), + ), + stream_timeout, + ), handlers::config::Config::SuiMsgVerifier { cosmwasm_contract, rpc_url, @@ -318,6 +332,29 @@ where ), stream_timeout, ), + handlers::config::Config::XRPLMsgVerifier { + cosmwasm_contract, + rpc_url, + rpc_timeout + } => self.create_handler_task( + "xrpl-msg-verifier", + handlers::xrpl_verify_msg::Handler::new( + worker.clone(), + cosmwasm_contract, + xrpl_http_client::Client::builder() + .base_url(rpc_url.as_str()) + .http_client( + reqwest::ClientBuilder::new() + .connect_timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) + .timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) + .build() + .change_context(Error::Connection)?, + ).build(), + self.broadcaster.client(), + self.block_height_monitor.latest_block_height(), + ), + stream_timeout, + ), handlers::config::Config::SuiWorkerSetVerifier { cosmwasm_contract, rpc_url, diff --git a/ampd/src/xrpl/json_rpc.rs b/ampd/src/xrpl/json_rpc.rs new file mode 100644 index 0000000000..ee524c703f --- /dev/null +++ b/ampd/src/xrpl/json_rpc.rs @@ -0,0 +1,26 @@ +use async_trait::async_trait; +use mockall::automock; +use crate::xrpl::types::TransactionId; +use xrpl_http_client::{TxRequest, TxResponse, Client, error}; + +type Result = error_stack::Result; + +#[automock] +#[async_trait] +pub trait XRPLClient { + async fn fetch_tx( + &self, + tx_id: &TransactionId, + ) -> Result>; +} + +#[async_trait] +impl XRPLClient for Client { + async fn fetch_tx(&self, tx_id: &TransactionId) -> Result> { + let req = TxRequest::new(tx_id.as_str()); + self.call(req).await.map(Some).or_else(|err| match err { + error::Error::Api(reason) if reason == "txnNotFound" => Ok(None), + _ => Err(err.into()), + }) + } +} diff --git a/ampd/src/xrpl/mod.rs b/ampd/src/xrpl/mod.rs new file mode 100644 index 0000000000..8f5e702c45 --- /dev/null +++ b/ampd/src/xrpl/mod.rs @@ -0,0 +1,3 @@ +pub mod types; +pub mod verifier; +pub mod json_rpc; \ No newline at end of file diff --git a/ampd/src/xrpl/types.rs b/ampd/src/xrpl/types.rs new file mode 100644 index 0000000000..0e9399a4c8 --- /dev/null +++ b/ampd/src/xrpl/types.rs @@ -0,0 +1,13 @@ +use serde::Deserialize; + +#[derive(Deserialize, Debug, PartialEq, Eq, Hash, Clone)] +pub struct TransactionId(pub String); + +impl TransactionId { + pub fn as_str(&self) -> &str { + return self.0.as_str(); + } +} + +#[derive(Deserialize, Debug, PartialEq)] +pub struct XRPLAddress(pub String); \ No newline at end of file diff --git a/ampd/src/xrpl/verifier.rs b/ampd/src/xrpl/verifier.rs new file mode 100644 index 0000000000..1c029b3708 --- /dev/null +++ b/ampd/src/xrpl/verifier.rs @@ -0,0 +1,136 @@ +use std::collections::HashMap; +use std::str::FromStr; + +use serde::Serialize; +use connection_router_api::ChainName; +use xrpl_http_client::{Amount, ResultCategory}; +use xrpl_http_client::{Memo, Transaction::Payment, Transaction}; +use axelar_wasm_std::voting::Vote; +use cosmwasm_std::{Uint256, HexBinary}; + +use crate::handlers::xrpl_verify_msg::Message; +use crate::xrpl::types::XRPLAddress; + +pub fn verify_message( + multisig_address: &XRPLAddress, + tx: &Transaction, + message: &Message, +) -> Vote { + if message.event_index == 0 && is_validated_tx(tx) && (is_valid_multisig_tx(tx, multisig_address, message) || is_valid_deposit_tx(tx, multisig_address, message)) { + if is_successful_tx(tx) { + Vote::SucceededOnChain + } else { + Vote::FailedOnChain + } + } else { + Vote::NotFound + } +} + +pub fn is_validated_tx(tx: &Transaction) -> bool { + matches!(tx.common().validated, Some(true)) +} + +pub fn is_valid_multisig_tx(tx: &Transaction, multisig_address: &XRPLAddress, message: &Message) -> bool { + tx.common().account == multisig_address.0 && message.source_address == *multisig_address && message.destination_chain == ChainName::from_str("XRPL").unwrap() +} + +pub fn is_valid_deposit_tx(tx: &Transaction, multisig_address: &XRPLAddress, message: &Message) -> bool { + if let Payment(payment_tx) = &tx { + if let Some(memos) = payment_tx.clone().common.memos { + return payment_tx.destination == multisig_address.0 && message.source_address.0 == tx.common().account && verify_memos(payment_tx.amount.clone(), memos, message); + } + } + return false; +} + +pub fn is_successful_tx(tx: &Transaction) -> bool { + if let Some(meta) = &tx.common().meta { + return meta.transaction_result.category() == ResultCategory::Tes; + } + return false; +} + +#[derive(Serialize, Debug, PartialEq)] +struct MemoPayload { + fee: Uint256, + relayer: String, + amount: Uint256, + currency: String, + payload_hash: HexBinary +} + +fn remove_0x_prefix(s: String) -> String { + if s.starts_with("0x") { + s[2..].to_string() + } else { + s + } +} + +pub fn verify_memos(amount: Amount, memos: Vec, message: &Message) -> bool { + let memo_kv: HashMap = memos + .into_iter() + .filter(|m| m.memo_type.is_some() && m.memo_data.is_some()) + .map(|m| (String::from_utf8(hex::decode(m.memo_type.unwrap()).unwrap()).unwrap(), m.memo_data.unwrap())) + .collect(); + + || -> Option { + let (token , amount) = match amount { + Amount::Issued(a) => (a.currency, a.value), + Amount::Drops(a) => ("XRP".to_string(), a), + }; + + let expected_payload = ethers::abi::encode(&vec![ + ethers::abi::Token::String(token), + ethers::abi::Token::Uint(ethers::types::U256::from_dec_str(amount.as_ref()).ok()?), + ethers::abi::Token::FixedBytes(hex::decode(remove_0x_prefix(memo_kv.get("payload_hash")?.clone())).ok()?), + ]); + let expected_payload_hash = ethers::utils::keccak256(expected_payload.clone()); + + Some(memo_kv.get("destination_address") == Some(&remove_0x_prefix(message.destination_address.clone()).to_uppercase()) + && memo_kv.get("destination_chain") == Some(&hex::encode_upper(message.destination_chain.to_string())) + && *message.payload_hash.to_fixed_bytes().to_vec() == expected_payload_hash) + }().unwrap_or(false) +} + +#[cfg(test)] +mod test { + use std::str::FromStr; + + use crate::xrpl::{types::XRPLAddress, verifier::verify_memos}; + use ethers::types::TxHash; + use xrpl_http_client::{Amount, Memo}; + use crate::handlers::xrpl_verify_msg::Message; + use connection_router_api::ChainName; + + #[test] + fn test_verify_memos() { + let memos = vec![ + Memo { + memo_type: Some("64657374696E6174696F6E5F61646472657373".to_string()), + memo_data: Some("592639C10223C4EC6C0FFC670E94D289A25DD1AD".to_string()), + memo_format: None + }, + Memo { + memo_type: Some("64657374696E6174696F6E5F636861696E".to_string()), + memo_data: Some("657468657265756D".to_string()), + memo_format: None + }, + Memo { + memo_type: Some("7061796C6F61645F68617368".to_string()), + memo_data: Some("4F246000525114CC0CC261973D12E9A1C53B7AA295DF41FA6A6BFD00045BF0E6".to_string()), + memo_format: None + } + ]; + let message = Message { + tx_id: crate::xrpl::types::TransactionId("1c6019555252bcb7bca95237d333a6c473112d6396d4f151a4a1c1f00f04f8f3".to_string()), + event_index: 14, + source_address: XRPLAddress("raNVNWvhUQzFkDDTdEw3roXRJfMJFVJuQo".to_string()), + destination_address: "0x592639c10223C4EC6C0ffc670e94d289A25DD1ad".to_string(), + destination_chain: ChainName::from_str("ethereum").unwrap(), + payload_hash: TxHash(hex::decode("feb30b51f41e4785664824dd0ee694e0d275757753f570e9f6b5e27d06197fa7").unwrap().to_vec().try_into().unwrap()) + }; + assert!(verify_memos(Amount::Drops("1000000".to_string()), memos, &message)); + } +} diff --git a/contracts/multisig-prover/src/test/mocks/multisig.rs b/contracts/multisig-prover/src/test/mocks/multisig.rs index 3d1db1eeea..acd9c3e95b 100644 --- a/contracts/multisig-prover/src/test/mocks/multisig.rs +++ b/contracts/multisig-prover/src/test/mocks/multisig.rs @@ -123,6 +123,7 @@ mod query { state: MultisigState::Completed { completed_at: 12345, }, + expires_at: 23456, quorum, signers, } diff --git a/contracts/multisig/src/contract/query.rs b/contracts/multisig/src/contract/query.rs index 7e5d88a277..33c66d7cf6 100644 --- a/contracts/multisig/src/contract/query.rs +++ b/contracts/multisig/src/contract/query.rs @@ -20,6 +20,7 @@ pub fn get_multisig(deps: Deps, session_id: Uint64) -> StdResult { Ok(Multisig { state: session.state, + expires_at: session.expires_at, quorum: worker_set.threshold, signers: signers_with_sigs, }) diff --git a/contracts/multisig/src/msg.rs b/contracts/multisig/src/msg.rs index 04f036fce1..899ac49aa6 100644 --- a/contracts/multisig/src/msg.rs +++ b/contracts/multisig/src/msg.rs @@ -81,6 +81,7 @@ pub struct Signer { #[cw_serde] pub struct Multisig { pub state: MultisigState, + pub expires_at: u64, pub quorum: Uint256, pub signers: Vec<(Signer, Option)>, } diff --git a/contracts/voting-verifier/src/events.rs b/contracts/voting-verifier/src/events.rs index 510da63da7..37f1f5e165 100644 --- a/contracts/voting-verifier/src/events.rs +++ b/contracts/voting-verifier/src/events.rs @@ -162,7 +162,7 @@ impl TryFrom for TxEventConfirmation { } } -fn parse_message_id( +pub fn parse_message_id( message_id: &nonempty::String, ) -> Result<(nonempty::String, u32), ContractError> { // expected format: : diff --git a/contracts/xrpl-multisig-prover/Cargo.toml b/contracts/xrpl-multisig-prover/Cargo.toml new file mode 100644 index 0000000000..5d06bac5d6 --- /dev/null +++ b/contracts/xrpl-multisig-prover/Cargo.toml @@ -0,0 +1,61 @@ +[package] +name = "xrpl-multisig-prover" +version = "0.1.0" +edition = "2021" +description = "XRPL multisig prover contract" + +exclude = [ + # Those files are rust-optimizer artifacts. You might want to commit them for convenience but they should not be part of the source code publication. + "contract.wasm", + "hash.txt", +] +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] + +[package.metadata.scripts] +optimize = """docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.6 +""" + +[dependencies] +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +axelar-wasm-std = { workspace = true } +axelar-wasm-std-derive = { workspace = true } +cw-storage-plus = { workspace = true } +connection-router-api = { workspace = true } +service-registry = { workspace = true } +multisig = { workspace = true, features = ["library"] } +gateway = { workspace = true } +gateway-api = { workspace = true } +monitoring = { workspace = true } +thiserror = { workspace = true } +error-stack = { workspace = true } +report = { workspace = true } +serde_json = "1.0.89" +sha2 = { version = "0.10.7" } +sha3 = { workspace = true } +cw-utils = "1.0.1" +bs58 = "0.5.0" +ripemd = "0.1.3" +hex = { version = "0.4.3", default-features = false, features = [] } +voting-verifier = { workspace = true, features = ["library"] } +k256 = { version = "0.13.1", features = ["ecdsa"] } +ascii = { version = "1.1.0", features = ["serde"] } +itertools = "0.11.0" + +[dev-dependencies] +anyhow = "1.0" +cw-multi-test = "0.15.1" +elliptic-curve = "0.13.5" +generic-array = "0.14.7" diff --git a/contracts/xrpl-multisig-prover/src/axelar_workers.rs b/contracts/xrpl-multisig-prover/src/axelar_workers.rs new file mode 100644 index 0000000000..000d95177e --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/axelar_workers.rs @@ -0,0 +1,232 @@ +use itertools::Itertools; +use std::collections::hash_map::RandomState; +use std::collections::{BTreeMap, BTreeSet, HashMap}; + +use axelar_wasm_std::Participant; +use axelar_wasm_std::{nonempty, MajorityThreshold}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Fraction, HexBinary, Uint256}; +use multisig::{ + key::{KeyType, PublicKey}, + msg::Signer, +}; +use service_registry::state::WeightedWorker; + +use crate::error::ContractError; +use crate::querier::Querier; + +#[cw_serde] +#[derive(Eq, Ord, PartialOrd)] +pub struct AxelarSigner { + pub address: Addr, + pub weight: u16, + pub pub_key: PublicKey, +} + +impl From for Participant { + fn from(signer: AxelarSigner) -> Self { + let weight = nonempty::Uint256::try_from(Uint256::from(u128::from(signer.weight))).unwrap(); + Self { + address: signer.address, + weight, + } + } +} + +#[cw_serde] +pub struct WorkerSet { + pub signers: BTreeSet, + pub quorum: u32, + // for hash uniqueness. The same exact worker set could be in use at two different times, + // and we need to be able to distinguish between the two + pub created_at: u64, +} + +impl From for multisig::worker_set::WorkerSet { + fn from(worker_set: WorkerSet) -> Self { + let participants = worker_set + .signers + .into_iter() + .map(|s| (s.clone().into(), s.pub_key)) + .collect(); + multisig::worker_set::WorkerSet::new( + participants, + Uint256::from(u128::from(worker_set.quorum)), + worker_set.created_at, + ) + } +} + +impl WorkerSet { + pub fn pub_keys_by_address(&self) -> HashMap { + self.signers + .iter() + .map(|signer| { + ( + signer.address.to_string(), + (KeyType::Ecdsa, signer.pub_key.as_ref().into()), + ) + }) + .collect() + } +} + +fn convert_uint256_to_u16(value: Uint256) -> Result { + if value > Uint256::from(u16::MAX) { + return Err(ContractError::GenericError( + "Overflow, cannot convert value to u16".to_owned(), + )); + } + let bytes = value.to_le_bytes(); + Ok(u16::from(bytes[0]) | u16::from(bytes[1]).checked_shl(8).unwrap()) // this unwrap is never supposed to fail +} + +// Converts a Vec to Vec, scaling down with precision loss, if necessary. +// We make sure that XRPL multisig and Axelar multisig both use the same scaled down numbers and have the same precision loss +fn convert_or_scale_weights(weights: &[Uint256]) -> Result, ContractError> { + let max_weight: Option<&Uint256> = weights.iter().max(); + match max_weight { + Some(max_weight) => { + let max_u16_as_uint256 = Uint256::from(u16::MAX); + let mut result = Vec::with_capacity(weights.len()); + for &weight in weights.iter() { + let scaled = weight.multiply_ratio(max_u16_as_uint256, *max_weight); + result.push(convert_uint256_to_u16(scaled)?); + } + + Ok(result) + } + None => Ok(vec![]), + } +} + +pub fn get_active_worker_set( + querier: &Querier, + signing_threshold: MajorityThreshold, + block_height: u64, +) -> Result { + let workers: Vec = querier.get_active_workers()?; + + let participants: Vec = workers + .into_iter() + .map(Participant::try_from) + .filter_map(|result| result.ok()) + .collect(); + + let weights = convert_or_scale_weights( + participants + .iter() + .map(|participant| Uint256::from(participant.weight)) + .collect::>() + .as_slice(), + )?; + + let mut signers: Vec = vec![]; + for (i, participant) in participants.iter().enumerate() { + let pub_key: PublicKey = querier.get_public_key(participant.address.to_string())?; + signers.push(AxelarSigner { + address: participant.address.clone(), + weight: weights[i], + pub_key, + }); + } + + let sum_of_weights: u32 = weights.iter().map(|w| u32::from(*w)).sum(); + + let quorum = u32::try_from( + u64::from(sum_of_weights) + .checked_mul(signing_threshold.numerator().into()) + .unwrap() + .checked_div(signing_threshold.denominator().into()) + .unwrap(), + ) + .unwrap(); + + let worker_set = WorkerSet { + signers: BTreeSet::from_iter(signers), + quorum, + created_at: block_height, + }; + + Ok(worker_set) +} + +pub fn should_update_worker_set( + new_workers: &multisig::worker_set::WorkerSet, + cur_workers: &multisig::worker_set::WorkerSet, + max_diff: usize, +) -> bool { + new_workers.threshold != cur_workers.threshold + || signers_symetric_difference_count(&new_workers.signers, &cur_workers.signers) > max_diff +} + +fn signers_symetric_difference_count( + s1: &BTreeMap, + s2: &BTreeMap, +) -> usize { + signers_difference_count(s1, s2).saturating_add(signers_difference_count(s2, s1)) +} + +fn signers_difference_count(s1: &BTreeMap, s2: &BTreeMap) -> usize { + s1.values().filter(|v| !s2.values().contains(v)).count() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_convert_or_scale_weights() { + let weights = vec![Uint256::from(1u128), Uint256::from(1u128)]; + let scaled_weights = convert_or_scale_weights(&weights).unwrap(); + assert_eq!(scaled_weights, vec![65535, 65535]); + + let weights = vec![ + Uint256::from(1u128), + Uint256::from(2u128), + Uint256::from(3u128), + ]; + let scaled_weights = convert_or_scale_weights(&weights).unwrap(); + assert_eq!(scaled_weights, vec![21845, 43690, 65535]); + + let weights = vec![ + Uint256::from(1u128), + Uint256::from(2u128), + Uint256::from(3u128), + Uint256::from(4u128), + ]; + let scaled_weights = convert_or_scale_weights(&weights).unwrap(); + assert_eq!(scaled_weights, vec![16383, 32767, 49151, 65535]); + + let weights = vec![ + Uint256::MAX - Uint256::from(3u128), + Uint256::MAX - Uint256::from(2u128), + Uint256::MAX - Uint256::from(1u128), + Uint256::MAX, + ]; + let scaled_weights = convert_or_scale_weights(&weights).unwrap(); + assert_eq!(scaled_weights, vec![65534, 65534, 65534, 65535]); + + let weights = vec![ + Uint256::from(0u128), + Uint256::from(1u128), + Uint256::MAX - Uint256::from(1u128), + Uint256::MAX, + ]; + let scaled_weights = convert_or_scale_weights(&weights).unwrap(); + assert_eq!(scaled_weights, vec![0, 0, 65534, 65535]); + + let weights = vec![ + Uint256::from(100000u128), + Uint256::from(2000000u128), + Uint256::from(30000000u128), + Uint256::from(400000000u128), + Uint256::from(50000000000u128), + ]; + let scaled_weights = convert_or_scale_weights(&weights).unwrap(); + assert_eq!(scaled_weights, vec![0, 2, 39, 524, 65535]); + + let scaled_weights = convert_or_scale_weights(&vec![]).unwrap(); + assert_eq!(scaled_weights, vec![] as Vec); + } +} diff --git a/contracts/xrpl-multisig-prover/src/bin/schema.rs b/contracts/xrpl-multisig-prover/src/bin/schema.rs new file mode 100644 index 0000000000..9110f958c0 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/bin/schema.rs @@ -0,0 +1,11 @@ +use cosmwasm_schema::write_api; + +use xrpl_multisig_prover::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } +} diff --git a/contracts/xrpl-multisig-prover/src/contract.rs b/contracts/xrpl-multisig-prover/src/contract.rs new file mode 100644 index 0000000000..ac57f4389a --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/contract.rs @@ -0,0 +1,471 @@ +use std::str::FromStr; + +#[cfg(not(feature = "library"))] +use axelar_wasm_std::{MajorityThreshold, VerificationStatus}; +use connection_router_api::{Address, ChainName, CrossChainId, Message}; +use cosmwasm_std::{ + entry_point, to_json_binary, wasm_execute, Addr, Binary, Deps, DepsMut, Env, Fraction, + HexBinary, MessageInfo, Reply, Response, StdResult, Storage, SubMsg, Uint64, +}; +// TODO: create custom message ID format +use voting_verifier::events::parse_message_id; + +use multisig::{key::PublicKey, types::MultisigState}; + +use crate::{ + axelar_workers, + error::ContractError, + msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}, + querier::{Querier, XRPL_CHAIN_NAME}, + query, reply, + state::{ + Config, AVAILABLE_TICKETS, CONFIG, CURRENT_WORKER_SET, LAST_ASSIGNED_TICKET_NUMBER, + MESSAGE_ID_TO_MULTISIG_SESSION_ID, MULTISIG_SESSION_ID_TO_TX_HASH, NEXT_SEQUENCE_NUMBER, + NEXT_WORKER_SET, REPLY_MESSAGE_ID, REPLY_TX_HASH, TOKENS, TRANSACTION_INFO, + }, + types::*, + xrpl_multisig, + xrpl_serialize::XRPLSerialize, +}; + +pub const START_MULTISIG_REPLY_ID: u64 = 1; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + let config = make_config(&deps, msg.clone())?; + CONFIG.save(deps.storage, &config)?; + + NEXT_SEQUENCE_NUMBER.save(deps.storage, &msg.next_sequence_number)?; + LAST_ASSIGNED_TICKET_NUMBER.save(deps.storage, &msg.last_assigned_ticket_number)?; + AVAILABLE_TICKETS.save(deps.storage, &msg.available_tickets)?; + + let querier = Querier::new(deps.querier, config.clone()); + let new_worker_set = + axelar_workers::get_active_worker_set(&querier, msg.signing_threshold, env.block.height)?; + + CURRENT_WORKER_SET.save(deps.storage, &new_worker_set.clone())?; + + Ok(Response::new() + .add_message(wasm_execute( + config.axelar_multisig, + &multisig::msg::ExecuteMsg::RegisterWorkerSet { + worker_set: new_worker_set.clone().into(), + }, + vec![], + )?) + .add_message(wasm_execute( + config.monitoring, + &monitoring::msg::ExecuteMsg::SetActiveVerifiers { + next_worker_set: new_worker_set.into(), + }, + vec![], + )?)) +} + +fn make_config( + deps: &DepsMut, + msg: InstantiateMsg, +) -> Result { + let admin = deps.api.addr_validate(&msg.admin_address)?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + let relayer = deps.api.addr_validate(&msg.relayer_address)?; + let axelar_multisig = deps.api.addr_validate(&msg.axelar_multisig_address)?; + let monitoring = deps.api.addr_validate(&msg.monitoring_address)?; + let gateway = deps.api.addr_validate(&msg.gateway_address)?; + let voting_verifier = deps.api.addr_validate(&msg.voting_verifier_address)?; + let service_registry = deps.api.addr_validate(&msg.service_registry_address)?; + + if msg.signing_threshold.numerator() > u32::MAX.into() + || msg.signing_threshold.denominator() == Uint64::zero() + { + return Err(ContractError::InvalidSigningThreshold.into()); + } + + Ok(Config { + admin, + governance, + relayer, + axelar_multisig, + monitoring, + gateway, + xrpl_multisig: msg.xrpl_multisig_address, + signing_threshold: msg.signing_threshold, + voting_verifier, + service_registry, + service_name: msg.service_name, + worker_set_diff_threshold: msg.worker_set_diff_threshold, + xrpl_fee: msg.xrpl_fee, + ticket_count_threshold: msg.ticket_count_threshold, + key_type: multisig::key::KeyType::Ecdsa, + xrp_denom: msg.xrp_denom, + }) +} + +pub fn require_admin(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { + match CONFIG.load(deps.storage)?.admin { + admin if admin == info.sender => Ok(()), + _ => Err(ContractError::Unauthorized), + } +} + +pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { + match CONFIG.load(deps.storage)?.governance { + governance if governance == info.sender => Ok(()), + _ => Err(ContractError::Unauthorized), + } +} + +pub fn require_permissioned_relayer( + deps: &DepsMut, + info: MessageInfo, +) -> Result<(), ContractError> { + match CONFIG.load(deps.storage)?.relayer { + governance if governance == info.sender => Ok(()), + _ => Err(ContractError::Unauthorized), + } +} + +fn register_token( + storage: &mut dyn Storage, + denom: String, + token: &XRPLToken, + decimals: u8, +) -> Result { + TOKENS.save(storage, &denom, &(token.clone(), decimals))?; + Ok(Response::default()) +} + +pub fn update_signing_threshold( + deps: DepsMut, + new_signing_threshold: MajorityThreshold, +) -> Result { + CONFIG.update( + deps.storage, + |mut config| -> Result { + config.signing_threshold = new_signing_threshold; + Ok(config) + }, + )?; + Ok(Response::new()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let config = CONFIG.load(deps.storage)?; + let querier = Querier::new(deps.querier, config.clone()); + + let res = match msg { + ExecuteMsg::RegisterToken { + denom, + token, + decimals, + } => { + require_admin(&deps, info.clone()) + .or_else(|_| require_governance(&deps, info.clone()))?; + register_token(deps.storage, denom, &token, decimals) + } + // TODO: coin should be info.funds + ExecuteMsg::ConstructProof { message_id, coin } => { + require_permissioned_relayer(&deps, info)?; + construct_payment_proof( + deps.storage, + &querier, + env.contract.address, + env.block.height, + &config, + message_id, + &coin, + ) + } + ExecuteMsg::UpdateWorkerSet {} => { + require_admin(&deps, info.clone()).or_else(|_| require_governance(&deps, info))?; + construct_signer_list_set_proof(deps.storage, &querier, env, &config) + } + ExecuteMsg::UpdateTxStatus { + multisig_session_id, + signer_public_keys, + message_id, + message_status, + } => update_tx_status( + deps.storage, + &querier, + &config, + &multisig_session_id, + &signer_public_keys, + &message_id, + message_status, + ), + ExecuteMsg::TicketCreate {} => { + construct_ticket_create_proof(deps.storage, env.contract.address, &config) + } + ExecuteMsg::UpdateSigningThreshold { + new_signing_threshold, + } => { + require_governance(&deps, info)?; + update_signing_threshold(deps, new_signing_threshold) + } + }?; + + Ok(res) +} + +fn construct_payment_proof( + storage: &mut dyn Storage, + querier: &Querier, + self_address: Addr, + block_height: u64, + config: &Config, + message_id: CrossChainId, + coin: &cosmwasm_std::Coin, +) -> Result { + // if info.funds.len() != 1 { + if coin.amount == cosmwasm_std::Uint128::zero() { + return Err(ContractError::InvalidPaymentAmount); + } + + // Prevent creating a duplicate signing session before the previous one expires + if let Some(multisig_session_id) = + MESSAGE_ID_TO_MULTISIG_SESSION_ID.may_load(storage, &message_id)? + { + let multisig_session = querier.get_multisig_session(&Uint64::from(multisig_session_id))?; + if multisig_session.state == MultisigState::Pending + && multisig_session.expires_at <= block_height + { + return Err(ContractError::PaymentAlreadyHasActiveSigningSession( + multisig_session_id, + )); + } + }; + + let message = querier.get_message(&message_id)?; + let xrpl_payment_amount = if coin.denom == config.xrp_denom { + let drops = + u64::try_from(coin.amount.u128()).map_err(|_| ContractError::InvalidAmount { + reason: "overflow".to_string(), + })?; + XRPLPaymentAmount::Drops(drops) + } else { + let (xrpl_token, decimals) = TOKENS.load(storage, &coin.denom)?; + // TODO: handle decimal precision conversion between CosmWasm Coin and XRPLToken + XRPLPaymentAmount::Token(xrpl_token, canonicalize_coin_amount(coin.amount, decimals)?) + }; + + let tx_hash = xrpl_multisig::issue_payment( + storage, + config, + message.destination_address.to_string().try_into()?, + &xrpl_payment_amount, + &message_id, + )?; + + REPLY_MESSAGE_ID.save(storage, &message_id)?; + start_signing_session(storage, config, tx_hash, self_address) +} + +pub fn start_signing_session( + storage: &mut dyn Storage, + config: &Config, + tx_hash: TxHash, + self_address: Addr, +) -> Result { + REPLY_TX_HASH.save(storage, &tx_hash)?; + let cur_worker_set_id = match CURRENT_WORKER_SET.may_load(storage)? { + Some(worker_set) => Into::::into(worker_set).id(), + None => { + return Err(ContractError::NoWorkerSet); + } + }; + + let start_sig_msg: multisig::msg::ExecuteMsg = multisig::msg::ExecuteMsg::StartSigningSession { + worker_set_id: cur_worker_set_id, + chain_name: ChainName::from_str(XRPL_CHAIN_NAME).unwrap(), + msg: tx_hash.into(), + sig_verifier: Some(self_address.into()), + }; + + let wasm_msg = wasm_execute(&config.axelar_multisig, &start_sig_msg, vec![])?; + + Ok(Response::new().add_submessage(SubMsg::reply_on_success(wasm_msg, START_MULTISIG_REPLY_ID))) +} + +fn construct_signer_list_set_proof( + storage: &mut dyn Storage, + querier: &Querier, + env: Env, + config: &Config, +) -> Result { + if !CURRENT_WORKER_SET.exists(storage) { + return Err(ContractError::WorkerSetIsNotSet); + } + + let new_worker_set = + axelar_workers::get_active_worker_set(querier, config.signing_threshold, env.block.height)?; + let cur_worker_set = CURRENT_WORKER_SET.load(storage)?; + if !axelar_workers::should_update_worker_set( + &new_worker_set.clone().into(), + &cur_worker_set.clone().into(), + usize::try_from(config.worker_set_diff_threshold).unwrap(), + ) { + return Err(ContractError::WorkerSetUnchanged); + } + + let tx_hash = xrpl_multisig::issue_signer_list_set(storage, config, cur_worker_set)?; + + NEXT_WORKER_SET.save(storage, &tx_hash, &new_worker_set)?; + + start_signing_session(storage, config, tx_hash, env.contract.address) +} + +fn construct_ticket_create_proof( + storage: &mut dyn Storage, + self_address: Addr, + config: &Config, +) -> Result { + let ticket_count = xrpl_multisig::tickets_available_to_request(storage)?; + if ticket_count < config.ticket_count_threshold { + return Err(ContractError::TicketCountThresholdNotReached); + } + + let tx_hash = xrpl_multisig::issue_ticket_create(storage, config, ticket_count)?; + + let response = start_signing_session(storage, config, tx_hash, self_address)?; + + Ok(response) +} + +fn update_tx_status( + storage: &mut dyn Storage, + querier: &Querier, + config: &Config, + multisig_session_id: &Uint64, + signer_public_keys: &[PublicKey], + message_id: &CrossChainId, + status: VerificationStatus, +) -> Result { + let unsigned_tx_hash = + MULTISIG_SESSION_ID_TO_TX_HASH.load(storage, multisig_session_id.u64())?; + let tx_info = TRANSACTION_INFO.load(storage, &unsigned_tx_hash)?; + let multisig_session = querier.get_multisig_session(multisig_session_id)?; + + let destination_str = match &tx_info.unsigned_contents { + XRPLUnsignedTx::Payment(p) => p.destination.to_string(), + _ => config.xrpl_multisig.to_string(), + }; + + let message = Message { + destination_chain: ChainName::from_str(XRPL_CHAIN_NAME).unwrap(), + source_address: Address::from_str(&config.xrpl_multisig.to_string()) + .map_err(|_| ContractError::InvalidAddress)?, + destination_address: Address::from_str(destination_str.as_ref()) + .map_err(|_| ContractError::InvalidAddress)?, + cc_id: message_id.clone(), + payload_hash: [0; 32], + }; + + let xrpl_signers: Vec = multisig_session + .signers + .iter() + .filter(|(signer, _)| signer_public_keys.contains(&signer.pub_key)) + .filter_map(|(signer, signature)| { + signature + .as_ref() + .map(|signature| XRPLSigner::try_from((signer.clone(), signature.clone()))) + }) + .collect::, ContractError>>()?; + + if xrpl_signers.len() != signer_public_keys.len() { + return Err(ContractError::SignatureNotFound); + } + + let signed_tx = XRPLSignedTransaction::new(tx_info.unsigned_contents, xrpl_signers); + let tx_blob = HexBinary::from(signed_tx.xrpl_serialize()?); + let tx_hash: HexBinary = xrpl_multisig::compute_signed_tx_hash(tx_blob.as_slice())?.into(); + + if parse_message_id(&message_id.id) + .map_err(|_| ContractError::InvalidMessageID(message_id.id.to_string()))? + .0 + .to_string() + != tx_hash.to_string() + { + return Err(ContractError::InvalidMessageID(message_id.id.to_string())); + } + + let actual_status = querier.get_message_status(message)?; + if status != actual_status { + return Err(ContractError::InvalidMessageStatus); + } + + xrpl_multisig::update_tx_status(storage, config, unsigned_tx_hash, status.into()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn reply( + deps: DepsMut, + _env: Env, + reply: Reply, +) -> Result { + match reply.id { + START_MULTISIG_REPLY_ID => reply::start_multisig_reply(deps, reply), + _ => unreachable!("unknown reply ID"), + } + .map_err(axelar_wasm_std::ContractError::from) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { + let config = CONFIG.load(deps.storage)?; + let querier = Querier::new(deps.querier, config.clone()); + match msg { + QueryMsg::GetProof { + multisig_session_id, + } => to_json_binary(&query::get_proof( + deps.storage, + querier, + &multisig_session_id, + )?), + QueryMsg::VerifySignature { + session_id, + message: _, + public_key, + signature, + signer_address: _, + } => to_json_binary(&query::verify_signature( + deps.storage, + &session_id, + &PublicKey::Ecdsa(public_key), + &multisig::key::Signature::try_from((multisig::key::KeyType::Ecdsa, signature)) + .map_err(|_| ContractError::InvalidSignature)?, + )?), + QueryMsg::GetWorkerSet {} => to_json_binary(&query::get_worker_set(deps.storage)?), + QueryMsg::GetMultisigSessionId { message_id } => { + to_json_binary(&query::get_multisig_session_id(deps.storage, &message_id)?) + } // TODO: rename + } +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn migrate( + deps: DepsMut, + _env: Env, + msg: MigrateMsg, +) -> Result { + let old_config = CONFIG.load(deps.storage)?; + let governance = deps.api.addr_validate(&msg.governance_address)?; + let new_config = Config { + governance, + ..old_config + }; + CONFIG.save(deps.storage, &new_config)?; + + Ok(Response::default()) +} diff --git a/contracts/xrpl-multisig-prover/src/error.rs b/contracts/xrpl-multisig-prover/src/error.rs new file mode 100644 index 0000000000..a0895dc0ae --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/error.rs @@ -0,0 +1,121 @@ +use axelar_wasm_std::nonempty; +use axelar_wasm_std_derive::IntoContractError; +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq, IntoContractError)] +pub enum ContractError { + #[error(transparent)] + Std(#[from] StdError), + + #[error("invalid amount: {reason}")] + InvalidAmount { reason: String }, + + #[error("serialization failed")] + SerializationFailed, + + #[error("invalid contract reply: {reason}")] + InvalidContractReply { reason: String }, + + #[error("caller is not authorized")] + Unauthorized, + + #[error("chain name is invalid")] + InvalidChainName, + + #[error(transparent)] + ServiceRegistryError(#[from] service_registry::ContractError), + + #[error(transparent)] + NonEmptyError(#[from] nonempty::Error), + + #[error("worker set has not changed sufficiently since last update")] + WorkerSetUnchanged, + + #[error("ticket count threshold has not been reached")] + TicketCountThresholdNotReached, + + #[error("transaction status is already updated")] + TransactionStatusAlreadyUpdated, + + #[error("previous ticket create transaction is pending")] + PreviousTicketCreateTxPending, + + #[error("invalid message status")] + InvalidMessageStatus, + + #[error("transaction has not been confirmed")] + TransactionStatusNotConfirmed, + + #[error("transaction status is not pending")] + TransactionStatusNotPending, + + #[error("invalid payment amount")] + InvalidPaymentAmount, + + #[error("invalid signing threshold")] + InvalidSigningThreshold, + + #[error("worker set is not set")] + WorkerSetIsNotSet, + + #[error("invalid address")] + InvalidAddress, + + #[error("invalid currency")] + InvalidCurrency, + + #[error("invalid signing pub key")] + InvalidSigningPubKey, + + #[error("invalid transaction signature")] + InvalidSignature, + + #[error("signing session not completed")] + SigningSessionNotCompleted, + + #[error("invalid blob")] + InvalidBlob, + + #[error("invalid message ID {0}")] + InvalidMessageID(String), + + #[error("failed to encode signature")] + FailedToEncodeSignature, + + #[error("failed to serialize")] + FailedToSerialize, + + #[error("signature verification failed")] + SignatureVerificationFailed, + + #[error("signature not found")] + SignatureNotFound, + + #[error("invalid message source address")] + InvalidMessageSourceAddress, + + #[error("invalid message destination address")] + InvalidMessageDestinationAddress, + + #[error("payment already has active signing session with ID {0}")] + PaymentAlreadyHasActiveSigningSession(u64), + + #[error("invalid token denomination")] + InvalidTokenDenom, + + #[error("no available tickets")] + NoAvailableTickets, + + #[error("no worker set stored")] + NoWorkerSet, + + #[error("generic error {0}")] + GenericError(String), +} + +impl From for StdError { + fn from(value: ContractError) -> Self { + Self::generic_err(value.to_string()) + } +} diff --git a/contracts/xrpl-multisig-prover/src/events.rs b/contracts/xrpl-multisig-prover/src/events.rs new file mode 100644 index 0000000000..2fb6474ca4 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/events.rs @@ -0,0 +1,77 @@ +use std::collections::HashMap; + +use axelar_wasm_std::Snapshot; +use cosmwasm_std::{HexBinary, Uint64}; +use multisig::key::PublicKey; +use serde_json::to_string; + +use crate::types::TxHash; +pub enum Event { + ProofUnderConstruction { + tx_hash: TxHash, + multisig_session_id: Uint64, + }, + SnapshotRotated { + key_id: String, + snapshot: Snapshot, + pub_keys: HashMap, + }, + XRPLSigningStarted { + session_id: Uint64, + worker_set_id: String, + pub_keys: HashMap, + unsigned_tx: HexBinary, + expires_at: u64, + }, +} + +impl From for cosmwasm_std::Event { + fn from(other: Event) -> Self { + match other { + Event::XRPLSigningStarted { + session_id, + worker_set_id, + pub_keys, + unsigned_tx, + expires_at, + } => cosmwasm_std::Event::new("xrpl_signing_started") + .add_attribute("session_id", session_id) + .add_attribute("worker_set_id", worker_set_id) + .add_attribute( + "pub_keys", + to_string(&pub_keys) + .expect("violated invariant: pub_keys are not serializable"), + ) + .add_attribute("unsigned_tx", unsigned_tx.to_hex()) + .add_attribute("expires_at", expires_at.to_string()), + Event::ProofUnderConstruction { + tx_hash, + multisig_session_id, + } => cosmwasm_std::Event::new("proof_under_construction") + .add_attribute( + "tx_hash", + to_string(&tx_hash).expect("violated invariant: tx_hash is not serializable"), + ) + .add_attribute( + "multisig_session_id", + to_string(&multisig_session_id) + .expect("violated invariant: multisig_session_id is not serializable"), + ), + Event::SnapshotRotated { + key_id, + snapshot, + pub_keys, + } => cosmwasm_std::Event::new("snapshot_rotated") + .add_attribute("key_id", key_id) + .add_attribute( + "snapshot", + to_string(&snapshot).expect("violated invariant: snapshot is not serializable"), + ) + .add_attribute( + "pub_keys", + to_string(&pub_keys) + .expect("violated invariant: pub_keys are not serializable"), + ), + } + } +} diff --git a/contracts/xrpl-multisig-prover/src/lib.rs b/contracts/xrpl-multisig-prover/src/lib.rs new file mode 100644 index 0000000000..66fde0ce38 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/lib.rs @@ -0,0 +1,12 @@ +pub mod axelar_workers; +pub mod contract; +pub mod error; +pub mod events; +pub mod msg; +pub mod querier; +pub mod query; +pub mod reply; +pub mod state; +pub mod types; +pub mod xrpl_multisig; +pub mod xrpl_serialize; diff --git a/contracts/xrpl-multisig-prover/src/msg.rs b/contracts/xrpl-multisig-prover/src/msg.rs new file mode 100644 index 0000000000..c096d437d5 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/msg.rs @@ -0,0 +1,93 @@ +use axelar_wasm_std::{MajorityThreshold, VerificationStatus}; +use connection_router_api::CrossChainId; +use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::{HexBinary, Uint64}; +use multisig::key::PublicKey; + +use crate::types::{TxHash, XRPLToken}; + +#[cw_serde] +pub struct InstantiateMsg { + pub admin_address: String, + pub axelar_multisig_address: String, + pub gateway_address: String, + pub signing_threshold: MajorityThreshold, + pub xrpl_multisig_address: String, + pub voting_verifier_address: String, + pub service_registry_address: String, + pub monitoring_address: String, + pub service_name: String, + pub worker_set_diff_threshold: u32, + pub xrpl_fee: u64, + pub ticket_count_threshold: u32, + pub available_tickets: Vec, + pub next_sequence_number: u32, + pub last_assigned_ticket_number: u32, + pub governance_address: String, + pub relayer_address: String, // TODO: REMOVE + pub xrp_denom: String, +} + +#[cw_serde] +#[derive(QueryResponses)] +pub enum QueryMsg { + #[returns(GetProofResponse)] + GetProof { multisig_session_id: Uint64 }, + + #[returns(bool)] + VerifySignature { + signature: HexBinary, + message: HexBinary, + public_key: HexBinary, + signer_address: String, + session_id: Uint64, + }, + + #[returns(multisig::worker_set::WorkerSet)] + GetWorkerSet, + + #[returns(Option)] + GetMultisigSessionId { message_id: CrossChainId }, +} + +#[cw_serde] +#[serde(tag = "status")] +pub enum GetProofResponse { + Completed { + unsigned_tx_hash: TxHash, + tx_blob: HexBinary, + }, + Pending { + unsigned_tx_hash: TxHash, + }, +} + +#[cw_serde] +pub enum ExecuteMsg { + RegisterToken { + denom: String, + token: XRPLToken, + decimals: u8, + }, + // TODO: remove coin parameter + ConstructProof { + message_id: CrossChainId, + coin: cosmwasm_std::Coin, + }, + UpdateTxStatus { + multisig_session_id: Uint64, + signer_public_keys: Vec, + message_id: CrossChainId, + message_status: VerificationStatus, + }, + UpdateWorkerSet, + TicketCreate, + UpdateSigningThreshold { + new_signing_threshold: MajorityThreshold, + }, +} + +#[cw_serde] +pub struct MigrateMsg { + pub governance_address: String, +} diff --git a/contracts/xrpl-multisig-prover/src/querier.rs b/contracts/xrpl-multisig-prover/src/querier.rs new file mode 100644 index 0000000000..7e73ef03af --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/querier.rs @@ -0,0 +1,109 @@ +use std::str::FromStr; + +use axelar_wasm_std::VerificationStatus; +use connection_router_api::{ChainName, CrossChainId, Message}; +#[cfg(not(feature = "library"))] +use cosmwasm_schema::serde::{de::DeserializeOwned, Serialize}; +use cosmwasm_std::{to_json_binary, QuerierWrapper, QueryRequest, Uint64, WasmQuery}; +use multisig::{key::PublicKey, msg::Multisig}; + +use crate::{error::ContractError, state::Config}; + +use service_registry::state::WeightedWorker; + +pub const XRPL_CHAIN_NAME: &str = "XRPL"; + +fn query( + querier: QuerierWrapper, + contract_addr: String, + query_msg: &T, +) -> Result +where + U: DeserializeOwned, + T: Serialize + ?Sized, +{ + querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr, + msg: to_json_binary(&query_msg)?, + })) + .map_err(ContractError::from) +} + +pub struct Querier<'a> { + querier: QuerierWrapper<'a>, + config: Config, +} + +impl<'a> Querier<'a> { + pub fn new(querier: QuerierWrapper<'a>, config: Config) -> Self { + Self { querier, config } + } + + pub fn get_active_workers(&self) -> Result, ContractError> { + query( + self.querier, + self.config.service_registry.to_string(), + &service_registry::msg::QueryMsg::GetActiveWorkers { + service_name: self.config.service_name.clone(), + chain_name: ChainName::from_str(XRPL_CHAIN_NAME).unwrap(), + }, + ) + } + + pub fn get_public_key(&self, worker_address: String) -> Result { + query( + self.querier, + self.config.axelar_multisig.to_string(), + &multisig::msg::QueryMsg::GetPublicKey { + worker_address, + key_type: self.config.key_type, + }, + ) + } + + pub fn get_message(&self, message_id: &CrossChainId) -> Result { + let messages: Vec = query( + self.querier, + self.config.gateway.to_string(), + &gateway_api::msg::QueryMsg::GetOutgoingMessages { + message_ids: vec![message_id.clone()], + }, + )?; + messages + .first() + .cloned() + .ok_or(ContractError::InvalidMessageID(message_id.id.to_string())) + } + + pub fn get_message_status( + &self, + message: Message, + ) -> Result { + let statuses: Vec<(CrossChainId, VerificationStatus)> = query( + self.querier, + self.config.voting_verifier.to_string(), + &voting_verifier::msg::QueryMsg::GetMessagesStatus { + messages: vec![message], + }, + )?; + let status = statuses.first().ok_or(ContractError::GenericError( + "failed fetching message status".to_owned(), + ))?; + Ok(status.1) + } + + pub fn get_multisig_session( + &self, + multisig_session_id: &Uint64, + ) -> Result { + let query_msg = multisig::msg::QueryMsg::GetMultisig { + session_id: *multisig_session_id, + }; + query( + self.querier, + self.config.axelar_multisig.to_string(), + &query_msg, + ) + } +} diff --git a/contracts/xrpl-multisig-prover/src/query.rs b/contracts/xrpl-multisig-prover/src/query.rs new file mode 100644 index 0000000000..6bea1c02e1 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/query.rs @@ -0,0 +1,108 @@ +use connection_router_api::CrossChainId; +use cosmwasm_std::{HexBinary, StdResult, Storage, Uint64}; + +use multisig::key::PublicKey; +use multisig::{key::Signature, types::MultisigState}; + +use crate::state::{AVAILABLE_TICKETS, MESSAGE_ID_TO_MULTISIG_SESSION_ID, MESSAGE_ID_TO_TICKET}; +use crate::{ + error::ContractError, + msg::GetProofResponse, + querier::Querier, + state::{CURRENT_WORKER_SET, MULTISIG_SESSION_ID_TO_TX_HASH, TRANSACTION_INFO}, + types::TransactionStatus, + types::*, + xrpl_multisig::{self, HASH_PREFIX_UNSIGNED_TX_MULTI_SIGNING}, + xrpl_serialize::XRPLSerialize, +}; + +pub fn get_message_to_sign( + storage: &dyn Storage, + multisig_session_id: &Uint64, + signer_xrpl_address: &XRPLAccountId, +) -> StdResult { + let unsigned_tx_hash = + MULTISIG_SESSION_ID_TO_TX_HASH.load(storage, multisig_session_id.u64())?; + + let tx_info = TRANSACTION_INFO.load(storage, &unsigned_tx_hash)?; + if tx_info.status != TransactionStatus::Pending { + return Err(ContractError::TransactionStatusNotPending.into()); + } + + let mut tx_blob = tx_info.unsigned_contents.xrpl_serialize()?; + tx_blob.extend(signer_xrpl_address.to_bytes()); + + Ok(xrpl_multisig::xrpl_hash(HASH_PREFIX_UNSIGNED_TX_MULTI_SIGNING, tx_blob.as_slice()).into()) +} + +pub fn verify_signature( + storage: &dyn Storage, + multisig_session_id: &Uint64, + public_key: &PublicKey, + signature: &Signature, +) -> StdResult { + let signer_xrpl_address = XRPLAccountId::from(public_key); + let tx_hash = get_message_to_sign(storage, multisig_session_id, &signer_xrpl_address)?; + + // m.tx_hash is going to be over 32 bytes due to inclusion of the signer address, so it has to be passed unchecked + Ok(signature + .verify(multisig::types::MsgToSign::unchecked(tx_hash), public_key) + .is_ok()) +} + +pub fn get_proof( + storage: &dyn Storage, + querier: Querier, + multisig_session_id: &Uint64, +) -> StdResult { + let unsigned_tx_hash = + MULTISIG_SESSION_ID_TO_TX_HASH.load(storage, multisig_session_id.u64())?; + + let tx_info = TRANSACTION_INFO.load(storage, &unsigned_tx_hash)?; + + let multisig_session = querier.get_multisig_session(multisig_session_id)?; + + let response = match multisig_session.state { + MultisigState::Pending => GetProofResponse::Pending { unsigned_tx_hash }, + MultisigState::Completed { .. } => { + let xrpl_signers: Vec = multisig_session + .signers + .into_iter() + .filter_map(|(signer, sig)| sig.map(|sig| (signer, sig))) + .map(XRPLSigner::try_from) + .collect::, ContractError>>()?; + let signed_tx = XRPLSignedTransaction::new(tx_info.unsigned_contents, xrpl_signers); + let tx_blob: HexBinary = HexBinary::from(signed_tx.xrpl_serialize()?); + GetProofResponse::Completed { + unsigned_tx_hash, + tx_blob, + } + } + }; + + Ok(response) +} + +pub fn get_worker_set(storage: &dyn Storage) -> StdResult { + Ok(CURRENT_WORKER_SET.load(storage)?.into()) +} + +pub fn get_multisig_session_id( + storage: &dyn Storage, + message_id: &CrossChainId, +) -> StdResult> { + let existing_ticket_number = MESSAGE_ID_TO_TICKET.may_load(storage, message_id)?; + let available_tickets = AVAILABLE_TICKETS.may_load(storage)?; + if existing_ticket_number.is_none() || available_tickets.is_none() { + return Ok(None); + } + + if available_tickets + .unwrap() + .contains(&existing_ticket_number.unwrap()) + { + return MESSAGE_ID_TO_MULTISIG_SESSION_ID.may_load(storage, message_id); + } + + Ok(None) +} diff --git a/contracts/xrpl-multisig-prover/src/reply.rs b/contracts/xrpl-multisig-prover/src/reply.rs new file mode 100644 index 0000000000..f1eb44b4f0 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/reply.rs @@ -0,0 +1,82 @@ +use cosmwasm_std::{from_json, Attribute, DepsMut, HexBinary, Reply, Response, Uint64}; +use cw_utils::{parse_reply_execute_data, MsgExecuteContractResponse}; + +use crate::{ + error::ContractError, + events::Event, + state::{ + MESSAGE_ID_TO_MULTISIG_SESSION_ID, MULTISIG_SESSION_ID_TO_TX_HASH, REPLY_MESSAGE_ID, + REPLY_TX_HASH, TRANSACTION_INFO, + }, + types::XRPLUnsignedTx, + xrpl_serialize::XRPLSerialize, +}; + +pub fn start_multisig_reply(deps: DepsMut, reply: Reply) -> Result { + match parse_reply_execute_data(reply.clone()) { + Ok(MsgExecuteContractResponse { data: Some(data) }) => { + let tx_hash = REPLY_TX_HASH.load(deps.storage)?; + + let multisig_session_id: Uint64 = + from_json(data).map_err(|_| ContractError::InvalidContractReply { + reason: "invalid multisig session ID".to_string(), + })?; + + MULTISIG_SESSION_ID_TO_TX_HASH.save( + deps.storage, + multisig_session_id.u64(), + &tx_hash, + )?; + + let tx_info = TRANSACTION_INFO.load(deps.storage, &tx_hash)?; + + match REPLY_MESSAGE_ID.may_load(deps.storage)? { + Some(message_id) => { + MESSAGE_ID_TO_MULTISIG_SESSION_ID.save( + deps.storage, + &message_id, + &multisig_session_id.u64(), + )?; + REPLY_MESSAGE_ID.remove(deps.storage); + } + None if matches!(tx_info.unsigned_contents, XRPLUnsignedTx::Payment(_)) => { + panic!("No reply message ID found for Payment") + } + None => (), + } + + let res = reply.result.unwrap(); + + let evt_attributes: Vec = res + .events + .into_iter() + .filter(|e| e.ty == "wasm-signing_started") + .flat_map(|e| e.attributes) + .filter(|a| !a.key.starts_with('_') && a.key != "msg") + .collect(); + + let evt = cosmwasm_std::Event::new("xrpl_signing_started") + .add_attributes(evt_attributes) + .add_attribute( + "unsigned_tx", + HexBinary::from(tx_info.unsigned_contents.xrpl_serialize()?).to_hex(), + ); + + Ok(Response::new() + .add_event( + Event::ProofUnderConstruction { + tx_hash, + multisig_session_id, + } + .into(), + ) + .add_event(evt)) + } + Ok(MsgExecuteContractResponse { data: None }) => Err(ContractError::InvalidContractReply { + reason: "no data".to_string(), + }), + Err(_) => { + unreachable!("violated invariant: replied failed submessage with ReplyOn::Success") + } + } +} diff --git a/contracts/xrpl-multisig-prover/src/state.rs b/contracts/xrpl-multisig-prover/src/state.rs new file mode 100644 index 0000000000..e01c8f80c6 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/state.rs @@ -0,0 +1,56 @@ +use crate::{ + axelar_workers::WorkerSet, + types::{TransactionInfo, TxHash, XRPLToken}, +}; +use axelar_wasm_std::MajorityThreshold; +use connection_router_api::CrossChainId; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Addr; +use cw_storage_plus::{Item, Map}; + +#[cw_serde] +pub struct Config { + pub admin: Addr, + pub governance: Addr, + pub relayer: Addr, + pub axelar_multisig: Addr, + pub monitoring: Addr, + pub gateway: Addr, + pub signing_threshold: MajorityThreshold, + pub xrpl_multisig: String, + pub voting_verifier: Addr, + pub service_registry: Addr, + pub service_name: String, + pub worker_set_diff_threshold: u32, + pub xrpl_fee: u64, + pub ticket_count_threshold: u32, + pub key_type: multisig::key::KeyType, + pub xrp_denom: String, +} + +pub const CONFIG: Item = Item::new("config"); +pub const REPLY_TX_HASH: Item = Item::new("reply_tx_hash"); +pub const REPLY_MESSAGE_ID: Item = Item::new("reply_message_id"); +pub const MULTISIG_SESSION_ID_TO_TX_HASH: Map = Map::new("multisig_session_tx"); + +// The next seq. no. is determined on TicketCreate and depends on the number of created tickets, +// not solely on the last sequence number used. +// On the contrary, the next ticket number to be used cannot be determined before proof construction, +// as it depends on the tickets available at the time. +// After all ticket numbers are used, we reuse the smallest available ticket number, +// going over all ticket numbers again, wrapping around. +pub const NEXT_SEQUENCE_NUMBER: Item = Item::new("next_sequence_number"); +pub const LAST_ASSIGNED_TICKET_NUMBER: Item = Item::new("last_assigned_ticket_number"); + +pub const MESSAGE_ID_TO_TICKET: Map<&CrossChainId, u32> = Map::new("message_id_to_ticket"); +pub const MESSAGE_ID_TO_MULTISIG_SESSION_ID: Map<&CrossChainId, u64> = + Map::new("message_id_to_multisig_session_id"); +pub const CONFIRMED_TRANSACTIONS: Map<&u32, TxHash> = Map::new("confirmed_transactions"); +pub const AVAILABLE_TICKETS: Item> = Item::new("available_tickets"); +pub const TRANSACTION_INFO: Map<&TxHash, TransactionInfo> = Map::new("transaction_info"); +pub const LATEST_SEQUENTIAL_TX_HASH: Item = Item::new("latest_sequential_tx_hash"); + +pub const TOKENS: Map<&String, (XRPLToken, u8)> = Map::new("tokens"); + +pub const CURRENT_WORKER_SET: Item = Item::new("current_worker_set"); +pub const NEXT_WORKER_SET: Map<&TxHash, WorkerSet> = Map::new("next_worker_set"); diff --git a/contracts/xrpl-multisig-prover/src/types.rs b/contracts/xrpl-multisig-prover/src/types.rs new file mode 100644 index 0000000000..a6cc4be5f6 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/types.rs @@ -0,0 +1,443 @@ +use std::fmt; +use std::fmt::Display; + +use axelar_wasm_std::VerificationStatus; +use connection_router_api::CrossChainId; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{from_json, Binary, HexBinary, StdResult, Uint128, Uint256}; +use cw_storage_plus::{Key, KeyDeserialize, PrimaryKey}; +use k256::ecdsa; +use k256::schnorr::signature::SignatureEncoding; +use multisig::key::PublicKey; +use multisig::key::Signature; +use ripemd::Ripemd160; +use sha2::{Digest, Sha256}; + +use crate::axelar_workers::AxelarSigner; +use crate::error::ContractError; +use voting_verifier::events::parse_message_id; + +#[cw_serde] +pub enum TransactionStatus { + Pending, + Succeeded, + FailedOnChain, + Inconclusive, +} + +#[cw_serde] +pub struct TxHash(pub HexBinary); + +impl TryFrom for TxHash { + type Error = ContractError; + fn try_from(cc_id: CrossChainId) -> Result { + let (tx_id, _event_index) = parse_message_id(&cc_id.id) + .map_err(|_e| ContractError::InvalidMessageID(cc_id.id.to_string()))?; + Ok(Self(HexBinary::from_hex( + tx_id.to_ascii_lowercase().as_str(), + )?)) + } +} + +impl From for HexBinary { + fn from(hash: TxHash) -> Self { + hash.0 + } +} + +impl From for TransactionStatus { + fn from(status: VerificationStatus) -> TransactionStatus { + match status { + VerificationStatus::SucceededOnChain => TransactionStatus::Succeeded, + VerificationStatus::FailedOnChain => TransactionStatus::FailedOnChain, + _ => TransactionStatus::Inconclusive, + } + } +} + +#[cw_serde] +pub struct TransactionInfo { + pub status: TransactionStatus, + pub unsigned_contents: XRPLUnsignedTx, + pub original_message_id: Option, +} + +impl From for TxHash { + fn from(id: HexBinary) -> Self { + Self(id) + } +} + +impl From<&[u8]> for TxHash { + fn from(id: &[u8]) -> Self { + Self(id.into()) + } +} + +impl<'a> PrimaryKey<'a> for TxHash { + type Prefix = (); + type SubPrefix = (); + type Suffix = TxHash; + type SuperSuffix = TxHash; + + fn key(&self) -> Vec { + vec![Key::Ref(self.0.as_slice())] + } +} + +impl KeyDeserialize for TxHash { + type Output = TxHash; + + fn from_vec(value: Vec) -> StdResult { + from_json(Binary::from(value)) + } +} + +#[cw_serde] +#[derive(Ord, PartialOrd, Eq)] +pub struct Operator { + pub address: HexBinary, + pub weight: Uint256, + pub signature: Option, +} + +impl Operator { + pub fn with_signature(self, sig: Signature) -> Operator { + Operator { + address: self.address, + weight: self.weight, + signature: Some(sig), + } + } +} + +#[cw_serde] +pub struct XRPLToken { + pub issuer: XRPLAccountId, + pub currency: XRPLCurrency, +} + +#[cw_serde] +pub enum XRPLPaymentAmount { + Drops(u64), + Token(XRPLToken, XRPLTokenAmount), +} + +#[cw_serde] +pub enum XRPLSequence { + Plain(u32), + Ticket(u32), +} + +impl From for u32 { + fn from(value: XRPLSequence) -> Self { + match value { + XRPLSequence::Plain(sequence) => sequence, + XRPLSequence::Ticket(ticket) => ticket, + } + } +} + +#[cw_serde] +pub struct XRPLSignerEntry { + pub account: XRPLAccountId, + pub signer_weight: u16, +} + +impl From for XRPLSignerEntry { + fn from(signer: AxelarSigner) -> Self { + Self { + account: XRPLAccountId::from(&signer.pub_key), + signer_weight: signer.weight, + } + } +} + +#[cw_serde] +pub enum XRPLUnsignedTx { + Payment(XRPLPaymentTx), + SignerListSet(XRPLSignerListSetTx), + TicketCreate(XRPLTicketCreateTx), +} + +impl XRPLUnsignedTx { + pub fn sequence(&self) -> &XRPLSequence { + match self { + XRPLUnsignedTx::Payment(tx) => &tx.sequence, + XRPLUnsignedTx::TicketCreate(tx) => &tx.sequence, + XRPLUnsignedTx::SignerListSet(tx) => &tx.sequence, + } + } + pub fn sequence_number_increment(&self, status: TransactionStatus) -> u32 { + if status == TransactionStatus::Pending || status == TransactionStatus::Inconclusive { + return 0; + } + + match self { + XRPLUnsignedTx::Payment(tx) => match tx.sequence { + XRPLSequence::Plain(_) => 1, + XRPLSequence::Ticket(_) => 0, + }, + XRPLUnsignedTx::SignerListSet(tx) => match tx.sequence { + XRPLSequence::Plain(_) => 1, + XRPLSequence::Ticket(_) => 0, + }, + XRPLUnsignedTx::TicketCreate(tx) => match status { + TransactionStatus::Succeeded => tx.ticket_count + 1, + TransactionStatus::FailedOnChain => 1, + TransactionStatus::Inconclusive | TransactionStatus::Pending => unreachable!(), + }, + } + } +} + +#[cw_serde] +pub struct XRPLPaymentTx { + pub account: XRPLAccountId, + pub fee: u64, + pub sequence: XRPLSequence, + pub amount: XRPLPaymentAmount, + pub destination: XRPLAccountId, +} + +#[cw_serde] +pub struct XRPLSignerListSetTx { + pub account: XRPLAccountId, + pub fee: u64, + pub sequence: XRPLSequence, + pub signer_quorum: u32, + pub signer_entries: Vec, +} + +#[cw_serde] +pub struct XRPLTicketCreateTx { + pub account: XRPLAccountId, + pub fee: u64, + pub sequence: XRPLSequence, + pub ticket_count: u32, +} + +#[cw_serde] +pub struct XRPLAccountId([u8; 20]); + +impl XRPLAccountId { + pub const fn to_bytes(&self) -> [u8; 20] { + self.0 + } + + pub fn from_bytes(bytes: [u8; 20]) -> Self { + Self(bytes) + } +} + +impl Display for XRPLAccountId { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut payload = Vec::::with_capacity(25); + payload.extend(&[0x00]); + payload.extend_from_slice(&self.to_bytes()); + + let checksum_hash1 = Sha256::digest(payload.clone()); + let checksum_hash2 = Sha256::digest(checksum_hash1); + let checksum = &checksum_hash2[0..4]; + + payload.extend(checksum); + + let str = bs58::encode(payload) + .with_alphabet(bs58::Alphabet::RIPPLE) + .into_string(); + + write!(f, "{}", str) + } +} + +impl From<&PublicKey> for XRPLAccountId { + fn from(pub_key: &PublicKey) -> Self { + let public_key_hex: HexBinary = pub_key.clone().into(); + + assert!(public_key_hex.len() == 33); + + let public_key_inner_hash = Sha256::digest(public_key_hex); + let account_id = Ripemd160::digest(public_key_inner_hash); + + XRPLAccountId(account_id.into()) + } +} + +impl std::str::FromStr for XRPLAccountId { + type Err = ContractError; + + fn from_str(address: &str) -> Result { + let res = bs58::decode(address) + .with_alphabet(bs58::Alphabet::RIPPLE) + .into_vec() + .map_err(|_| ContractError::InvalidAddress)?; + // .map_err(|_| ContractError::InvalidAddress)?; + if res.len() != 25 { + return Err(ContractError::InvalidAddress); + } + let mut buffer = [0u8; 20]; + buffer.copy_from_slice(&res[1..21]); + Ok(XRPLAccountId(buffer)) + } +} + +#[cw_serde] +pub struct XRPLSigner { + pub account: XRPLAccountId, + pub txn_signature: HexBinary, + pub signing_pub_key: PublicKey, +} + +impl TryFrom<(multisig::msg::Signer, multisig::key::Signature)> for XRPLSigner { + type Error = ContractError; + + fn try_from( + (axelar_signer, signature): (multisig::msg::Signer, multisig::key::Signature), + ) -> Result { + let txn_signature = match signature { + multisig::key::Signature::Ecdsa(_) | multisig::key::Signature::EcdsaRecoverable(_) => { + HexBinary::from( + ecdsa::Signature::to_der( + &ecdsa::Signature::try_from(signature.clone().as_ref()) + .map_err(|_| ContractError::FailedToEncodeSignature)?, + ) + .to_vec(), + ) + } + _ => unimplemented!("Unsupported signature type"), + }; + + Ok(XRPLSigner { + account: XRPLAccountId::from(&axelar_signer.pub_key), + signing_pub_key: axelar_signer.pub_key.clone(), + txn_signature, + }) + } +} + +#[cw_serde] +pub struct XRPLSignedTransaction { + pub unsigned_tx: XRPLUnsignedTx, + pub signers: Vec, +} + +impl XRPLSignedTransaction { + pub fn new(unsigned_tx: XRPLUnsignedTx, signers: Vec) -> Self { + Self { + unsigned_tx, + signers, + } + } +} + +#[cw_serde] +pub struct XRPLCurrency(String); + +impl XRPLCurrency { + pub fn to_bytes(self) -> [u8; 20] { + let mut buffer = [0u8; 20]; + buffer[12..15].copy_from_slice(self.to_string().as_bytes()); + buffer + } +} + +impl Display for XRPLCurrency { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +const ALLOWED_CURRENCY_CHARS: &str = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789?!@#$%^&*<>(){}[]|"; + +impl TryFrom for XRPLCurrency { + type Error = ContractError; + + fn try_from(s: String) -> Result { + if s.len() != 3 || s == "XRP" || !s.chars().all(|c| ALLOWED_CURRENCY_CHARS.contains(c)) { + return Err(ContractError::InvalidCurrency); + } + Ok(XRPLCurrency(s)) + } +} + +pub const MIN_MANTISSA: u64 = 1_000_000_000_000_000; +pub const MAX_MANTISSA: u64 = 10_000_000_000_000_000 - 1; +pub const MIN_EXPONENT: i64 = -96; +pub const MAX_EXPONENT: i64 = 80; + +// XRPLTokenAmount always in canonicalized XRPL mantissa-exponent format, +// such that MIN_MANTISSA <= mantissa <= MAX_MANTISSA (or equal to zero), MIN_EXPONENT <= exponent <= MAX_EXPONENT, +// In XRPL generally it can be decimal and even negative (!) but in our case that doesn't apply. +#[cw_serde] +pub struct XRPLTokenAmount { + mantissa: u64, + exponent: i64, +} + +impl XRPLTokenAmount { + pub fn new(mantissa: u64, exponent: i64) -> Self { + assert!( + mantissa == 0 + || ((MIN_MANTISSA..=MAX_MANTISSA).contains(&mantissa) + && (MIN_EXPONENT..=MAX_EXPONENT).contains(&exponent)) + ); + Self { mantissa, exponent } + } + + pub fn to_bytes(&self) -> [u8; 8] { + if self.mantissa == 0 { + 0x8000000000000000u64.to_be_bytes() + } else { + // not xrp-bit | positive bit | 8 bits exponent | 54 bits mantissa + (0xC000000000000000u64 | ((self.exponent + 97) as u64) << 54 | self.mantissa) + .to_be_bytes() + } + } +} + +pub fn canonicalize_coin_amount( + amount: Uint128, + decimals: u8, +) -> Result { + let (mantissa, exponent) = canonicalize_mantissa(amount, -i64::from(decimals))?; + Ok(XRPLTokenAmount::new(mantissa, exponent)) +} + +// always called when XRPLTokenAmount instantiated +// see https://github.com/XRPLF/xrpl-dev-portal/blob/82da0e53a8d6cdf2b94a80594541d868b4d03b94/content/_code-samples/tx-serialization/py/xrpl_num.py#L19 +pub fn canonicalize_mantissa( + mut mantissa: Uint128, + mut exponent: i64, +) -> Result<(u64, i64), ContractError> { + let ten = Uint128::from(10u128); + + while mantissa < MIN_MANTISSA.into() && exponent > MIN_EXPONENT { + mantissa *= ten; + exponent -= 1; + } + + while mantissa > MAX_MANTISSA.into() && exponent > MIN_EXPONENT { + if exponent > MAX_EXPONENT { + return Err(ContractError::InvalidAmount { + reason: "overflow".to_string(), + }); + } + mantissa /= ten; + exponent += 1; + } + + if exponent < MIN_EXPONENT || mantissa < MIN_MANTISSA.into() { + return Ok((0, 1)); + } + + if exponent > MAX_EXPONENT || mantissa > MAX_MANTISSA.into() { + return Err(ContractError::InvalidAmount { + reason: format!("overflow exponent {} mantissa {}", exponent, mantissa).to_string(), + }); + } + + let mantissa = u64::from_be_bytes(mantissa.to_be_bytes()[8..].try_into().unwrap()); + + Ok((mantissa, exponent)) +} diff --git a/contracts/xrpl-multisig-prover/src/xrpl_multisig.rs b/contracts/xrpl-multisig-prover/src/xrpl_multisig.rs new file mode 100644 index 0000000000..3afc744379 --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/xrpl_multisig.rs @@ -0,0 +1,361 @@ +use axelar_wasm_std::nonempty; +use connection_router_api::CrossChainId; +use cosmwasm_std::{wasm_execute, HexBinary, Response, Storage}; +use sha2::{Digest, Sha256, Sha512}; +use std::str::FromStr; + +use crate::{ + axelar_workers::WorkerSet, + error::ContractError, + state::{ + Config, AVAILABLE_TICKETS, CONFIRMED_TRANSACTIONS, CURRENT_WORKER_SET, + LAST_ASSIGNED_TICKET_NUMBER, LATEST_SEQUENTIAL_TX_HASH, MESSAGE_ID_TO_TICKET, + NEXT_SEQUENCE_NUMBER, NEXT_WORKER_SET, TRANSACTION_INFO, + }, + types::*, +}; + +fn issue_tx( + storage: &mut dyn Storage, + tx: XRPLUnsignedTx, + message_id: Option, +) -> Result { + let tx_hash = compute_unsigned_tx_hash(&tx)?; + + TRANSACTION_INFO.save( + storage, + &tx_hash, + &TransactionInfo { + status: TransactionStatus::Pending, + unsigned_contents: tx.clone(), + original_message_id: message_id, + }, + )?; + + match tx.sequence() { + XRPLSequence::Ticket(ticket_number) => { + LAST_ASSIGNED_TICKET_NUMBER.save(storage, ticket_number)?; + } + XRPLSequence::Plain(_) => { + LATEST_SEQUENTIAL_TX_HASH.save(storage, &tx_hash)?; + } + }; + + Ok(tx_hash) +} + +pub fn issue_payment( + storage: &mut dyn Storage, + config: &Config, + destination: nonempty::String, + amount: &XRPLPaymentAmount, + message_id: &CrossChainId, +) -> Result { + let ticket_number = assign_ticket_number(storage, message_id)?; + + let tx = XRPLPaymentTx { + account: XRPLAccountId::from_str(config.xrpl_multisig.as_str())?, + fee: config.xrpl_fee, + sequence: XRPLSequence::Ticket(ticket_number), + amount: amount.clone(), + destination: XRPLAccountId::from_str(destination.as_str())?, + }; + + issue_tx( + storage, + XRPLUnsignedTx::Payment(tx), + Some(message_id.clone()), + ) +} + +pub fn issue_ticket_create( + storage: &mut dyn Storage, + config: &Config, + ticket_count: u32, +) -> Result { + let sequence_number = get_next_sequence_number(storage)?; + + let tx = XRPLTicketCreateTx { + account: XRPLAccountId::from_str(config.xrpl_multisig.as_str())?, + fee: config.xrpl_fee, + sequence: XRPLSequence::Plain(sequence_number), + ticket_count, + }; + + issue_tx(storage, XRPLUnsignedTx::TicketCreate(tx), None) +} + +pub fn issue_signer_list_set( + storage: &mut dyn Storage, + config: &Config, + workers: WorkerSet, +) -> Result { + let sequence_number = get_next_sequence_number(storage)?; + + let tx = XRPLSignerListSetTx { + account: XRPLAccountId::from_str(config.xrpl_multisig.as_str())?, + fee: config.xrpl_fee, + sequence: XRPLSequence::Plain(sequence_number), + signer_quorum: workers.quorum, + signer_entries: workers + .signers + .into_iter() + .map(XRPLSignerEntry::from) + .collect(), + }; + + issue_tx(storage, XRPLUnsignedTx::SignerListSet(tx), None) +} + +pub fn update_tx_status( + storage: &mut dyn Storage, + config: &Config, + unsigned_tx_hash: TxHash, + new_status: TransactionStatus, +) -> Result { + let mut tx_info = TRANSACTION_INFO.load(storage, &unsigned_tx_hash)?; + if tx_info.status != TransactionStatus::Pending { + return Err(ContractError::TransactionStatusAlreadyUpdated); + } + + tx_info.status = new_status.clone(); + + let tx_sequence_number: u32 = tx_info.unsigned_contents.sequence().clone().into(); + + let sequence_number_increment = tx_info + .unsigned_contents + .sequence_number_increment(new_status.clone()); + if sequence_number_increment > 0 && tx_sequence_number == NEXT_SEQUENCE_NUMBER.load(storage)? { + NEXT_SEQUENCE_NUMBER.save(storage, &(tx_sequence_number + sequence_number_increment))?; + } + + if new_status == TransactionStatus::Succeeded || new_status == TransactionStatus::FailedOnChain + { + CONFIRMED_TRANSACTIONS.save(storage, &tx_sequence_number, &unsigned_tx_hash)?; + mark_ticket_unavailable(storage, tx_sequence_number)?; + } + + TRANSACTION_INFO.save(storage, &unsigned_tx_hash, &tx_info)?; + + if tx_info.status != TransactionStatus::Succeeded { + return Ok(Response::default()); + } + + Ok(match &tx_info.unsigned_contents { + XRPLUnsignedTx::TicketCreate(tx) => { + mark_tickets_available( + storage, + (tx_sequence_number + 1)..(tx_sequence_number + tx.ticket_count + 1) + )?; + Response::default() + } + XRPLUnsignedTx::SignerListSet(_tx) => { + let next_worker_set = NEXT_WORKER_SET.load(storage, &unsigned_tx_hash)?; + CURRENT_WORKER_SET.save(storage, &next_worker_set)?; + NEXT_WORKER_SET.remove(storage, &unsigned_tx_hash); + + Response::new() + .add_message(wasm_execute( + config.axelar_multisig.clone(), + &multisig::msg::ExecuteMsg::RegisterWorkerSet { + worker_set: next_worker_set.clone().into(), + }, + vec![], + )?) + .add_message(wasm_execute( + config.monitoring.clone(), + &monitoring::msg::ExecuteMsg::SetActiveVerifiers { + next_worker_set: next_worker_set.into(), + }, + vec![], + )?) + } + XRPLUnsignedTx::Payment(_) => Response::default(), + }) +} + +// TICKET / SEQUENCE NUMBER ASSIGNEMENT LOGIC + +// A message ID can be ticketed a different ticket number +// only if the previous ticket number has been consumed +// by a TX that doesn't correspond to this message. +pub fn assign_ticket_number( + storage: &mut dyn Storage, + message_id: &CrossChainId, +) -> Result { + // If this message ID has already been ticketed, + // then use the same ticket number as before, + if let Some(ticket_number) = MESSAGE_ID_TO_TICKET.may_load(storage, message_id)? { + let confirmed_tx_hash = CONFIRMED_TRANSACTIONS.may_load(storage, &ticket_number)?; + // as long as it has not already been consumed + if confirmed_tx_hash.is_none() + // or if it has been consumed by the same message. + || TRANSACTION_INFO.load(storage, &confirmed_tx_hash.unwrap())?.original_message_id.as_ref() == Some(message_id) + { + return Ok(ticket_number); + } + } + + // Otherwise, use the next available ticket number. + let new_ticket_number = get_next_ticket_number(storage)?; + MESSAGE_ID_TO_TICKET.save(storage, message_id, &new_ticket_number)?; + Ok(new_ticket_number) +} + +pub fn get_next_ticket_number(storage: &dyn Storage) -> Result { + let last_assigned_ticket_number: u32 = LAST_ASSIGNED_TICKET_NUMBER.load(storage)?; + + // TODO: handle no available tickets + let available_tickets = AVAILABLE_TICKETS.load(storage)?; + + if available_tickets.is_empty() { + return Err(ContractError::NoAvailableTickets); + } + + // find next largest in available, otherwise use available_tickets[0] + let ticket_number = available_tickets + .iter() + .find(|&x| x > &last_assigned_ticket_number) + .unwrap_or(&available_tickets[0]); + Ok(*ticket_number) +} + +pub fn tickets_available_to_request(storage: &mut dyn Storage) -> Result { + let available_tickets = AVAILABLE_TICKETS.load(storage)?; + let available_ticket_count = u32::try_from(available_tickets.len()) + .map_err(|e| ContractError::GenericError(e.to_string()))?; + assert!(available_ticket_count <= 250); + Ok(250 - available_ticket_count) +} + +fn get_next_sequence_number(storage: &dyn Storage) -> Result { + match load_latest_sequential_tx_info(storage)? { + Some(latest_sequential_tx_info) + if latest_sequential_tx_info.status == TransactionStatus::Pending => + { + Ok(latest_sequential_tx_info + .unsigned_contents + .sequence() + .clone() + .into()) + } + _ => NEXT_SEQUENCE_NUMBER.load(storage).map_err(|e| e.into()), + } +} + +fn load_latest_sequential_tx_info( + storage: &dyn Storage, +) -> Result, ContractError> { + LATEST_SEQUENTIAL_TX_HASH + .may_load(storage)? + .map_or(Ok(None), |tx_hash| { + Ok(TRANSACTION_INFO.may_load(storage, &tx_hash)?) + }) +} + +fn mark_tickets_available( + storage: &mut dyn Storage, + tickets: impl Iterator, +) -> Result<(), ContractError> { + AVAILABLE_TICKETS.update(storage, |available_tickets| -> Result<_, ContractError> { + let mut new_available_tickets = available_tickets.clone(); + new_available_tickets.extend(tickets); + Ok(new_available_tickets) + })?; + Ok(()) +} + +fn mark_ticket_unavailable(storage: &mut dyn Storage, ticket: u32) -> Result<(), ContractError> { + AVAILABLE_TICKETS.update(storage, |available_tickets| -> Result<_, ContractError> { + Ok(available_tickets + .into_iter() + .filter(|&x| x != ticket) + .collect()) + })?; + Ok(()) +} + +// HASHING LOGIC + +pub const HASH_PREFIX_SIGNED_TRANSACTION: [u8; 4] = [0x54, 0x58, 0x4E, 0x00]; +pub const HASH_PREFIX_UNSIGNED_TX_MULTI_SIGNING: [u8; 4] = [0x53, 0x4D, 0x54, 0x00]; + +pub fn xrpl_hash(prefix: [u8; 4], tx_blob: &[u8]) -> [u8; 32] { + let mut hasher = Sha512::new_with_prefix(prefix); + hasher.update(tx_blob); + let hash: [u8; 64] = hasher.finalize().into(); + hash[..32].try_into().unwrap() +} + +pub fn compute_unsigned_tx_hash(unsigned_tx: &XRPLUnsignedTx) -> Result { + let encoded_unsigned_tx = + serde_json::to_vec(unsigned_tx).map_err(|_| ContractError::FailedToSerialize)?; + + let d = Sha256::digest(encoded_unsigned_tx); + Ok(TxHash(HexBinary::from(d.to_vec()))) +} + +pub fn compute_signed_tx_hash(encoded_signed_tx: &[u8]) -> Result { + Ok(TxHash(HexBinary::from(xrpl_hash( + HASH_PREFIX_SIGNED_TRANSACTION, + encoded_signed_tx, + )))) +} + +pub fn message_to_sign( + encoded_unsigned_tx: &HexBinary, + signer_address: &XRPLAccountId, +) -> Result<[u8; 32], ContractError> { + let mut msg = encoded_unsigned_tx.to_vec(); + msg.extend_from_slice(&signer_address.to_bytes()); + Ok(xrpl_hash( + HASH_PREFIX_UNSIGNED_TX_MULTI_SIGNING, + msg.as_slice(), + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use multisig::key::PublicKey; + + #[test] + fn test_account_id_to_bytes_address() { + assert_eq!( + "rrrrrrrrrrrrrrrrrrrrrhoLvTp", + XRPLAccountId::from_bytes([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + .to_string() + ); + assert_eq!( + "rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi", + XRPLAccountId::from_bytes([ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255 + ]) + .to_string() + ); + } + #[test] + fn ed25519_public_key_to_xrpl_address() -> Result<(), ContractError> { + assert_eq!( + XRPLAccountId::from(&PublicKey::Ed25519(HexBinary::from_hex( + "ED9434799226374926EDA3B54B1B461B4ABF7237962EAE18528FEA67595397FA32" + )?)) + .to_string(), + "rDTXLQ7ZKZVKz33zJbHjgVShjsBnqMBhmN" + ); + Ok(()) + } + + #[test] + fn secp256k1_public_key_to_xrpl_address() -> Result<(), ContractError> { + assert_eq!( + XRPLAccountId::from(&PublicKey::Ecdsa(HexBinary::from_hex( + "0303E20EC6B4A39A629815AE02C0A1393B9225E3B890CAE45B59F42FA29BE9668D" + )?)) + .to_string(), + "rnBFvgZphmN39GWzUJeUitaP22Fr9be75H" + ); + Ok(()) + } +} diff --git a/contracts/xrpl-multisig-prover/src/xrpl_serialize.rs b/contracts/xrpl-multisig-prover/src/xrpl_serialize.rs new file mode 100644 index 0000000000..118a12aa9d --- /dev/null +++ b/contracts/xrpl-multisig-prover/src/xrpl_serialize.rs @@ -0,0 +1,829 @@ +use std::cmp::Ordering; + +use cosmwasm_std::{HexBinary, Uint64}; +use multisig::key::PublicKey; + +use crate::{error::ContractError, types::*}; + +const PAYMENT_TX_TYPE: u16 = 0; +const TICKET_CREATE_TX_TYPE: u16 = 10; +const SIGNER_LIST_SET_TX_TYPE: u16 = 12; +const POSITIVE_BIT: u64 = 0x4000000000000000; + +#[derive(Clone)] +pub enum Field { + SigningPubKey, + TxnSignature, + Account, + SignerWeight, + MemoData, + TransactionType, + Flags, + Sequence, + TicketSequence, + Amount, + Fee, + Destination, + SignerQuorum, + SignerEntries, + SignerEntry, + Memos, + Memo, + TicketCount, + Signers, + Signer, +} + +impl Field { + const fn to_u8(&self) -> u8 { + match self { + Field::SigningPubKey => 3, + Field::TxnSignature => 4, + Field::Account => 1, + Field::SignerWeight => 3, + Field::MemoData => 13, + Field::TransactionType => 2, + Field::Flags => 2, + Field::Amount => 1, + Field::Fee => 8, + Field::Destination => 3, + Field::Sequence => 4, + Field::TicketSequence => 41, + Field::SignerQuorum => 35, + Field::SignerEntries => 4, + Field::SignerEntry => 11, + Field::Memos => 9, + Field::Memo => 10, + Field::TicketCount => 40, + Field::Signers => 3, + Field::Signer => 16, + } + } +} + +use Field::*; + +#[macro_export] +macro_rules! xrpl_json { + // Match a JSON-like structure. + ({ $($key:ident: $value:expr),* $(,)? }) => {{ + let mut obj = XRPLObject::new(); + + // Process each key-value pair. + $( + obj.add_field($key, $value)?; + )* + + obj + }}; +} + +pub trait XRPLSerialize { + const TYPE_CODE: u8; + fn xrpl_serialize(&self) -> Result, ContractError>; +} + +impl XRPLSerialize for u16 { + const TYPE_CODE: u8 = 1; + + fn xrpl_serialize(&self) -> Result, ContractError> { + Ok(self.to_be_bytes().to_vec()) + } +} + +impl XRPLSerialize for u32 { + const TYPE_CODE: u8 = 2; + + fn xrpl_serialize(&self) -> Result, ContractError> { + Ok(self.to_be_bytes().to_vec()) + } +} + +impl XRPLSerialize for XRPLPaymentAmount { + const TYPE_CODE: u8 = 6; + + fn xrpl_serialize(&self) -> Result, ContractError> { + match self { + &XRPLPaymentAmount::Drops(value) => { + if value <= 10u64.pow(17) { + Ok((value | POSITIVE_BIT).to_be_bytes().to_vec()) + } else { + Err(ContractError::InvalidAmount { + reason: "more than maximum amount of drops".to_string(), + }) + } + } + XRPLPaymentAmount::Token(token, amount) => { + let mut buf = Vec::with_capacity(48); + buf.extend_from_slice(&amount.to_bytes()); + buf.extend_from_slice(&token.currency.clone().to_bytes()); + buf.extend_from_slice(&token.issuer.to_bytes()); + Ok(buf) + } + } + } +} + +impl XRPLSerialize for HexBinary { + const TYPE_CODE: u8 = 7; + + fn xrpl_serialize(&self) -> Result, ContractError> { + let len_encoded = encode_length(self.len())?; + let contents = self.to_vec(); + let mut result = Vec::with_capacity(len_encoded.len() + contents.len()); + result.extend(len_encoded); + result.extend(contents); + Ok(result) + } +} + +// see https://github.com/XRPLF/xrpl-dev-portal/blob/master/content/_code-samples/tx-serialization/py/serialize.py#L92 +// may error if length too big +pub fn encode_length(mut length: usize) -> Result, ContractError> { + if length <= 192 { + Ok(vec![length as u8]) + } else if length <= 12480 { + length -= 193; + Ok(vec![193 + (length >> 8) as u8, (length & 0xff) as u8]) + } else if length <= 918744 { + length -= 12481; + Ok(vec![ + 241 + (length >> 16) as u8, + ((length >> 8) & 0xff) as u8, + (length & 0xff) as u8, + ]) + } else { + Err(ContractError::InvalidBlob) + } +} + +impl XRPLSerialize for PublicKey { + const TYPE_CODE: u8 = 7; + fn xrpl_serialize(&self) -> Result, ContractError> { + match self.clone() { + // rippled prefixes Ed25519 public keys with the byte 0xED so both types of public key are 33 bytes. + // https://xrpl.org/cryptographic-keys.html + Self::Ed25519(hex) => { + HexBinary::from_hex(format!("ED{}", hex.to_hex()).as_str())?.xrpl_serialize() + } + Self::Ecdsa(hex) => hex.xrpl_serialize(), + } + } +} + +impl TryInto for XRPLSigner { + type Error = ContractError; + + fn try_into(self) -> Result { + Ok(xrpl_json!({ + SigningPubKey: self.signing_pub_key, + TxnSignature: self.txn_signature, + Account: self.account + })) + } +} + +impl TryInto for XRPLSignerEntry { + type Error = ContractError; + + fn try_into(self) -> Result { + Ok(xrpl_json!({ + Account: self.account, + SignerWeight: self.signer_weight + })) + } +} + +#[derive(Clone)] +pub struct XRPLMemo(HexBinary); + +impl From for HexBinary { + fn from(memo: XRPLMemo) -> Self { + memo.0 + } +} + +impl TryInto for XRPLMemo { + type Error = ContractError; + + fn try_into(self) -> Result { + Ok(xrpl_json!({ + MemoData: self.0 + })) + } +} + +impl XRPLSerialize for XRPLAccountId { + const TYPE_CODE: u8 = 8; + + fn xrpl_serialize(&self) -> Result, ContractError> { + let mut result: Vec = Vec::new(); + result.extend(vec![20u8]); + result.extend(self.to_bytes()); + Ok(result) + } +} + +pub fn hex_encode_session_id(session_id: Uint64) -> HexBinary { + HexBinary::from( + session_id + .to_be_bytes() + .iter() + .skip_while(|&&byte| byte == 0) + .cloned() + .collect::>(), + ) +} + +impl TryInto for XRPLPaymentTx { + type Error = ContractError; + + fn try_into(self) -> Result { + let mut obj = xrpl_json!({ + TransactionType: PAYMENT_TX_TYPE, + Flags: 0u32, + Amount: self.amount, + Fee: XRPLPaymentAmount::Drops(self.fee), + Account: self.account, + SigningPubKey: HexBinary::from(vec![]), + Destination: self.destination, + }); + obj.add_sequence(self.sequence)?; + Ok(obj) + } +} + +impl TryInto for XRPLSignerListSetTx { + type Error = ContractError; + + fn try_into(self) -> Result { + let mut obj = xrpl_json!({ + TransactionType: SIGNER_LIST_SET_TX_TYPE, + Flags: 0u32, + SignerQuorum: self.signer_quorum, + Fee: XRPLPaymentAmount::Drops(self.fee), + Account: self.account, + SigningPubKey: HexBinary::from(vec![]), + SignerEntries: XRPLArray{ field: Field::SignerEntry, items: self.signer_entries.clone() }, + }); + obj.add_sequence(self.sequence)?; + Ok(obj) + } +} + +impl TryInto for XRPLTicketCreateTx { + type Error = ContractError; + + fn try_into(self) -> Result { + let mut obj = xrpl_json!({ + TransactionType: TICKET_CREATE_TX_TYPE, + Flags: 0u32, + TicketCount: self.ticket_count, + Fee: XRPLPaymentAmount::Drops(self.fee), + Account: self.account, + SigningPubKey: HexBinary::from(vec![]), + }); + obj.add_sequence(self.sequence)?; + Ok(obj) + } +} + +impl TryInto for XRPLUnsignedTx { + type Error = ContractError; + + fn try_into(self) -> Result { + match self { + XRPLUnsignedTx::Payment(tx) => tx.try_into(), + XRPLUnsignedTx::TicketCreate(tx) => tx.try_into(), + XRPLUnsignedTx::SignerListSet(tx) => tx.try_into(), + } + } +} + +impl TryInto for XRPLSignedTransaction { + type Error = ContractError; + + fn try_into(self) -> Result { + let mut sorted_signers = self.signers.clone(); + sorted_signers.sort_by(|a, b| { + // the Signers array must be sorted based on the numeric value of the signer addresses + // https://xrpl.org/multi-signing.html#sending-multi-signed-transactions + a.account.to_bytes().cmp(&b.account.to_bytes()) + }); + let mut obj: XRPLObject = self.unsigned_tx.clone().try_into()?; + obj.add_field( + Field::Signers, + XRPLArray { + field: Field::Signer, + items: sorted_signers, + }, + )?; + Ok(obj) + } +} + +struct XRPLArray { + field: Field, + items: Vec, +} + +impl XRPLSerialize for XRPLArray { + const TYPE_CODE: u8 = 15; + + fn xrpl_serialize(&self) -> Result, ContractError> { + let mut result: Vec = Vec::new(); + for item in &self.items { + result.extend(field_id(T::TYPE_CODE, self.field.clone().to_u8())); + result.extend(item.xrpl_serialize()?); + result.extend(field_id(T::TYPE_CODE, 1)); + } + result.extend(field_id(Self::TYPE_CODE, 1)); + Ok(result) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +struct SerializedField { + type_code: u8, + field_code: u8, + serialized_value: Vec, +} + +impl SerializedField { + fn new(type_code: u8, field_code: u8, serialized_value: Vec) -> Self { + Self { + type_code, + field_code, + serialized_value, + } + } +} + +impl PartialOrd for SerializedField { + fn partial_cmp(&self, other: &SerializedField) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for SerializedField { + fn cmp(&self, other: &SerializedField) -> Ordering { + (self.type_code, self.field_code).cmp(&(other.type_code, other.field_code)) + } +} + +#[derive(Debug, Clone, Default)] +pub struct XRPLObject { + fields: Vec, +} + +impl XRPLObject { + pub fn new() -> XRPLObject { + Self { fields: Vec::new() } + } + + pub fn add_field( + &mut self, + field: Field, + value: T, + ) -> Result<(), ContractError> { + self.fields.push(SerializedField::new( + T::TYPE_CODE, + field.to_u8(), + value.xrpl_serialize()?, + )); + Ok(()) + } + + pub fn add_sequence(&mut self, sequence: XRPLSequence) -> Result<(), ContractError> { + match sequence { + XRPLSequence::Plain(seq) => self.add_field(Field::Sequence, seq), + XRPLSequence::Ticket(seq) => { + self.add_field(Field::Sequence, 0u32)?; + self.add_field(Field::TicketSequence, seq) + } + } + } +} + +impl XRPLSerialize for XRPLObject { + const TYPE_CODE: u8 = 14; + + fn xrpl_serialize(&self) -> Result, ContractError> { + let mut fields: Vec = self.fields.clone(); + fields.sort(); + let mut buf = Vec::new(); + for field in fields { + buf.extend(field_id(field.type_code, field.field_code)); + buf.extend(field.serialized_value); + } + Ok(buf) + } +} + +// Implementing XRPLSerialize for any type T that can be converted into XRPLObject +impl XRPLSerialize for T +where + T: TryInto + Clone, +{ + const TYPE_CODE: u8 = XRPLObject::TYPE_CODE; + + fn xrpl_serialize(&self) -> Result, ContractError> { + let obj: XRPLObject = self.clone().try_into()?; + obj.xrpl_serialize() + } +} + +// field ids and type codes from here +// https://github.com/XRPLF/xrpl.js/blob/main/packages/ripple-binary-codec/src/enums/definitions.json +pub fn field_id(type_code: u8, field_code: u8) -> Vec { + assert!(type_code < 16); + if field_code < 16 { + vec![type_code << 4 | field_code] + } else { + vec![type_code << 4, field_code] + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + + use cosmwasm_std::Uint128; + use multisig::key::PublicKey; + + use crate::types::XRPLToken; + + use super::*; + + #[macro_export] + macro_rules! assert_hex_eq { + ($expected:expr, $actual:expr) => { + assert_eq!($expected, hex::encode_upper($actual)); + }; + } + + #[test] + fn test_encode_length() -> Result<(), ContractError> { + assert_hex_eq!("00", encode_length(0)?); + assert_hex_eq!("0A", encode_length(10)?); + assert_hex_eq!("C100", encode_length(193)?); + assert_hex_eq!("F10000", encode_length(12481)?); + assert_hex_eq!("FED417", encode_length(918744)?); + assert!(encode_length(918745).is_err()); + Ok(()) + } + + #[test] + fn test_xrpl_serialize() -> Result<(), ContractError> { + assert_hex_eq!("0000", 0u16.xrpl_serialize()?); + assert_hex_eq!("0001", 1u16.xrpl_serialize()?); + assert_hex_eq!("FFFF", 0xffffu16.xrpl_serialize()?); + assert_hex_eq!("00000000", 0u32.xrpl_serialize()?); + assert_hex_eq!("00000005", 5u32.xrpl_serialize()?); + assert_hex_eq!("FFFFFFFF", 0xffffffffu32.xrpl_serialize()?); + assert_hex_eq!("00", HexBinary::from_hex("")?.xrpl_serialize()?); + assert_hex_eq!( + "04DEADBEEF", + HexBinary::from_hex("DEADBEEF")?.xrpl_serialize()? + ); + assert_hex_eq!( + "800000000000000000000000000000000000000055534400000000005B812C9D57731E27A2DA8B1830195F88EF32A3B6", + XRPLPaymentAmount::Token(XRPLToken { + issuer: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + currency: "USD".to_string().try_into()?, + }, canonicalize_coin_amount(Uint128::zero(), 0)?) + .xrpl_serialize()? + ); + assert_hex_eq!( + "D4838D7EA4C6800000000000000000000000000055534400000000005B812C9D57731E27A2DA8B1830195F88EF32A3B6", + XRPLPaymentAmount::Token(XRPLToken { + issuer: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + currency: "USD".to_string().try_into()?, + }, canonicalize_coin_amount(Uint128::one(), 0)?) + .xrpl_serialize()? + ); + // minimum absolute amount + assert_hex_eq!( + "C0438D7EA4C6800000000000000000000000000055534400000000005B812C9D57731E27A2DA8B1830195F88EF32A3B6", + XRPLPaymentAmount::Token(XRPLToken { + issuer: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + currency: "USD".to_string().try_into()? + }, XRPLTokenAmount::new(MIN_MANTISSA, MIN_EXPONENT)) + .xrpl_serialize()? + ); + // maximum amount + assert_hex_eq!( + "EC6386F26FC0FFFF00000000000000000000000055534400000000005B812C9D57731E27A2DA8B1830195F88EF32A3B6", + XRPLPaymentAmount::Token(XRPLToken { + issuer: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + currency: "USD".to_string().try_into()? + }, XRPLTokenAmount::new(MAX_MANTISSA, MAX_EXPONENT)) + .xrpl_serialize()? + ); + // currency cannot contain certain characters like ";" + assert!(XRPLCurrency::try_from("${;".to_string()).is_err()); + assert!(XRPLCurrency::try_from("XRP".to_string()).is_err()); + // currency can contain non-alphanumeric ascii letters + assert_hex_eq!( + "D4CEEBE0B40E8000000000000000000000000000247B7D00000000005B812C9D57731E27A2DA8B1830195F88EF32A3B6", + XRPLPaymentAmount::Token(XRPLToken { + issuer: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + currency: "${}".to_string().try_into()?, + }, canonicalize_coin_amount(Uint128::from(42u128), 0)?) + .xrpl_serialize()? + ); + // minimum XRP + assert_hex_eq!( + "4000000000000000", + XRPLPaymentAmount::Drops(0).xrpl_serialize()? + ); + assert_hex_eq!( + "4000000000000001", + XRPLPaymentAmount::Drops(1).xrpl_serialize()? + ); + assert_hex_eq!( + "40000000499602D2", + XRPLPaymentAmount::Drops(1234567890).xrpl_serialize()? + ); + // maximum XRP + assert_hex_eq!( + "416345785D8A0000", + XRPLPaymentAmount::Drops(100_000_000_000_000_000).xrpl_serialize()? + ); + // more than maximum XRP fails + assert!(XRPLPaymentAmount::Drops(100_000_000_000_000_001) + .xrpl_serialize() + .is_err()); + // account "0" (with length prefix) + assert_hex_eq!( + "140000000000000000000000000000000000000000", + XRPLAccountId::from_str("rrrrrrrrrrrrrrrrrrrrrhoLvTp")?.xrpl_serialize()? + ); + // account "1" (with length prefix) + assert_hex_eq!( + "140000000000000000000000000000000000000001", + XRPLAccountId::from_str("rrrrrrrrrrrrrrrrrrrrBZbvji")?.xrpl_serialize()? + ); + // max acccount + assert_hex_eq!( + "14FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + XRPLAccountId::from_str("rQLbzfJH5BT1FS9apRLKV3G8dWEA5njaQi")?.xrpl_serialize()? + ); + assert_hex_eq!( + "13000081140000000000000000000000000000000000000000", + XRPLSignerEntry { + account: XRPLAccountId::from_str("rrrrrrrrrrrrrrrrrrrrrhoLvTp")?, + signer_weight: 0 + } + .xrpl_serialize()? + ); + // { "NetworkID": 0 } + assert_hex_eq!( + "2100000000", + XRPLObject { + fields: vec![SerializedField::new(2, 1, 0u32.xrpl_serialize()?)] + } + .xrpl_serialize()? + ); + // empty array + assert_hex_eq!( + "F1", + XRPLArray:: { + field: Field::Memo, + items: vec![] + } + .xrpl_serialize()? + ); + // array with 1 element + assert_hex_eq!( + "EA13000081140000000000000000000000000000000000000000E1F1", + XRPLArray:: { + field: Field::Memo, + items: vec![XRPLSignerEntry { + account: XRPLAccountId::from_str("rrrrrrrrrrrrrrrrrrrrrhoLvTp")?, + signer_weight: 0 + },] + } + .xrpl_serialize()? + ); + Ok(()) + } + + #[test] + fn serialize_xrpl_unsigned_token_payment_transaction() -> Result<(), ContractError> { + let unsigned_tx = XRPLPaymentTx { + account: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + fee: 12, + sequence: XRPLSequence::Plain(1), + amount: XRPLPaymentAmount::Token( + XRPLToken { + currency: "JPY".to_string().try_into()?, + issuer: XRPLAccountId::from_str("rrrrrrrrrrrrrrrrrrrrBZbvji")?, + }, + XRPLTokenAmount::new(3369568318000000u64, -16), + ), + destination: XRPLAccountId::from_str("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")?, + }; + let encoded_unsigned_tx = XRPLUnsignedTx::Payment(unsigned_tx).xrpl_serialize()?; + assert_eq!( + "1200002200000000240000000161D44BF89AC2A40B800000000000000000000000004A50590000000000000000000000000000000000000000000000000168400000000000000C730081145B812C9D57731E27A2DA8B1830195F88EF32A3B68314B5F762798A53D543A014CAF8B297CFF8F2F937E8", + hex::encode_upper(encoded_unsigned_tx) + ); + Ok(()) + } + + #[test] + fn serialize_xrpl_unsigned_xrp_payment_transaction() -> Result<(), ContractError> { + let tx = XRPLPaymentTx { + account: XRPLAccountId::from_str("r9LqNeG6qHxjeUocjvVki2XR35weJ9mZgQ")?, + fee: 10, + sequence: XRPLSequence::Plain(1), + amount: XRPLPaymentAmount::Drops(1000), + destination: XRPLAccountId::from_str("rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh")?, + }; + let encoded_unsigned_tx = &XRPLUnsignedTx::Payment(tx).xrpl_serialize()?; + assert_eq!( + "120000220000000024000000016140000000000003E868400000000000000A730081145B812C9D57731E27A2DA8B1830195F88EF32A3B68314B5F762798A53D543A014CAF8B297CFF8F2F937E8", + hex::encode_upper(encoded_unsigned_tx) + ); + + let tx = XRPLPaymentTx { + account: XRPLAccountId::from_str("rhKnz85JUKcrAizwxNUDfqCvaUi9ZMhuwj")?, + fee: 3, + sequence: XRPLSequence::Plain(43497363), + amount: XRPLPaymentAmount::Drops(1000000000), + destination: XRPLAccountId::from_str("rw2521mDNXyKzHBrFGZ5Rj4wzUjS9FbiZq")?, + }; + let encoded_unsigned_tx = &XRPLUnsignedTx::Payment(tx).xrpl_serialize()?; + assert_eq!( + "1200002200000000240297B79361400000003B9ACA0068400000000000000373008114245409103F1B06F22FBCED389AAE0EFCE2F6689A83146919924835FA51D3991CDF5CF4505781227686E6", + hex::encode_upper(encoded_unsigned_tx) + ); + Ok(()) + } + + fn pub_key_from_hex(hex: &str) -> Result { + Ok(PublicKey::Ecdsa(HexBinary::from_hex(hex)?)) + } + + #[test] + fn serialize_xrpl_signed_xrp_payment_transaction() -> Result<(), ContractError> { + let signed_tx = XRPLSignedTransaction { + unsigned_tx: XRPLUnsignedTx::Payment(XRPLPaymentTx { + account: XRPLAccountId::from_str("rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb")?, + fee: 30, + sequence: XRPLSequence::Ticket(44218193), + amount: XRPLPaymentAmount::Drops(100000000), + destination: XRPLAccountId::from_str("rfgqgX62inhKsfti1NR6FeMS8NcQJCFniG")?, + }), signers: vec![ + XRPLSigner{ + account: XRPLAccountId::from_str("r3mJFUQeVQma7qucT4iQSNCWuijVCPcicZ")?, + txn_signature: HexBinary::from_hex("3044022023DD4545108D411008FC9A76A58E1573AB0F8786413C8F38A92B1E2EAED60014022012A0A7890BFD0F0C8EA2C342107F65D4C91CAC29AAF3CF2840350BF3FB91E045")?, + signing_pub_key: pub_key_from_hex("025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC008856")? + }, + XRPLSigner{ + account: XRPLAccountId::from_str("rHxbKjRSFUUyuiio1jnFhimJRVAYYaGj7f")?, + txn_signature: HexBinary::from_hex("3045022100FC1490C236AD05A306EB5FD89072F14FEFC19ED35EB61BACD294D10E0910EDB102205A4CF0C0A759D7158A8FEE2F526C70277910DE88BF85564A1B3142AE635C9CE9")?, + signing_pub_key: pub_key_from_hex("036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE")? + } + ], + }; + let encoded_signed_tx = &signed_tx.xrpl_serialize()?; + assert_eq!( + "12000022000000002400000000202902A2B751614000000005F5E10068400000000000001E73008114447BB6E37CA4D5D89FC2E2470A64632DA9BDD9E4831449599D50E0C1AC0CFC8D3B2A30830F3738EACC3EF3E0107321025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC00885674463044022023DD4545108D411008FC9A76A58E1573AB0F8786413C8F38A92B1E2EAED60014022012A0A7890BFD0F0C8EA2C342107F65D4C91CAC29AAF3CF2840350BF3FB91E0458114552A0D8EFCF978186CA9C37112B502D3728DA9EFE1E0107321036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE74473045022100FC1490C236AD05A306EB5FD89072F14FEFC19ED35EB61BACD294D10E0910EDB102205A4CF0C0A759D7158A8FEE2F526C70277910DE88BF85564A1B3142AE635C9CE98114BA058AB3573EA34DC934D60E719A12DE6C213DE2E1F1", + hex::encode_upper(encoded_signed_tx) + ); + Ok(()) + } + + #[test] + fn tx_serialization_sort_signers() -> Result<(), ContractError> { + let signed_tx = XRPLSignedTransaction { + unsigned_tx: XRPLUnsignedTx::Payment(XRPLPaymentTx { + account: XRPLAccountId::from_str("rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb")?, + fee: 30, + sequence: XRPLSequence::Ticket(44218193), + amount: XRPLPaymentAmount::Drops(100000000), + destination: XRPLAccountId::from_str("rfgqgX62inhKsfti1NR6FeMS8NcQJCFniG")?, + }), signers: vec![ + XRPLSigner{ + account: XRPLAccountId::from_str("rHxbKjRSFUUyuiio1jnFhimJRVAYYaGj7f")?, + txn_signature: HexBinary::from_hex("3045022100FC1490C236AD05A306EB5FD89072F14FEFC19ED35EB61BACD294D10E0910EDB102205A4CF0C0A759D7158A8FEE2F526C70277910DE88BF85564A1B3142AE635C9CE9")?, + signing_pub_key: pub_key_from_hex("036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE")? + }, + XRPLSigner{ + account: XRPLAccountId::from_str("r3mJFUQeVQma7qucT4iQSNCWuijVCPcicZ")?, + txn_signature: HexBinary::from_hex("3044022023DD4545108D411008FC9A76A58E1573AB0F8786413C8F38A92B1E2EAED60014022012A0A7890BFD0F0C8EA2C342107F65D4C91CAC29AAF3CF2840350BF3FB91E045")?, + signing_pub_key: pub_key_from_hex("025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC008856")? + }, + ], + }; + let encoded_signed_tx = &signed_tx.xrpl_serialize()?; + assert_eq!( + "12000022000000002400000000202902A2B751614000000005F5E10068400000000000001E73008114447BB6E37CA4D5D89FC2E2470A64632DA9BDD9E4831449599D50E0C1AC0CFC8D3B2A30830F3738EACC3EF3E0107321025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC00885674463044022023DD4545108D411008FC9A76A58E1573AB0F8786413C8F38A92B1E2EAED60014022012A0A7890BFD0F0C8EA2C342107F65D4C91CAC29AAF3CF2840350BF3FB91E0458114552A0D8EFCF978186CA9C37112B502D3728DA9EFE1E0107321036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE74473045022100FC1490C236AD05A306EB5FD89072F14FEFC19ED35EB61BACD294D10E0910EDB102205A4CF0C0A759D7158A8FEE2F526C70277910DE88BF85564A1B3142AE635C9CE98114BA058AB3573EA34DC934D60E719A12DE6C213DE2E1F1", + hex::encode_upper(encoded_signed_tx) + ); + Ok(()) + } + + #[test] + fn tx_serialization_ed25519_signers() -> Result<(), ContractError> { + let signed_tx = XRPLSignedTransaction { + unsigned_tx: XRPLUnsignedTx::Payment(XRPLPaymentTx { + account: XRPLAccountId::from_str("r4ZMbbb4Y3KoeexmjEeTdhqUBrYjjWdyGM")?, + fee: 30, + sequence: XRPLSequence::Ticket(45205896), + amount: XRPLPaymentAmount::Token(XRPLToken{ + currency: "ETH".to_string().try_into()?, + issuer: XRPLAccountId::from_str("r4ZMbbb4Y3KoeexmjEeTdhqUBrYjjWdyGM")? + }, canonicalize_coin_amount(Uint128::from(100000000u128), 0)?), + destination: XRPLAccountId::from_str("raNVNWvhUQzFkDDTdEw3roXRJfMJFVJuQo")?, + }), signers: vec![ + XRPLSigner{ + account: XRPLAccountId::from_str("rBTmbPMAWghUv52pCCtkLYh5SPVy2PuDSj")?, + txn_signature: HexBinary::from_hex("531B9E854C81AEFA573C00DF1603C3DE80C1F3680D39A80F3FB725A0388D177E3EC5E28AD6760D9EEF8203FEB1FC61F9D9451F777114B97943E5702B54589E09")?, + signing_pub_key: PublicKey::Ed25519(HexBinary::from_hex("45e67eaf446e6c26eb3a2b55b64339ecf3a4d1d03180bee20eb5afdd23fa644f")?) + }, + XRPLSigner{ + account: XRPLAccountId::from_str("rhAdaMDgF89314TfNRHc5GsA6LQZdk35S5")?, + txn_signature: HexBinary::from_hex("76CF2097D7038B90445CB952AE52CBDBE6D55FE7C0562493FE3D9AAE5E05A66A43777CBCDAA89233CAFD4D1D0F9B02DB0619B9BB14957CC3ADAA8D7D343E0106")?, + signing_pub_key: PublicKey::Ed25519(HexBinary::from_hex("dd9822c7fa239dda9913ebee813ecbe69e35d88ff651548d5cc42c033a8a667b")?) + }, + ], + }; + let encoded_signed_tx = &signed_tx.xrpl_serialize()?; + assert_eq!( + "12000022000000002400000000202902B1C98861D6838D7EA4C680000000000000000000000000004554480000000000EC792533BC26024CFAA5DDC2D04128E59581309C68400000000000001E73008114EC792533BC26024CFAA5DDC2D04128E59581309C831439659AAAD4DC8603798352FCF954419A67977536F3E0107321EDDD9822C7FA239DDA9913EBEE813ECBE69E35D88FF651548D5CC42C033A8A667B744076CF2097D7038B90445CB952AE52CBDBE6D55FE7C0562493FE3D9AAE5E05A66A43777CBCDAA89233CAFD4D1D0F9B02DB0619B9BB14957CC3ADAA8D7D343E010681142B3CF7B1986F5CB4EFEF11F933F40EC3106412C2E1E0107321ED45E67EAF446E6C26EB3A2B55B64339ECF3A4D1D03180BEE20EB5AFDD23FA644F7440531B9E854C81AEFA573C00DF1603C3DE80C1F3680D39A80F3FB725A0388D177E3EC5E28AD6760D9EEF8203FEB1FC61F9D9451F777114B97943E5702B54589E09811472C14C0DB6CEF64A87CC3D152D7B0E917D372BE7E1F1", + hex::encode_upper(encoded_signed_tx) + ); + Ok(()) + } + + #[test] + fn serialize_xrpl_signed_xrp_ticket_create_transaction() -> Result<(), ContractError> { + let signed_tx = XRPLSignedTransaction { + unsigned_tx: XRPLUnsignedTx::TicketCreate(XRPLTicketCreateTx { + account: XRPLAccountId::from_str("rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb")?, + fee: 30, + sequence: XRPLSequence::Plain(44218194), + ticket_count: 3, + }), signers: vec![ + XRPLSigner{ + account: XRPLAccountId::from_str("r3mJFUQeVQma7qucT4iQSNCWuijVCPcicZ")?, + txn_signature: HexBinary::from_hex("304402203C10D5295AE4A34FD702355B075E951CF9FFE3A73F8B7557FB68E5DF64D87D3702200945D65BAAD7F10A14EA57E08914005F412709D10F27D868D63BE3052F30363F")?, + signing_pub_key: pub_key_from_hex("025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC008856")? + }, + XRPLSigner{ + account: XRPLAccountId::from_str("rHxbKjRSFUUyuiio1jnFhimJRVAYYaGj7f")?, + txn_signature: HexBinary::from_hex("3045022100EF2CBAC3B2D81E1E3502B064BA198D9D0D3F1FFE6604DAC5019C53C262B5F9E7022000808A438BD5CA808649DCDA6766D2BA0E8FA7E94150675F73FC41B2F73C9C58")?, + signing_pub_key: pub_key_from_hex("036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE")? + }, + ] + }; + let encoded_signed_tx = signed_tx.xrpl_serialize()?; + assert_eq!( + "12000A22000000002402A2B75220280000000368400000000000001E73008114447BB6E37CA4D5D89FC2E2470A64632DA9BDD9E4F3E0107321025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC0088567446304402203C10D5295AE4A34FD702355B075E951CF9FFE3A73F8B7557FB68E5DF64D87D3702200945D65BAAD7F10A14EA57E08914005F412709D10F27D868D63BE3052F30363F8114552A0D8EFCF978186CA9C37112B502D3728DA9EFE1E0107321036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE74473045022100EF2CBAC3B2D81E1E3502B064BA198D9D0D3F1FFE6604DAC5019C53C262B5F9E7022000808A438BD5CA808649DCDA6766D2BA0E8FA7E94150675F73FC41B2F73C9C588114BA058AB3573EA34DC934D60E719A12DE6C213DE2E1F1", + hex::encode_upper(encoded_signed_tx) + ); + Ok(()) + } + + #[test] + fn serialize_xrpl_signed_signer_list_set_transaction() -> Result<(), ContractError> { + let signed_tx = XRPLSignedTransaction { + unsigned_tx: XRPLUnsignedTx::SignerListSet(XRPLSignerListSetTx { + account: XRPLAccountId::from_str("rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb")?, + fee: 30, + sequence: XRPLSequence::Plain(44218445), + signer_quorum: 3, + signer_entries: vec![ + XRPLSignerEntry{ + account: XRPLAccountId::from_str("r3mJFUQeVQma7qucT4iQSNCWuijVCPcicZ")?, + signer_weight: 2 + }, + XRPLSignerEntry{ + account: XRPLAccountId::from_str("rHxbKjRSFUUyuiio1jnFhimJRVAYYaGj7f")?, + signer_weight: 1 + } + ], + }), signers: vec![ + XRPLSigner{ + account: XRPLAccountId::from_str("r3mJFUQeVQma7qucT4iQSNCWuijVCPcicZ")?, + txn_signature: HexBinary::from_hex("3045022100B94B346A418BE9EF5AEE7806EE984E3E9B48EB4ED48E79B5BFB69C607167023E02206B14BD72B69206D14DADA82ACCDD2539D275719FB187ECE2A46BAC9025877B39")?, + signing_pub_key: pub_key_from_hex("025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC008856")?, + }, + XRPLSigner{ + account: XRPLAccountId::from_str("rHxbKjRSFUUyuiio1jnFhimJRVAYYaGj7f")?, + txn_signature: HexBinary::from_hex("3044022072A1028FF972D9D6E950810AF72443EEE352ADB1BC54B1112983842C857C464502206D74A77387979A47863F08F9191611D142C2BD6B32D5C750EF58513C5669F21A")?, + signing_pub_key: pub_key_from_hex("036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE")?, + }, + ], + }; + let encoded_signed_tx = signed_tx.xrpl_serialize()?; + assert_eq!( + "12000C22000000002402A2B84D20230000000368400000000000001E73008114447BB6E37CA4D5D89FC2E2470A64632DA9BDD9E4F3E0107321025E0231BFAD810E5276E2CF9EB2F3F380CE0BDF6D84C3B6173499D3DDCC00885674473045022100B94B346A418BE9EF5AEE7806EE984E3E9B48EB4ED48E79B5BFB69C607167023E02206B14BD72B69206D14DADA82ACCDD2539D275719FB187ECE2A46BAC9025877B398114552A0D8EFCF978186CA9C37112B502D3728DA9EFE1E0107321036FF6F4B2BC5E08ABA924BD8FD986608F3685CA651A015B3D9D6A656DE14769FE74463044022072A1028FF972D9D6E950810AF72443EEE352ADB1BC54B1112983842C857C464502206D74A77387979A47863F08F9191611D142C2BD6B32D5C750EF58513C5669F21A8114BA058AB3573EA34DC934D60E719A12DE6C213DE2E1F1F4EB1300028114552A0D8EFCF978186CA9C37112B502D3728DA9EFE1EB1300018114BA058AB3573EA34DC934D60E719A12DE6C213DE2E1F1", + hex::encode_upper(encoded_signed_tx) + ); + Ok(()) + } +} diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 787424aea2..85edc00d1f 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -41,6 +41,7 @@ k256 = { version = "0.13.1", features = ["ecdsa"] } monitoring = { workspace = true } multisig = { workspace = true } multisig-prover = { workspace = true } +xrpl-multisig-prover = { workspace = true } report = { workspace = true } rewards = { workspace = true } serde = { workspace = true } diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 05de894a37..6ce0343f42 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -4,6 +4,7 @@ pub mod gateway_contract; pub mod monitoring_contract; pub mod multisig_contract; pub mod multisig_prover_contract; +pub mod xrpl_multisig_prover_contract; pub mod protocol; pub mod rewards_contract; pub mod service_registry_contract; diff --git a/integration-tests/src/xrpl_multisig_prover_contract.rs b/integration-tests/src/xrpl_multisig_prover_contract.rs new file mode 100644 index 0000000000..aaa5ef73f4 --- /dev/null +++ b/integration-tests/src/xrpl_multisig_prover_contract.rs @@ -0,0 +1,76 @@ +use crate::{contract::Contract, protocol::Protocol}; +use axelar_wasm_std::Threshold; +use cosmwasm_std::Addr; +use cw_multi_test::{ContractWrapper, Executor}; + +#[derive(Clone)] +pub struct XRPLMultisigProverContract { + pub contract_addr: Addr, + pub admin_addr: Addr, +} + +impl XRPLMultisigProverContract { + pub fn instantiate_contract( + protocol: &mut Protocol, + admin_address: Addr, + gateway_address: Addr, + voting_verifier_address: Addr, + xrpl_multisig_address: String, + ) -> Self { + let code = ContractWrapper::new( + xrpl_multisig_prover::contract::execute, + xrpl_multisig_prover::contract::instantiate, + xrpl_multisig_prover::contract::query, + ) + .with_reply(xrpl_multisig_prover::contract::reply); + let app = &mut protocol.app; + let code_id = app.store_code(Box::new(code)); + + let contract_addr = app + .instantiate_contract( + code_id, + Addr::unchecked("anyone"), + &xrpl_multisig_prover::msg::InstantiateMsg { + admin_address: admin_address.to_string(), + governance_address: protocol.governance_address.to_string(), + gateway_address: gateway_address.to_string(), + axelar_multisig_address: protocol.multisig.contract_addr.to_string(), + monitoring_address: protocol.monitoring.contract_addr.to_string(), + service_registry_address: protocol.service_registry.contract_addr.to_string(), + voting_verifier_address: voting_verifier_address.to_string(), + signing_threshold: Threshold::try_from((2, 3)).unwrap().try_into().unwrap(), + service_name: protocol.service_name.to_string(), + worker_set_diff_threshold: 0, + xrpl_fee: 30, + xrpl_multisig_address: xrpl_multisig_address.clone(), + ticket_count_threshold: 1, + next_sequence_number: 44218446, + last_assigned_ticket_number: 44218195, + available_tickets: vec![ + vec![], + (44218195..44218200).collect::>() + ].concat(), + xrp_denom: "uxrp".to_string(), + relayer_address: Addr::unchecked("relayer").to_string(), + }, + &[], + "xrpl_multisig_prover", + None, + ) + .unwrap(); + + XRPLMultisigProverContract { + contract_addr, + admin_addr: admin_address, + } + } +} + +impl Contract for XRPLMultisigProverContract { + type QMsg = xrpl_multisig_prover::msg::QueryMsg; + type ExMsg = xrpl_multisig_prover::msg::ExecuteMsg; + + fn contract_address(&self) -> Addr { + self.contract_addr.clone() + } +} diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index 8954f9df3e..101aceafda 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -1,11 +1,13 @@ -use cosmwasm_std::{Addr, HexBinary, Uint128}; - -use connection_router_api::{CrossChainId, Message}; +use axelar_wasm_std::VerificationStatus; +use connection_router_api::{Address, CrossChainId, Message}; +use cosmwasm_std::{Addr, Coin, HexBinary, Uint128}; +use multisig::key::KeyType; use integration_tests::contract::Contract; -use crate::test_utils::AXL_DENOMINATION; +use crate::test_utils::{ETH_DENOMINATION, AXL_DENOMINATION}; pub mod test_utils; + /// Tests that a single message can be routed fully through the protocol. Submits a message to the /// gateway, votes on the poll, routes the message to the outgoing gateway, triggers signing at the prover /// and signs via multisig. Also tests that rewards are distributed as expected for voting and signing. @@ -112,6 +114,213 @@ fn single_message_can_be_verified_and_routed_and_proven_and_rewards_are_distribu } #[test] +fn xrpl_ticket_create_can_be_proven() { + let (mut protocol, _, xrpl, workers, _) = test_utils::setup_xrpl_destination_test_case(); + + /* Create tickets */ + let session_id = test_utils::construct_xrpl_ticket_create_proof_and_sign( + &mut protocol, + &xrpl.multisig_prover, + &workers, + ); + + let proof = test_utils::get_xrpl_proof( + &mut protocol.app, + &xrpl.multisig_prover, + &session_id, + ); + assert!(matches!( + proof, + xrpl_multisig_prover::msg::GetProofResponse::Completed { .. } + )); + println!("TicketCreate proof: {:?}", proof); + + let xrpl_multisig_address = "rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb".to_string(); // TODO: fix duplicate definition + let proof_msgs = vec![Message { + destination_chain: xrpl.chain_name.clone(), + source_address: Address::try_from(xrpl_multisig_address.clone()).unwrap(), + destination_address: Address::try_from(xrpl_multisig_address).unwrap(), + cc_id: CrossChainId { + chain: xrpl.chain_name.clone(), + id: "9c2f220fe5ee650b3cd10b0a72af1206b3912afce8376214234354180198c5d5-0" + .to_string() + .try_into() + .unwrap(), + }, + payload_hash: [0; 32], + }]; + + let (poll_id, expiry) = test_utils::verify_messages( + &mut protocol.app, + &xrpl.gateway, + &proof_msgs, + ); + test_utils::vote_success_for_all_messages( + &mut protocol.app, + &xrpl.voting_verifier, + &proof_msgs, + &workers, + poll_id, + ); + test_utils::advance_at_least_to_height(&mut protocol.app, expiry); + test_utils::end_poll(&mut protocol.app, &xrpl.voting_verifier, poll_id); + + test_utils::xrpl_update_tx_status( + &mut protocol.app, + &xrpl.multisig_prover, + workers.iter().map(|w| (KeyType::Ecdsa, HexBinary::from(w.key_pair.encoded_verifying_key())).try_into().unwrap()).collect(), + session_id, + proof_msgs[0].cc_id.clone(), + VerificationStatus::SucceededOnChain + ); +} + +#[test] +fn payment_towards_xrpl_can_be_verified_and_routed_and_proven() { + let (mut protocol, source_chain, xrpl, workers, _) = test_utils::setup_xrpl_destination_test_case(); + + let msg = Message { + cc_id: CrossChainId { + chain: source_chain.chain_name.clone(), + id: "0xaff42a67c474758ce97bd9b69c395c6dc6019707b400e06c30b0878a9357b2ea-3" + .to_string() + .try_into() + .unwrap(), + }, + // TODO: should be 0x address + source_address: "rhKnz85JUKcrAizwxNUDfqCvaUi9ZMhuwj" + .to_string() + .try_into() + .unwrap(), + destination_address: "raNVNWvhUQzFkDDTdEw3roXRJfMJFVJuQo" + .to_string() + .try_into() + .unwrap(), + destination_chain: xrpl.chain_name.clone(), + // TODO: payload_hash? + payload_hash: [0; 32], + }; + let msg_id: CrossChainId = msg.cc_id.clone(); + let msgs = vec![msg.clone()]; + let msg_ids = vec![msg_id.clone()]; + + // start the flow by submitting the message to the gateway + let (poll_id, expiry) = + test_utils::verify_messages(&mut protocol.app, &source_chain.gateway, &msgs); + + // do voting + test_utils::vote_success_for_all_messages( + &mut protocol.app, + &source_chain.voting_verifier, + &msgs, + &workers, + poll_id, + ); + + test_utils::advance_at_least_to_height(&mut protocol.app, expiry); + + test_utils::end_poll(&mut protocol.app, &source_chain.voting_verifier, poll_id); + + // should be verified, now route + test_utils::route_messages(&mut protocol.app, &source_chain.gateway, &msgs); + + // check that the message can be found at the outgoing gateway + let found_msgs = + test_utils::get_messages_from_gateway(&mut protocol.app, &xrpl.gateway, &msg_ids); + assert_eq!(found_msgs, msgs); + + // trigger signing and submit all necessary signatures + let session_id = test_utils::construct_xrpl_payment_proof_and_sign( + &mut protocol, + &xrpl.multisig_prover, + msg, + &workers, + &[Coin { + denom: ETH_DENOMINATION.to_string(), + // amount: Uint128::MAX, + // amount: Uint128::from(10u128.pow(29)), // scaled down to 10^17 drops = max XRP + amount: Uint128::from(100000000u128) + }], + ); + + let proof = test_utils::get_xrpl_proof( + &mut protocol.app, + &xrpl.multisig_prover, + &session_id, + ); + println!("Payment proof: {:?}", proof); + assert!(matches!( + //proof.status, + proof, + xrpl_multisig_prover::msg::GetProofResponse::Completed { .. } + )); + + let xrpl_multisig_address = "rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb".to_string(); // TODO: fix duplicate definition + let proof_msgs = vec![Message { + destination_chain: xrpl.chain_name.clone(), + source_address: Address::try_from(xrpl_multisig_address).unwrap(), + destination_address: Address::try_from("raNVNWvhUQzFkDDTdEw3roXRJfMJFVJuQo".to_string()).unwrap(), + cc_id: CrossChainId { + chain: xrpl.chain_name.clone(), + id: "c5c80adaff8703e589988f68587535d5c5cac5a7d7b99f0507aee3de40201137-0" + .to_string() + .try_into() + .unwrap(), + }, + payload_hash: [0; 32], + }]; + + let (poll_id, expiry) = test_utils::verify_messages( + &mut protocol.app, + &xrpl.gateway, + &proof_msgs + ); + test_utils::vote_success_for_all_messages( + &mut protocol.app, + &xrpl.voting_verifier, + &proof_msgs, + &workers, + poll_id, + ); + test_utils::advance_at_least_to_height(&mut protocol.app, expiry); + test_utils::end_poll(&mut protocol.app, &xrpl.voting_verifier, poll_id); + + test_utils::xrpl_update_tx_status( + &mut protocol.app, + &xrpl.multisig_prover, + workers.iter().map(|w| (KeyType::Ecdsa, HexBinary::from(w.key_pair.encoded_verifying_key())).try_into().unwrap()).collect(), + session_id, + proof_msgs[0].cc_id.clone(), + VerificationStatus::SucceededOnChain + ); + + // Advance the height to be able to distribute rewards + test_utils::advance_height( + &mut protocol.app, + u64::from(protocol.rewards_params.epoch_duration) * 2, + ); + + test_utils::distribute_rewards(&mut protocol, &xrpl.chain_name, xrpl.voting_verifier.contract_addr.clone()); + test_utils::distribute_rewards(&mut protocol, &source_chain.chain_name, source_chain.voting_verifier.contract_addr.clone()); + + let protocol_multisig_address = protocol.multisig.contract_addr.clone(); + test_utils::distribute_rewards(&mut protocol, &source_chain.chain_name, protocol_multisig_address); + + // rewards split evenly amongst all workers, but there are two contracts that rewards should have been distributed for + let expected_rewards = Uint128::from(protocol.rewards_params.rewards_per_epoch) + / Uint128::from(workers.len() as u64) + * Uint128::from(2u64); + + for worker in workers { + let balance = protocol + .app + .wrap() + .query_balance(worker.addr, test_utils::AXL_DENOMINATION) + .unwrap(); + assert_eq!(balance.amount, expected_rewards); + } +} + fn routing_to_incorrect_gateway_interface() { let (mut protocol, chain1, chain2, _, _) = test_utils::setup_test_case(); diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 5a02311e4a..cdc380d46d 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -1,11 +1,14 @@ +use std::{fmt::Debug, ops::Add, str::FromStr}; + use axelar_wasm_std::{ nonempty, voting::{PollId, Vote}, Participant, Threshold, + VerificationStatus, }; use connection_router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; use cosmwasm_std::{ - coins, Addr, Attribute, BlockInfo, Event, HexBinary, StdError, Uint128, Uint256, Uint64, + coins, Addr, Attribute, BlockInfo, Coin, Event, HexBinary, StdError, Uint128, Uint256, Uint64 }; use cw_multi_test::{App, AppResponse, Executor}; @@ -14,6 +17,7 @@ use integration_tests::gateway_contract::GatewayContract; use integration_tests::monitoring_contract::MonitoringContract; use integration_tests::multisig_contract::MultisigContract; use integration_tests::multisig_prover_contract::MultisigProverContract; +use integration_tests::xrpl_multisig_prover_contract::XRPLMultisigProverContract; use integration_tests::rewards_contract::RewardsContract; use integration_tests::service_registry_contract::ServiceRegistryContract; use integration_tests::voting_verifier_contract::VotingVerifierContract; @@ -28,11 +32,14 @@ use multisig::{ worker_set::WorkerSet, }; use multisig_prover::encoding::{make_operators, Encoder}; +use xrpl_multisig_prover::types::{XRPLToken, XRPLAccountId}; use rewards::state::PoolId; use service_registry::msg::ExecuteMsg; use tofn::ecdsa::KeyPair; pub const AXL_DENOMINATION: &str = "uaxl"; +pub const XRP_DENOMINATION: &str = "uxrp"; +pub const ETH_DENOMINATION: &str = "ueth"; pub const SIGNATURE_BLOCK_EXPIRY: u64 = 100; @@ -261,6 +268,105 @@ pub fn register_service(protocol: &mut Protocol, min_worker_bond: Uint128) { assert!(response.is_ok()); } +pub fn construct_xrpl_ticket_create_proof_and_sign( + protocol: &mut Protocol, + multisig_prover: &XRPLMultisigProverContract, + workers: &Vec, +) -> Uint64 { + let response = multisig_prover.execute( + &mut protocol.app, + Addr::unchecked("relayer"), + &xrpl_multisig_prover::msg::ExecuteMsg::TicketCreate, + ); + assert!(response.is_ok()); + let response = response.unwrap(); + + sign_xrpl_proof(protocol, workers, response) +} + +pub fn construct_xrpl_payment_proof_and_sign( + protocol: &mut Protocol, + multisig_prover: &XRPLMultisigProverContract, + message: Message, + workers: &Vec, + coins: &[Coin], +) -> Uint64 { + let response = multisig_prover.execute( + &mut protocol.app, + Addr::unchecked("relayer"), + &xrpl_multisig_prover::msg::ExecuteMsg::ConstructProof { + message_id: message.cc_id.clone(), + coin: coins.to_vec().get(0).unwrap().clone(), // TODO: remove + }, + // coins, + ); + assert!(response.is_ok()); + let response = response.unwrap(); + + sign_xrpl_proof(protocol, workers, response) +} + +pub fn construct_xrpl_signer_list_set_proof_and_sign( + protocol: &mut Protocol, + multisig_prover: &XRPLMultisigProverContract, + workers: &Vec, +) -> Uint64 { + let response = multisig_prover.execute( + &mut protocol.app, + multisig_prover.admin_addr.clone(), + &xrpl_multisig_prover::msg::ExecuteMsg::UpdateWorkerSet, + ); + let response = response.unwrap(); + + sign_xrpl_proof(protocol, workers, response) +} + +pub fn sign_xrpl_proof( + protocol: &mut Protocol, + workers: &Vec, + response: AppResponse, +) -> Uint64 { + let session_id: Uint64 = + get_event_attribute(&response.events, "wasm-signing_started", "session_id") + .map(|attr| attr.value.as_str().try_into().unwrap()) + .expect("couldn't get session_id"); + + let unsigned_tx: HexBinary = + get_event_attribute(&response.events, "wasm-xrpl_signing_started", "unsigned_tx") + .map(|attr| HexBinary::from_hex(attr.value.as_str()).unwrap()) + .expect("couldn't get unsigned_tx"); + + for worker in workers { + let xrpl_signer_address = XRPLAccountId::from( + &multisig::key::PublicKey::Ecdsa(worker.key_pair.encoded_verifying_key().into()) + ); + + let msg = xrpl_multisig_prover::xrpl_multisig::message_to_sign(&unsigned_tx, &xrpl_signer_address).unwrap(); + + let signature = tofn::ecdsa::sign( + worker.key_pair.signing_key(), + &msg + .as_slice() + .try_into() + .unwrap(), + ) + .unwrap(); + + let response = protocol.multisig.execute( + &mut protocol.app, + worker.addr.clone(), + &multisig::msg::ExecuteMsg::SubmitSignature { + session_id, + // TODO: why from_der and then back to_der? + signature: HexBinary::from(ecdsa::Signature::from_der(&signature).unwrap().to_vec()), + }, + ); + assert!(response.is_ok()); + } + + session_id +} + pub fn get_messages_from_gateway( app: &mut App, gateway: &GatewayContract, @@ -319,6 +425,55 @@ pub fn get_worker_set_from_monitoring( query_response.unwrap() } +pub fn get_xrpl_worker_set_from_prover( + app: &mut App, + multisig_prover: &XRPLMultisigProverContract, +) -> multisig::worker_set::WorkerSet { + let query_response: Result<_, StdError> = multisig_prover.query( + app, + &xrpl_multisig_prover::msg::QueryMsg::GetWorkerSet, + ); + assert!(query_response.is_ok()); + query_response.unwrap() +} + +pub fn get_xrpl_proof( + app: &mut App, + multisig_prover: &XRPLMultisigProverContract, + multisig_session_id: &Uint64, +) -> xrpl_multisig_prover::msg::GetProofResponse { + let query_response: Result = multisig_prover.query( + app, + &xrpl_multisig_prover::msg::QueryMsg::GetProof { + multisig_session_id: *multisig_session_id, + }, + ); + assert!(query_response.is_ok()); + query_response.unwrap() +} + +pub fn xrpl_update_tx_status( + app: &mut App, + multisig_prover: &XRPLMultisigProverContract, + signer_public_keys: Vec, + multisig_session_id: Uint64, + message_id: CrossChainId, + message_status: VerificationStatus, +) { + let response = multisig_prover.execute( + app, + Addr::unchecked("relayer"), + &xrpl_multisig_prover::msg::ExecuteMsg::UpdateTxStatus { + message_status, + multisig_session_id, + message_id, + signer_public_keys, + }, + ); + println!("xrpl_update_tx_status res: {:?}", response); + assert!(response.is_ok()); +} + #[allow(clippy::arithmetic_side_effects)] pub fn advance_height(app: &mut App, increment: u64) { let cur_block = app.block_info(); @@ -355,12 +510,32 @@ pub fn distribute_rewards(protocol: &mut Protocol, chain_name: &ChainName, contr pub fn setup_protocol(service_name: nonempty::String) -> Protocol { let genesis = Addr::unchecked("genesis"); + // TODO: return relayer + let relayer = Addr::unchecked("relayer"); + let xrpl_init_coins = vec![ + coins(u128::MAX, XRP_DENOMINATION), + coins(u128::MAX, ETH_DENOMINATION), + ].concat(); let mut app = App::new(|router, _, storage| { router .bank - .init_balance(storage, &genesis, coins(u128::MAX, AXL_DENOMINATION)) - .unwrap() + .init_balance( + storage, + &genesis, + vec![ + coins(u128::MAX, AXL_DENOMINATION), + xrpl_init_coins.clone(), + ].concat()) + .unwrap(); }); + + let response = app.send_tokens( + genesis.clone(), + relayer, + &xrpl_init_coins, + ); + + assert!(response.is_ok()); let router_admin_address = Addr::unchecked("admin"); let governance_address = Addr::unchecked("governance"); let nexus_gateway = Addr::unchecked("nexus_gateway"); @@ -420,6 +595,7 @@ pub fn generate_key(seed: u32) -> KeyPair { tofn::ecdsa::keygen(&secret_recovery_key, b"tofn nonce").unwrap() } +#[derive(Debug)] pub struct Worker { pub addr: Addr, pub supported_chains: Vec, @@ -595,6 +771,42 @@ pub fn workers_to_worker_set(protocol: &mut Protocol, workers: &Vec) -> ) } +// TODO: fix duplication +pub fn xrpl_workers_to_worker_set(protocol: &mut Protocol, workers: &Vec) -> WorkerSet { + // get public keys + let mut pub_keys = vec![]; + for worker in workers { + let encoded_verifying_key = + HexBinary::from(worker.key_pair.encoded_verifying_key().to_vec()); + let pub_key = PublicKey::try_from((KeyType::Ecdsa, encoded_verifying_key)).unwrap(); + pub_keys.push(pub_key); + } + + // turn into participants + let participants: Vec = workers + .iter() + .map(|worker| Participant { + address: worker.addr.clone(), + weight: Uint256::from(65535u128).try_into().unwrap(), + }) + .collect(); + + let total_weight = participants + .iter() + .fold( + Uint256::zero(), + |acc, p| acc.add(Uint256::from(p.weight)) + ); + + let pubkeys_by_participant = participants.into_iter().zip(pub_keys).collect(); + + WorkerSet::new( + pubkeys_by_participant, + total_weight.mul_ceil((2u64, 3u64)).into(), + protocol.app.block_info().height, + ) +} + pub fn create_new_workers_vec( chains: Vec, worker_details: Vec<(String, u32)>, @@ -667,6 +879,14 @@ pub struct Chain { pub chain_name: ChainName, } +#[derive(Clone)] +pub struct XRPLChain { + pub gateway: GatewayContract, + pub voting_verifier: VotingVerifierContract, + pub multisig_prover: XRPLMultisigProverContract, + pub chain_name: ChainName, +} + pub fn setup_chain(protocol: &mut Protocol, chain_name: ChainName) -> Chain { let voting_verifier = VotingVerifierContract::instantiate_contract( protocol, @@ -760,6 +980,143 @@ pub fn setup_chain(protocol: &mut Protocol, chain_name: ChainName) -> Chain { } } +pub fn register_xrpl_token( + protocol: &mut Protocol, + multisig_prover: &XRPLMultisigProverContract, + denom: String, + token: XRPLToken, + decimals: u8, +) { + let response = multisig_prover.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &xrpl_multisig_prover::msg::ExecuteMsg::RegisterToken { + denom, + token, + decimals, + }, + ); + assert!(response.is_ok()); +} + +pub fn setup_xrpl(protocol: &mut Protocol) -> XRPLChain { + let chain_name = ChainName::from_str("XRPL").unwrap(); + + let voting_verifier = VotingVerifierContract::instantiate_contract( + protocol, + "doesn't matter".to_string().try_into().unwrap(), + Threshold::try_from((9, 10)).unwrap().try_into().unwrap(), + chain_name.clone(), + ); + + let gateway= GatewayContract::instantiate_contract( + &mut protocol.app, + protocol.connection_router.contract_address().clone(), + voting_verifier.contract_addr.clone(), + ); + + let xrpl_multisig_address = "rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb".to_string(); // TODO: fix duplicate definition + let multisig_prover_admin = Addr::unchecked(chain_name.to_string() + "prover_admin"); + let multisig_prover = XRPLMultisigProverContract::instantiate_contract( + protocol, + multisig_prover_admin.clone(), + gateway.contract_addr.clone(), + voting_verifier.contract_addr.clone(), + xrpl_multisig_address.clone(), + //chain_name.to_string(), + + /*voting_verifier_address: voting_verifier_address.to_string(), + signing_threshold: (2, 3).try_into().unwrap(), + service_name: protocol.service_name.to_string(), + worker_set_diff_threshold: 1, + xrpl_fee: 30, + xrpl_multisig_address: xrpl_multisig_address.clone(), + ticket_count_threshold: 1, + next_sequence_number: 44218446, + last_assigned_ticket_number: 44218195, + available_tickets: vec![ + vec![], + (44218195..44218200).collect::>() + ].concat(), + governance_address: protocol.governance_address.to_string(), + relayer_address: Addr::unchecked("relayer").to_string(), + xrp_denom: "uxrp".to_string(),*/ + ); + + register_xrpl_token( + protocol, + &multisig_prover, + ETH_DENOMINATION.to_string(), + XRPLToken { + issuer: XRPLAccountId::from_str(xrpl_multisig_address.as_str()).unwrap(), + currency: "ETH".to_string().try_into().unwrap(), + }, + 18u8, + ); + + let response = protocol.multisig.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &multisig::msg::ExecuteMsg::AuthorizeCaller { + contract_address: multisig_prover.contract_addr.clone(), + }, + ); + assert!(response.is_ok()); + + let response = protocol.connection_router.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &connection_router_api::msg::ExecuteMsg::RegisterChain { + chain: chain_name.clone(), + gateway_address: gateway.contract_addr.to_string().try_into().unwrap(), + }, + ); + assert!(response.is_ok()); + + let response = protocol.rewards.execute_with_funds( + &mut protocol.app, + protocol.genesis_address.clone(), + &rewards::msg::ExecuteMsg::AddRewards { + pool_id: PoolId { + chain_name: chain_name.clone(), + contract: voting_verifier.contract_addr.clone(), + }, + }, + &coins(1000, AXL_DENOMINATION), + ); + assert!(response.is_ok()); + + let response = protocol.rewards.execute_with_funds( + &mut protocol.app, + protocol.genesis_address.clone(), + &rewards::msg::ExecuteMsg::AddRewards { + pool_id: PoolId { + chain_name: chain_name.clone(), + contract: protocol.multisig.contract_addr.clone(), + }, + }, + &coins(1000, AXL_DENOMINATION), + ); + assert!(response.is_ok()); + + let response = protocol.monitoring.execute( + &mut protocol.app, + protocol.governance_address.clone(), + &MonitoringExecuteMsg::RegisterProverContract { + chain_name: chain_name.clone(), + new_prover_addr: multisig_prover.contract_addr.clone(), + }, + ); + assert!(response.is_ok()); + + XRPLChain { + gateway, + voting_verifier, + multisig_prover, + chain_name, + } +} + // Creates an instance of Axelar Amplifier with an initial worker set registered, and returns the instance, the chains, the workers, and the minimum worker bond. pub fn setup_test_case() -> (Protocol, Chain, Chain, Vec, Uint128) { let mut protocol = setup_protocol("validators".to_string().try_into().unwrap()); @@ -788,6 +1145,33 @@ pub fn setup_test_case() -> (Protocol, Chain, Chain, Vec, Uint128) { (protocol, chain1, chain2, workers, min_worker_bond) } +pub fn setup_xrpl_destination_test_case() -> (Protocol, Chain, XRPLChain, Vec, Uint128) { + let mut protocol = setup_protocol("validators".to_string().try_into().unwrap()); + let chains = vec![ + "Ethereum".to_string().try_into().unwrap(), + "XRPL".to_string().try_into().unwrap(), + ]; + let workers = vec![ + Worker { + addr: Addr::unchecked("worker1"), + supported_chains: chains.clone(), + key_pair: generate_key(0), + }, + Worker { + addr: Addr::unchecked("worker2"), + supported_chains: chains.clone(), + key_pair: generate_key(1), + }, + ]; + let min_worker_bond = Uint128::new(100); + register_service(&mut protocol, min_worker_bond); + + register_workers(&mut protocol, &workers, min_worker_bond); + let source_chain = setup_chain(&mut protocol, chains.first().unwrap().clone()); + let xrpl = setup_xrpl(&mut protocol); + (protocol, source_chain, xrpl, workers, min_worker_bond) +} + pub fn assert_contract_err_strings_equal( actual: impl Into, expected: impl Into, diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index b22926e2ca..0393d16c2a 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -1,6 +1,8 @@ -use cosmwasm_std::Addr; +use connection_router_api::{Address, CrossChainId, Message}; +use cosmwasm_std::{Addr, HexBinary}; +use axelar_wasm_std::VerificationStatus; use cw_multi_test::Executor; - +use multisig::key::KeyType; use integration_tests::contract::Contract; use multisig_prover::msg::ExecuteMsg; use test_utils::Worker; @@ -93,8 +95,8 @@ fn worker_set_can_be_initialized_and_then_manually_updated() { ðereum.multisig_prover, ); - let new_worker_set = - test_utils::get_worker_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + let new_worker_set = test_utils::get_worker_set_from_prover(&mut protocol.app, ðereum.multisig_prover); + assert_eq!(new_worker_set, expected_new_worker_set); let monitoring_worker_set = test_utils::get_worker_set_from_monitoring( @@ -105,6 +107,114 @@ fn worker_set_can_be_initialized_and_then_manually_updated() { assert_eq!(monitoring_worker_set, expected_new_worker_set); } +#[test] +fn xrpl_worker_set_can_be_initialized_and_then_manually_updated() { + let chains: Vec = vec![ + "Ethereum".to_string().try_into().unwrap(), + "XRPL".to_string().try_into().unwrap(), + ]; + let (mut protocol, _, xrpl, initial_workers, min_worker_bond) = + test_utils::setup_xrpl_destination_test_case(); + + let simulated_worker_set = test_utils::xrpl_workers_to_worker_set(&mut protocol, &initial_workers); + + let worker_set = + test_utils::get_xrpl_worker_set_from_prover(&mut protocol.app, &xrpl.multisig_prover); + + assert_eq!(worker_set, simulated_worker_set); + + // add third and fourth worker + let mut new_workers = Vec::new(); + let new_worker = Worker { + addr: Addr::unchecked("worker3"), + supported_chains: chains.clone(), + key_pair: test_utils::generate_key(2), + }; + new_workers.push(new_worker); + let new_worker = Worker { + addr: Addr::unchecked("worker4"), + supported_chains: chains.clone(), + key_pair: test_utils::generate_key(3), + }; + new_workers.push(new_worker); + + let expected_new_worker_set = test_utils::xrpl_workers_to_worker_set(&mut protocol, &new_workers); + + test_utils::register_workers(&mut protocol, &new_workers, min_worker_bond); + + // remove old workers + test_utils::deregister_workers(&mut protocol, &initial_workers); + + let session_id = test_utils::construct_xrpl_signer_list_set_proof_and_sign( + &mut protocol, + &xrpl.multisig_prover, + &initial_workers, + ); + + let proof = test_utils::get_xrpl_proof( + &mut protocol.app, + &xrpl.multisig_prover, + &session_id, + ); + assert!(matches!( + proof, + xrpl_multisig_prover::msg::GetProofResponse::Completed { .. } + )); + println!("SignerListSet proof: {:?}", proof); + + let xrpl_multisig_address = "rfEf91bLxrTVC76vw1W3Ur8Jk4Lwujskmb".to_string(); // TODO: fix duplicate definition + let proof_msgs = vec![Message { + destination_chain: xrpl.chain_name.clone(), + source_address: Address::try_from(xrpl_multisig_address.clone()).unwrap(), + destination_address: Address::try_from(xrpl_multisig_address).unwrap(), + cc_id: CrossChainId { + chain: xrpl.chain_name.clone(), + id: "fbf428da41656ca3aef36287bfcb6d8491daa76f20c201c4a60172450ab517f9-0" + .to_string() + .try_into() + .unwrap(), + }, + payload_hash: [0; 32], + }]; + + // TODO: verify_message_statuses should be called through gateway, like verify_messages + let (poll_id, expiry) = test_utils::verify_messages( + &mut protocol.app, + &xrpl.gateway, + &proof_msgs + ); + test_utils::vote_success_for_all_messages( + &mut protocol.app, + &xrpl.voting_verifier, + &proof_msgs, + &new_workers, + poll_id, + ); + test_utils::advance_at_least_to_height(&mut protocol.app, expiry); + test_utils::end_poll(&mut protocol.app, &xrpl.voting_verifier, poll_id); + + test_utils::xrpl_update_tx_status( + &mut protocol.app, + &xrpl.multisig_prover, + initial_workers.iter().map(|w| (KeyType::Ecdsa, HexBinary::from(w.key_pair.encoded_verifying_key())).try_into().unwrap()).collect(), + session_id, + proof_msgs[0].cc_id.clone(), + VerificationStatus::SucceededOnChain + ); + + let new_worker_set = + test_utils::get_xrpl_worker_set_from_prover(&mut protocol.app, &xrpl.multisig_prover); + + assert_eq!(new_worker_set, expected_new_worker_set); + + let monitoring_worker_set = test_utils::get_worker_set_from_monitoring( + &mut protocol.app, + &protocol.monitoring, + xrpl.chain_name, + ); + assert_eq!(monitoring_worker_set, expected_new_worker_set); +} + #[test] fn worker_set_cannot_be_updated_again_while_pending_worker_is_not_yet_confirmed() { let chains = vec![