diff --git a/Cargo.lock b/Cargo.lock index 467622f79..2e7d17489 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,23 +18,23 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli", + "gimli 0.27.3", ] [[package]] -name = "adler" -version = "1.0.2" +name = "addr2line" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli 0.28.1", +] [[package]] -name = "aead" -version = "0.3.2" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array 0.14.6", -] +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" @@ -42,8 +42,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array 0.14.6", - "rand_core 0.6.4", + "generic-array 0.14.7", ] [[package]] @@ -53,18 +52,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", - "generic-array 0.14.6", -] - -[[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher 0.2.5", + "generic-array 0.14.7", ] [[package]] @@ -76,14 +64,14 @@ dependencies = [ "cfg-if 1.0.0", "cipher 0.3.0", "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", ] [[package]] name = "aes" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if 1.0.0", "cipher 0.4.4", @@ -92,50 +80,30 @@ dependencies = [ [[package]] name = "aes-gcm" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" -dependencies = [ - "aead 0.4.3", - "aes 0.7.5", - "cipher 0.3.0", - "ctr 0.8.0", - "ghash 0.4.4", - "subtle", -] - -[[package]] -name = "aes-gcm" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e1366e0c69c9f927b1fa5ce2c7bf9eafc8f9268c0b9800729e8b267612447c" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead 0.5.2", - "aes 0.8.2", + "aes 0.8.4", "cipher 0.4.4", "ctr 0.9.2", - "ghash 0.5.0", + "ghash", "subtle", ] [[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug 0.3.0", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" +name = "aes-gcm-siv" +version = "0.10.3" +source = "git+https://github.com/RustCrypto/AEADs?rev=6105d7a5591aefa646a95d12b5e8d3f55a9214ef#6105d7a5591aefa646a95d12b5e8d3f55a9214ef" dependencies = [ - "cipher 0.2.5", - "opaque-debug 0.3.0", + "aead 0.4.3", + "aes 0.7.5", + "cipher 0.3.0", + "ctr 0.8.0", + "polyval 0.5.3", + "subtle", + "zeroize", ] [[package]] @@ -149,41 +117,239 @@ 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 0.2.8", + "getrandom 0.2.15", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "cd7d5a2cecb58716e47d67d5703a249964b14c7be1ec3cad3affc295b2d1c35d" dependencies = [ "cfg-if 1.0.0", - "getrandom 0.2.8", + "getrandom 0.2.15", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + [[package]] name = "always-assert" -version = "0.1.2" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4436e0292ab1bb631b42973c61205e704475fe8126af845c8d923c0996328127" + +[[package]] +name = "anchor-attribute-access-control" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-account" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "bs58 0.5.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-constant" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-error" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-event" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-attribute-program" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-client" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-lang", + "anyhow", + "bytemuck", + "futures", + "regex", + "serde", + "solana-account-decoder", + "solana-client", + "solana-sdk", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "anchor-derive-accounts" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-serde" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-syn", + "borsh-derive-internal 0.10.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-derive-space" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "anchor-lang" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anchor-attribute-access-control", + "anchor-attribute-account", + "anchor-attribute-constant", + "anchor-attribute-error", + "anchor-attribute-event", + "anchor-attribute-program", + "anchor-derive-accounts", + "anchor-derive-serde", + "anchor-derive-space", + "arrayref", + "base64 0.21.7", + "bincode", + "borsh 0.10.3", + "bytemuck", + "getrandom 0.2.15", + "solana-program", + "thiserror", +] + +[[package]] +name = "anchor-spl" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c4fd6e43b2ca6220d2ef1641539e678bfc31b6cc393cf892b373b5997b6a39a" +dependencies = [ + "anchor-lang", + "mpl-token-metadata", + "solana-program", + "spl-associated-token-account", + "spl-token", + "spl-token-2022 0.9.0", +] + +[[package]] +name = "anchor-syn" +version = "0.29.0" +source = "git+https://github.com/dhruvja/anchor#90a3008fcbbc5bcbc704cd6cccf61ef130c5f9eb" +dependencies = [ + "anyhow", + "bs58 0.5.1", + "heck 0.3.3", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.8", + "syn 1.0.109", + "thiserror", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf688625d06217d5b1bb0ea9d9c44a1635fd0ee3534466388d18203174f4d11" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] name = "android_system_properties" @@ -205,57 +371,58 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.69" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "approx" @@ -266,17 +433,11 @@ dependencies = [ "num-traits", ] -[[package]] -name = "arc-swap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" - [[package]] name = "argh" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab257697eb9496bf75526f0217b5ed64636a9cfafa78b8365c71bd283fcef93e" +checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219" dependencies = [ "argh_derive", "argh_shared", @@ -284,103 +445,207 @@ dependencies = [ [[package]] name = "argh_derive" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b382dbd3288e053331f03399e1db106c9fb0d8562ad62cb04859ae926f324fa6" +checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a" dependencies = [ "argh_shared", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] name = "argh_shared" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cb94155d965e3d37ffbbe7cc5b82c3dd79dd33bd48e536f73d2cfb8d85506f" +checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531" +dependencies = [ + "serde", +] [[package]] -name = "array-bytes" -version = "4.2.0" +name = "ark-bn254" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] [[package]] -name = "array-bytes" -version = "6.1.0" +name = "ark-ec" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools 0.10.5", + "num-traits", + "zeroize", +] [[package]] -name = "arrayref" -version = "0.3.6" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.5", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] [[package]] -name = "arrayvec" -version = "0.4.12" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "nodrop", + "quote", + "syn 1.0.109", ] [[package]] -name = "arrayvec" -version = "0.5.2" +name = "ark-ff-macros" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.5", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "arrayvec" -version = "0.7.2" +name = "ark-poly" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] [[package]] -name = "asn1-rs" -version = "0.3.1" +name = "ark-serialize" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ff05a702273012438132f449575dbc804e27b2f3cbe3069aa237d26c98fa33" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint 0.4.5", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ - "asn1-rs-derive 0.1.0", - "asn1-rs-impl", - "displaydoc", - "nom", "num-traits", - "rusticata-macros", - "thiserror", - "time 0.3.17", + "rand 0.8.5", +] + +[[package]] +name = "array-bytes" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52f63c5c1316a16a4b35eaac8b76a98248961a533f061684cb2a7cb0eafb6c6" + +[[package]] +name = "array-bytes" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f840fb7195bcfc5e17ea40c26e5ce6d5b9ce5d584466e17703209657e459ae0" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", ] +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "ascii" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" + [[package]] name = "asn1-rs" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" dependencies = [ - "asn1-rs-derive 0.4.0", + "asn1-rs-derive", "asn1-rs-impl", "displaydoc", "nom", "num-traits", "rusticata-macros", "thiserror", - "time 0.3.17", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8b7511298d5b7784b40b092d9e9dcd3a627a5707e4b5e507931ab0d44eeebf" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", + "time", ] [[package]] @@ -419,118 +684,145 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ "concurrent-queue", - "event-listener", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e9eabd7a98fe442131a17c316bd9349c43695e49e730c3c8e12cfb5f4da2693" +dependencies = [ + "brotli", + "flate2", "futures-core", + "memchr", + "pin-project-lite 0.2.14", + "tokio", ] [[package]] name = "async-io" -version = "1.12.0" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" +checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884" dependencies = [ - "async-lock", - "autocfg", + "async-lock 3.3.0", + "cfg-if 1.0.0", "concurrent-queue", + "futures-io", "futures-lite", - "libc", - "log", "parking", "polling", + "rustix 0.38.34", "slab", - "socket2 0.4.9", - "waker-fn", - "windows-sys 0.42.0", + "tracing", + "windows-sys 0.52.0", ] [[package]] name = "async-lock" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" dependencies = [ - "event-listener", - "futures-lite", + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy", + "pin-project-lite 0.2.14", +] + +[[package]] +name = "async-mutex" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" +dependencies = [ + "event-listener 2.5.3", ] [[package]] name = "async-recursion" -version = "1.0.5" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "async-stream" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", + "pin-project-lite 0.2.14", ] [[package]] name = "async-stream-impl" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[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", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "async-tungstenite" -version = "0.17.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb" +checksum = "1e0388bb7a400072bbb41ceb75d65c3baefb2ea99672fa22e85278452cd9b58b" dependencies = [ "futures-io", "futures-util", "log", - "pin-project-lite 0.2.13", - "rustls-native-certs 0.6.2", + "pin-project-lite 0.2.14", + "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.23.4", - "tungstenite 0.17.3", + "tungstenite 0.18.0", ] [[package]] name = "asynchronous-codec" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182" +checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" dependencies = [ "bytes", "futures-sink", "futures-util", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] -[[package]] -name = "atomic-waker" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" - [[package]] name = "atty" version = "0.2.14" @@ -544,15 +836,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "axum" -version = "0.6.4" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5694b64066a2459918d8074c2ce0d5a88f409431994c2356617c8ae0c4721fc" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", @@ -567,21 +859,20 @@ dependencies = [ "memchr", "mime", "percent-encoding", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "rustversion", "serde", "sync_wrapper", "tower", - "tower-http 0.3.5", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", @@ -596,16 +887,16 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ - "addr2line", + "addr2line 0.21.0", "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", - "object", + "object 0.32.2", "rustc-demangle", ] @@ -633,6 +924,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.13.1" @@ -641,15 +938,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.0" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bech32" @@ -777,13 +1074,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.15", + "prettyplease 0.2.20", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -792,14 +1089,14 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" dependencies = [ - "bs58", + "bs58 0.4.0", "hmac 0.12.1", "k256 0.11.6", "once_cell", "pbkdf2 0.11.0", "rand_core 0.6.4", "ripemd", - "sha2 0.10.6", + "sha2 0.10.8", "subtle", "zeroize", ] @@ -827,9 +1124,21 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] [[package]] name = "bitvec" @@ -849,7 +1158,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -864,38 +1173,38 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", - "arrayvec 0.7.2", - "constant_time_eq 0.2.4", + "arrayvec 0.7.4", + "constant_time_eq 0.3.0", ] [[package]] name = "blake2s_simd" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" dependencies = [ "arrayref", - "arrayvec 0.7.2", - "constant_time_eq 0.1.5", + "arrayvec 0.7.4", + "constant_time_eq 0.3.0", ] [[package]] name = "blake3" -version = "1.3.3" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", - "arrayvec 0.7.2", + "arrayvec 0.7.4", "cc", "cfg-if 1.0.0", - "constant_time_eq 0.2.4", - "digest 0.10.6", + "constant_time_eq 0.3.0", + "digest 0.10.7", ] [[package]] @@ -916,26 +1225,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.6", + "block-padding 0.2.1", + "generic-array 0.14.7", ] [[package]] name = "block-buffer" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" -dependencies = [ - "generic-array 0.14.6", -] - -[[package]] -name = "block-modes" -version = "0.7.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "block-padding 0.2.1", - "cipher 0.2.5", + "generic-array 0.14.7", ] [[package]] @@ -953,29 +1253,69 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "bnum" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" + +[[package]] +name = "borsh" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" +dependencies = [ + "borsh-derive 0.9.3", + "hashbrown 0.11.2", +] + [[package]] name = "borsh" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ - "borsh-derive", + "borsh-derive 0.10.3", "hashbrown 0.13.2", ] +[[package]] +name = "borsh-derive" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" +dependencies = [ + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + [[package]] name = "borsh-derive" version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", "proc-macro2", "syn 1.0.109", ] +[[package]] +name = "borsh-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "borsh-derive-internal" version = "0.10.3" @@ -987,6 +1327,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "borsh-schema-derive-internal" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "borsh-schema-derive-internal" version = "0.10.3" @@ -1000,9 +1351,9 @@ dependencies = [ [[package]] name = "bounded-collections" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b05133427c07c4776906f673ccf36c21b102c9829c641a5b56bd151d44fd6" +checksum = "ca548b6163b872067dc5eb82fd130c56881435e30367d2073594a3d9744120dd" dependencies = [ "log", "parity-scale-codec", @@ -1019,6 +1370,27 @@ dependencies = [ "thiserror", ] +[[package]] +name = "brotli" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19483b140a7ac7174d34b5a581b406c64f84da5409d3e09cf4fff604f9270e67" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6221fe77a248b9117d431ad93761222e1cf8ff282d9d1d5d9f53d6299a1cf76" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bs58" version = "0.4.0" @@ -1028,11 +1400,20 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bstr" -version = "1.2.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" dependencies = [ "memchr", "serde", @@ -1049,9 +1430,19 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bv" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" +dependencies = [ + "feature-probe", + "serde", +] [[package]] name = "byte-slice-cast" @@ -1067,21 +1458,35 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] [[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.4.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" dependencies = [ "serde", ] @@ -1099,18 +1504,28 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.2" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77df041dc383319cc661b428b6961a005db4d6808d5e12536931b1ca9556055" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" dependencies = [ "serde", ] +[[package]] +name = "caps" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190baaad529bcfbde9e1a19022c42781bdb6ff9de25721abdb8fd98c0807730b" +dependencies = [ + "libc", + "thiserror", +] + [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -1123,7 +1538,7 @@ checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" dependencies = [ "camino", "cargo-platform", - "semver 1.0.16", + "semver 1.0.23", "serde", "serde_json", "thiserror", @@ -1131,22 +1546,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.79" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" dependencies = [ "jobserver", -] - -[[package]] -name = "ccm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aca1a8fbc20b50ac9673ff014abfb2b5f4085ee1a850d408f14a159c5853ac7" -dependencies = [ - "aead 0.3.2", - "cipher 0.2.5", - "subtle", + "libc", + "once_cell", ] [[package]] @@ -1158,11 +1564,99 @@ dependencies = [ "nom", ] +[[package]] +name = "cf-guest" +version = "0.0.0" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "derive_more", + "guestchain", + "ibc-client-tendermint-types", + "ibc-core-client-context", + "ibc-core-commitment-types", + "ibc-core-host", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "lib", + "prost 0.12.3", + "prost-build 0.12.3", + "proto-utils", + "sealable-trie", + "stdx", + "trie-ids", +] + +[[package]] +name = "cf-guest" +version = "0.0.1" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "cf-guest 0.0.0", + "derive_more", + "ed25519-consensus", + "guestchain", + "ibc 0.15.0", + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-derive 0.1.0", + "ibc-primitives 0.50.0", + "ibc-proto 0.18.0", + "insta", + "lib", + "memory", + "prost 0.11.9", + "prost 0.12.3", + "prost-build 0.11.9", + "rand 0.8.5", + "sealable-trie", + "serde", + "stdx", + "tendermint-proto 0.34.1", + "trie-ids", +] + +[[package]] +name = "cf-guest-cw" +version = "0.1.0" +dependencies = [ + "borsh 0.10.3", + "byteorder", + "cf-guest 0.0.1", + "cosmwasm-schema", + "cosmwasm-std", + "cw-multi-test", + "derive_more", + "digest 0.10.7", + "ed25519-dalek 2.1.1", + "guestchain", + "hex", + "hyperspace-primitives", + "ibc 0.15.0", + "ibc-derive 0.1.0", + "ibc-proto 0.18.0", + "ics08-wasm", + "ics23 0.10.0", + "pallet-ibc", + "prost 0.11.9", + "schemars", + "serde", + "serde-json-wasm 0.5.2", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", + "trie-ids", +] + [[package]] name = "cfg-expr" -version = "0.15.5" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" dependencies = [ "smallvec", ] @@ -1187,42 +1681,41 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chacha20" -version = "0.8.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if 1.0.0", - "cipher 0.3.0", + "cipher 0.4.4", "cpufeatures", - "zeroize", ] [[package]] name = "chacha20poly1305" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ - "aead 0.4.3", + "aead 0.5.2", "chacha20", - "cipher 0.3.0", + "cipher 0.4.4", "poly1305", "zeroize", ] [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", - "time 0.1.45", + "serde", "wasm-bindgen", - "winapi", + "windows-targets 0.52.5", ] [[package]] @@ -1238,22 +1731,13 @@ dependencies = [ "unsigned-varint", ] -[[package]] -name = "cipher" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" -dependencies = [ - "generic-array 0.14.6", -] - [[package]] name = "cipher" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -1264,6 +1748,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] @@ -1286,9 +1771,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -1297,41 +1782,56 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap 0.11.0", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags 1.3.2", - "clap_derive 3.2.18", + "clap_derive 3.2.25", "clap_lex 0.2.4", - "indexmap 1.9.2", + "indexmap 1.9.3", "once_cell", - "strsim", + "strsim 0.10.0", "termcolor", - "textwrap", + "textwrap 0.16.1", ] [[package]] name = "clap" -version = "4.4.6" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", - "clap_derive 4.4.2", + "clap_derive 4.5.4", ] [[package]] name = "clap_builder" -version = "4.4.6" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", - "clap_lex 0.5.1", - "strsim", + "clap_lex 0.7.0", + "strsim 0.11.1", ] [[package]] @@ -1340,16 +1840,16 @@ version = "3.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f7a2e0a962c45ce25afce14220bc24f9dade0a1787f185cecf96bfba7847cd8" dependencies = [ - "clap 3.2.23", + "clap 3.2.25", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -1358,14 +1858,14 @@ dependencies = [ [[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", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -1379,19 +1879,18 @@ dependencies = [ [[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 = "coarsetime" -version = "0.1.22" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "454038500439e141804c655b4cd1bc6a70bcb95cd2bc9463af5661b6956f0e46" +checksum = "13b3839cf01bb7960114be3ccf2340f541b6d0c81f8690b007b2b39f750f7e5d" dependencies = [ "libc", - "once_cell", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasix", "wasm-bindgen", ] @@ -1400,7 +1899,7 @@ name = "codegen" version = "0.1.0" dependencies = [ "anyhow", - "clap 3.2.23", + "clap 3.2.25", "frame-metadata 15.1.0", "hex", "http", @@ -1409,7 +1908,7 @@ dependencies = [ "serde_json", "subxt-codegen", "subxt-metadata", - "syn 2.0.32", + "syn 2.0.61", "tokio", "wasm-testbed", ] @@ -1426,48 +1925,107 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "combine" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii 0.9.3", + "byteorder", + "either", + "memchr", + "unreachable", +] [[package]] name = "comfy-table" -version = "6.1.4" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e7b787b0dc42e8111badfdbe4c3059158ccb2db8780352fa1b01e8ccf45cc4d" +checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba" dependencies = [ - "strum", - "strum_macros", + "strum 0.24.1", + "strum_macros 0.24.3", "unicode-width", ] [[package]] name = "concurrent-queue" -version = "2.1.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "crossbeam-utils 0.8.14", + "crossbeam-utils 0.8.19", ] [[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", "unicode-width", - "windows-sys 0.45.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "console_log" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89f72f65e8501878b8a004d5a1afb780987e2ce2b4532c562e367a72c57499f" +dependencies = [ + "log", + "web-sys", ] [[package]] name = "const-oid" -version = "0.9.5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] [[package]] name = "constant_time_eq" @@ -1477,9 +2035,9 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "constant_time_eq" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ad85c1f65dc7b37604eb0e89748faf0b9653065f2a8ef69f96a687ec1e9279" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "contracts" @@ -1515,9 +2073,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", @@ -1525,9 +2083,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core2" @@ -1540,31 +2098,32 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.2.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f22add0f9b2a5416df98c1d0248a8d8eedb882c38fbf0c5052b64eebe865df6d" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", + "ecdsa 0.16.9", "ed25519-zebra", - "k256 0.11.6", + "k256 0.13.3", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.2.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e64f710a18ef90d0a632cf27842e98ffc2d005a38a6f76c12fd0bc03bc1a2d" +checksum = "c586ced10c3b00e809ee664a895025a024f60d65d34fe4c09daed4a4db68a3f3" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.2.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe5ad2e23a971b9e4cd57b20cee3e2e79c33799bed4b128e473aca3702bfe5dd" +checksum = "8467874827d384c131955ff6f4d47d02e72a956a08eb3c0ff24f8c903a5517b4" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -1575,9 +2134,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.2.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2926d159a9bb1a716a592b40280f1663f2491a9de3b6da77c0933cee2a2655b8" +checksum = "f6db85d98ac80922aef465e564d5b21fa9cfac5058cb62df7f116c3682337393" dependencies = [ "proc-macro2", "quote", @@ -1586,11 +2145,13 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.2.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76fee88ff5bf7bef55bd37ac0619974701b99bf6bd4b16cf56ee8810718abd71" +checksum = "ad011ae7447188e26e4a7dbca2fcd0fc186aa21ae5c86df0503ea44c78f9e469" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", + "bech32", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -1598,17 +2159,17 @@ dependencies = [ "hex", "schemars", "serde", - "serde-json-wasm", - "sha2 0.10.6", + "serde-json-wasm 0.5.2", + "sha2 0.10.8", + "static_assertions", "thiserror", - "uint", ] [[package]] name = "cosmwasm-storage" -version = "1.2.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "639bc36408bc1ac45e3323166ceeb8f0b91b55a941c4ad59d389829002fbbd94" +checksum = "66de2ab9db04757bcedef2b5984fbe536903ada4a8a9766717a4a71197ef34f6" dependencies = [ "cosmwasm-std", "serde", @@ -1635,9 +2196,9 @@ 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", ] @@ -1663,7 +2224,7 @@ dependencies = [ "cranelift-codegen-shared", "cranelift-entity", "cranelift-isle", - "gimli", + "gimli 0.27.3", "hashbrown 0.13.2", "log", "regalloc2", @@ -1733,33 +2294,18 @@ dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", - "itertools", + "itertools 0.10.5", "log", "smallvec", "wasmparser", "wasmtime-types", ] -[[package]] -name = "crc" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" -dependencies = [ - "crc-catalog", -] - -[[package]] -name = "crc-catalog" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" - [[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 1.0.0", ] @@ -1776,46 +2322,39 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.14", + "crossbeam-utils 0.8.19", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.14", + "crossbeam-utils 0.8.19", ] [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if 1.0.0", - "crossbeam-utils 0.8.14", - "memoffset 0.7.1", - "scopeguard", + "crossbeam-utils 0.8.19", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.14", + "crossbeam-utils 0.8.19", ] [[package]] @@ -1831,12 +2370,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -1850,7 +2386,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "rand_core 0.6.4", "subtle", "zeroize", @@ -1858,11 +2394,11 @@ dependencies = [ [[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 0.14.6", + "generic-array 0.14.7", "rand_core 0.6.4", "subtle", "zeroize", @@ -1874,7 +2410,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "rand_core 0.6.4", "typenum", ] @@ -1885,7 +2421,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -1895,7 +2431,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -1931,7 +2467,7 @@ name = "cumulus-client-cli" version = "0.1.0" source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.43#b8999fce0f61fb757f9e57e326cda48e70137019" dependencies = [ - "clap 4.4.6", + "clap 4.5.4", "parity-scale-codec", "sc-chain-spec", "sc-cli", @@ -1951,7 +2487,7 @@ dependencies = [ "cumulus-primitives-core", "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "polkadot-node-primitives", "polkadot-node-subsystem", "polkadot-overseer", @@ -2053,7 +2589,7 @@ dependencies = [ "futures", "futures-timer", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "polkadot-node-primitives", "polkadot-parachain", "polkadot-primitives", @@ -2195,7 +2731,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -2368,7 +2904,7 @@ name = "cumulus-relay-chain-minimal-node" version = "0.1.0" source = "git+https://github.com/paritytech/cumulus?branch=polkadot-v0.9.43#b8999fce0f61fb757f9e57e326cda48e70137019" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.2", "async-trait", "cumulus-primitives-core", "cumulus-relay-chain-interface", @@ -2459,13 +2995,13 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +version = "3.2.1" +source = "git+https://github.com/solana-labs/curve25519-dalek.git?rev=b500cdc2a920cd5bff9e2dd974d7b97349d61464#b500cdc2a920cd5bff9e2dd974d7b97349d61464" dependencies = [ "byteorder", "digest 0.9.0", "rand_core 0.5.1", + "serde", "subtle", "zeroize", ] @@ -2473,15 +3009,14 @@ dependencies = [ [[package]] name = "curve25519-dalek" version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek?rev=0cd099a9fb8ff9f6fedc8723d44dbb1c743e9d35#0cd099a9fb8ff9f6fedc8723d44dbb1c743e9d35" dependencies = [ "cfg-if 1.0.0", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.6", + "digest 0.10.7", "fiat-crypto", - "platforms 3.0.2", + "platforms 3.4.0", "rustc_version", "subtle", "zeroize", @@ -2490,12 +3025,11 @@ dependencies = [ [[package]] name = "curve25519-dalek-derive" version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" +source = "git+https://github.com/dalek-cryptography/curve25519-dalek?rev=0cd099a9fb8ff9f6fedc8723d44dbb1c743e9d35#0cd099a9fb8ff9f6fedc8723d44dbb1c743e9d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -2523,7 +3057,7 @@ dependencies = [ "cw-storage-plus", "cw-utils", "derivative", - "itertools", + "itertools 0.10.5", "prost 0.9.0", "schemars", "serde", @@ -2551,7 +3085,7 @@ dependencies = [ "cosmwasm-std", "cw2", "schemars", - "semver 1.0.16", + "semver 1.0.23", "serde", "thiserror", ] @@ -2571,9 +3105,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.89" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc831ee6a32dd495436e317595e639a587aa9907bef96fe6e6abc290ab6204e9" +checksum = "bb497fad022245b29c2a0351df572e2d67c1046bcef2260ebc022aec81efea82" dependencies = [ "cc", "cxxbridge-flags", @@ -2583,9 +3117,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.89" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94331d54f1b1a8895cd81049f7eaaaef9d05a7dcb4d1fd08bf3ff0806246789d" +checksum = "9327c7f9fbd6329a200a5d4aa6f674c60ab256525ff0084b52a889d4e4c60cee" dependencies = [ "cc", "codespan-reporting", @@ -2593,24 +3127,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] name = "cxxbridge-flags" -version = "1.0.89" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48dcd35ba14ca9b40d6e4b4b39961f23d835dbb8eed74565ded361d93e1feb8a" +checksum = "688c799a4a846f1c0acb9f36bb9c6272d9b3d9457f3633c7753c6057270df13c" [[package]] name = "cxxbridge-macro" -version = "1.0.89" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bbeb29798b407ccd82a3324ade1a7286e0d29851475990b612670f6f5124d2" +checksum = "928bc249a7e3cd554fd2e8e08a426e9670c50bbfc9a621653cfa9accc9641783" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] @@ -2625,12 +3159,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]] @@ -2643,22 +3177,22 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "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", "quote", - "strsim", - "syn 2.0.32", + "strsim 0.10.0", + "syn 2.0.61", ] [[package]] @@ -2674,26 +3208,36 @@ dependencies = [ [[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", + "darling_core 0.20.8", "quote", - "syn 2.0.32", + "syn 2.0.61", +] + +[[package]] +name = "dashmap" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", ] [[package]] name = "data-encoding" -version = "2.3.3" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" [[package]] name = "data-encoding-macro" -version = "0.1.12" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86927b7cd2fe88fa698b87404b287ab98d1a0063a34071d92e575b72d3029aca" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" dependencies = [ "data-encoding", "data-encoding-macro-internal", @@ -2701,63 +3245,72 @@ dependencies = [ [[package]] name = "data-encoding-macro-internal" -version = "0.1.10" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5bbed42daaa95e780b60a50546aa345b8413a1e46f9a40a12907d3598f038db" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" dependencies = [ "data-encoding", "syn 1.0.109", ] +[[package]] +name = "der" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +dependencies = [ + "const-oid 0.7.1", +] + [[package]] name = "der" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" dependencies = [ - "const-oid", - "pem-rfc7468", + "const-oid 0.9.6", "zeroize", ] [[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", + "const-oid 0.9.6", "zeroize", ] [[package]] name = "der-parser" -version = "7.0.0" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe398ac75057914d7d07307bf67dc7f3f574a26783b4fc7805a20ffa9f506e82" +checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" dependencies = [ - "asn1-rs 0.3.1", + "asn1-rs", "displaydoc", "nom", - "num-bigint", + "num-bigint 0.4.5", "num-traits", "rusticata-macros", ] [[package]] -name = "der-parser" -version = "8.2.0" +name = "deranged" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ - "asn1-rs 0.5.2", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", + "powerfmt", ] +[[package]] +name = "derivation-path" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" + [[package]] name = "derivative" version = "2.2.0" @@ -2780,37 +3333,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_builder" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07adf7be193b71cc36b193d0f5fe60b918a3a9db4dad0449f57bcfd519704a3" -dependencies = [ - "derive_builder_macro", -] - -[[package]] -name = "derive_builder_core" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f91d4cfa921f1c05904dc3c57b4a32c38aed3340cce209f3a6fd1478babafc4" -dependencies = [ - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "derive_builder_macro" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f0314b72bed045f3a68671b3c86328386762c93f82d98c65c3cb5e5f573dd68" -dependencies = [ - "derive_builder_core", - "syn 1.0.109", -] - [[package]] name = "derive_more" version = "0.99.17" @@ -2824,6 +3346,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "dialoguer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c6f2989294b9a498d3ad5491a79c6deb604617378e1cdc4bfc1c1361fe2f87" +dependencies = [ + "console", + "shell-words", + "tempfile", + "zeroize", +] + [[package]] name = "difflib" version = "0.4.0" @@ -2845,17 +3379,17 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", - "const-oid", + "block-buffer 0.10.4", + "const-oid 0.9.6", "crypto-common", "subtle", ] @@ -2903,13 +3437,36 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", +] + +[[package]] +name = "dlopen2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", ] [[package]] @@ -2920,15 +3477,15 @@ 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 = "dtoa" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00704156a7de8df8da0911424e30c2049957b0a714542a44e05fe693dd85313" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" [[package]] name = "dyn-clonable" @@ -2953,9 +3510,15 @@ dependencies = [ [[package]] name = "dyn-clone" -version = "1.0.14" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "eager" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d2f3407d9a573d666de4b5bdf10569d73ca9478087346697dcbae6244bfbcd" +checksum = "abe71d579d1812060163dff96056261deb5bf6729b100fa2e36a68b9649ba3d3" [[package]] name = "ecdsa" @@ -2971,16 +3534,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.7" +version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", - "digest 0.10.6", - "elliptic-curve 0.13.6", + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve 0.13.8", "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2994,12 +3557,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]] @@ -3022,33 +3585,48 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek 3.2.0", + "curve25519-dalek 3.2.1", "ed25519 1.5.3", + "rand 0.7.3", + "serde", "sha2 0.9.9", "zeroize", ] [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek 4.1.1", - "ed25519 2.2.2", + "ed25519 2.2.3", "rand_core 0.6.4", "serde", - "sha2 0.10.6", + "sha2 0.10.8", + "subtle", "zeroize", ] +[[package]] +name = "ed25519-dalek-bip32" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" +dependencies = [ + "derivation-path", + "ed25519-dalek 1.0.1", + "hmac 0.12.1", + "sha2 0.10.8", +] + [[package]] name = "ed25519-zebra" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" dependencies = [ - "curve25519-dalek 3.2.0", + "curve25519-dalek 3.2.1", "hashbrown 0.12.3", "hex", "rand_core 0.6.4", @@ -3059,9 +3637,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" @@ -3072,12 +3650,10 @@ dependencies = [ "base16ct 0.1.1", "crypto-bigint 0.4.9", "der 0.6.1", - "digest 0.10.6", + "digest 0.10.7", "ff 0.12.1", - "generic-array 0.14.6", + "generic-array 0.14.7", "group 0.12.1", - "hkdf", - "pem-rfc7468", "pkcs8 0.9.0", "rand_core 0.6.4", "sec1 0.3.0", @@ -3087,19 +3663,19 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.13.6" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct 0.2.0", - "crypto-bigint 0.5.3", - "digest 0.10.6", + "crypto-bigint 0.5.5", + "digest 0.10.7", "ff 0.13.0", - "generic-array 0.14.6", + "generic-array 0.14.7", "group 0.13.0", "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1 0.7.1", + "sec1 0.7.3", "subtle", "zeroize", ] @@ -3110,47 +3686,76 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "enum-as-inner" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 1.0.109", ] +[[package]] +name = "enum-iterator" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + [[package]] name = "enumflags2" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" +checksum = "3278c9d5fb675e0a51dabcf4c0d355f692b064171535ba72361be1528a9d8e8d" dependencies = [ "enumflags2_derive", ] [[package]] name = "enumflags2_derive" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" +checksum = "5c785274071b1b420972453b306eeca06acf4633829db4223b58a2a8c5953bc4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "enumn" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ad8cef1d801a4686bfd8919f0b30eac4c8e48968c437a6405ded4fb5272d2b" +checksum = "6fd000fd6988e73bbe993ea3db9b1aa64906ab88766d654973924340c8cddb42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -3168,9 +3773,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -3193,41 +3798,40 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ - "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] -name = "errno" -version = "0.3.4" +name = "event-listener" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "event-listener" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ - "cc", - "libc", + "concurrent-queue", + "parking", + "pin-project-lite 0.2.14", ] [[package]] -name = "event-listener" -version = "2.5.3" +name = "event-listener-strategy" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite 0.2.14", +] [[package]] name = "exit-future" @@ -3277,22 +3881,23 @@ dependencies = [ [[package]] name = "expander" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f86a749cf851891866c10515ef6c299b5c69661465e9c3bbe7e07a2b77fb0f7" +checksum = "00e83c02035136f1592a47964ea60c05a50e4ed8b5892cfac197063850898d4d" dependencies = [ "blake2", "fs-err", + "prettier-please", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[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", @@ -3310,14 +3915,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" [[package]] name = "fatality" @@ -3336,7 +3944,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5aa1e3ae159e592ad222dc90c5acbad632b527779ba88486abe92782ab268bd" dependencies = [ "expander 0.0.4", - "indexmap 1.9.2", + "indexmap 1.9.3", "proc-macro-crate 1.3.1", "proc-macro2", "quote", @@ -3353,6 +3961,12 @@ dependencies = [ "libc", ] +[[package]] +name = "feature-probe" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" + [[package]] name = "ff" version = "0.12.1" @@ -3375,9 +3989,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.1" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0870c84016d4b481be5c9f323c24f65e31e901ae618f0e80f4308fb00de1d2d" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" [[package]] name = "file-per-thread-logger" @@ -3385,20 +3999,20 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84f2e425d9790201ba4af4630191feac6dcc98765b118d4d18e91d23c2353866" dependencies = [ - "env_logger 0.10.0", + "env_logger 0.10.2", "log", ] [[package]] name = "filetime" -version = "0.2.19" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e884668cd0c7480504233e951174ddc3b382f7c2666e3b7310b5c4e7b0c37f9" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", - "windows-sys 0.42.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -3413,7 +4027,7 @@ dependencies = [ "log", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "scale-info", ] @@ -3437,9 +4051,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" dependencies = [ "crc32fast", "libz-sys", @@ -3471,6 +4085,21 @@ 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 = "fork-tree" version = "3.0.0" @@ -3481,9 +4110,9 @@ dependencies = [ [[package]] name = "form_urlencoded" -version = "1.1.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -3533,14 +4162,14 @@ dependencies = [ "Inflector", "array-bytes 4.2.0", "chrono", - "clap 4.4.6", + "clap 4.5.4", "comfy-table", "frame-benchmarking", "frame-support", "frame-system", "gethostname", "handlebars", - "itertools", + "itertools 0.10.5", "lazy_static", "linked-hash-map", "log", @@ -3580,7 +4209,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -3644,7 +4273,7 @@ dependencies = [ [[package]] name = "frame-metadata" version = "16.0.0" -source = "git+https://github.com/paritytech/frame-metadata?branch=main#0e90489c8588d48b55779f1c6b93216346ecc8a9" +source = "git+https://github.com/paritytech/frame-metadata?branch=main#94e7743fa454963609763cf9cccbb7f85bc96d2f" dependencies = [ "cfg-if 1.0.0", "parity-scale-codec", @@ -3683,7 +4312,7 @@ dependencies = [ "frame-metadata 15.1.0", "frame-support-procedural", "impl-trait-for-tuples", - "k256 0.13.1", + "k256 0.13.3", "log", "once_cell", "parity-scale-codec", @@ -3716,11 +4345,11 @@ dependencies = [ "cfg-expr", "derive-syn-parse", "frame-support-procedural-tools", - "itertools", + "itertools 0.10.5", "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -3732,7 +4361,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -3742,7 +4371,7 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -3802,9 +4431,12 @@ dependencies = [ [[package]] name = "fs-err" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0845fa252299212f0389d64ba26f34fa32cfe41588355f21ed507c59a0f64541" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] name = "fs2" @@ -3822,7 +4454,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" dependencies = [ - "rustix 0.38.17", + "rustix 0.38.34", "windows-sys 0.48.0", ] @@ -3840,9 +4472,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", @@ -3855,9 +4487,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", @@ -3865,15 +4497,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", @@ -3883,34 +4515,29 @@ 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-lite" -version = "1.12.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand", "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite 0.2.13", - "waker-fn", + "pin-project-lite 0.2.14", ] [[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", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -3920,33 +4547,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" dependencies = [ "futures-io", - "rustls 0.20.8", - "webpki 0.22.0", + "rustls 0.20.9", + "webpki 0.22.4", ] [[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" [[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", @@ -3955,7 +4582,7 @@ dependencies = [ "futures-sink", "futures-task", "memchr", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "pin-utils", "slab", ] @@ -3980,10 +4607,11 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ + "serde", "typenum", "version_check", "zeroize", @@ -4006,15 +4634,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -4024,36 +4654,41 @@ dependencies = [ ] [[package]] -name = "ghash" -version = "0.4.4" +name = "getrandom_or_panic" +version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ - "opaque-debug 0.3.0", - "polyval 0.5.3", + "rand_core 0.6.4", ] [[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 0.3.0", - "polyval 0.6.0", + "opaque-debug 0.3.1", + "polyval 0.6.2", ] [[package]] name = "gimli" -version = "0.27.1" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" dependencies = [ "fallible-iterator", - "indexmap 1.9.2", + "indexmap 1.9.3", "stable_deref_trait", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "git2" version = "0.13.25" @@ -4077,15 +4712,26 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" dependencies = [ "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "goblin" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" +dependencies = [ + "log", + "plain", + "scroll", ] [[package]] @@ -4192,6 +4838,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "guestchain" +version = "0.0.0" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "derive_more", + "ibc-core-client-context", + "ibc-core-commitment-types", + "ibc-core-host", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "lib", + "prost 0.12.3", + "proto-utils", + "sealable-trie", + "stdx", + "strum 0.25.0", + "trie-ids", +] + [[package]] name = "gumdrop" version = "0.8.1" @@ -4214,9 +4881,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.15" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", @@ -4224,7 +4891,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.2", + "indexmap 2.2.6", "slab", "tokio", "tokio-util", @@ -4233,15 +4900,15 @@ dependencies = [ [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "handlebars" -version = "4.3.6" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "035ef95d03713f2c347a72547b7cd38cbc9af7cd51e6099fb62d586d4a6dee3a" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" dependencies = [ "log", "pest", @@ -4266,13 +4933,31 @@ dependencies = [ "crunchy", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.8", +] + [[package]] name = "hashbrown" 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]] @@ -4281,23 +4966,35 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", ] [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +dependencies = [ + "ahash 0.8.5", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.2", +] [[package]] name = "headers" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", + "base64 0.21.7", "bytes", "headers-core", "http", @@ -4315,6 +5012,15 @@ dependencies = [ "http", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "heck" version = "0.4.1" @@ -4322,28 +5028,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "hermit-abi" -version = "0.3.0" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -4364,13 +5067,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" [[package]] -name = "hkdf" -version = "0.12.3" +name = "histogram" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" -dependencies = [ - "hmac 0.12.1", -] +checksum = "12cb882ccb290b8646e554b157ab0b71e64e8d5bef775cd66b6531e52d302669" [[package]] name = "hmac" @@ -4398,7 +5098,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -4408,10 +5108,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", - "generic-array 0.14.6", + "generic-array 0.14.7", "hmac 0.8.1", ] +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "hostname" version = "0.3.1" @@ -4425,9 +5134,9 @@ dependencies = [ [[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", @@ -4436,20 +5145,20 @@ 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", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", ] [[package]] name = "http-range-header" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" @@ -4459,9 +5168,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -4471,9 +5180,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.24" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e011372fa0b68db8350aa7a248930ecc7839bf46d8485577d69f117a75f164c" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -4485,8 +5194,8 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project-lite 0.2.13", - "socket2 0.4.9", + "pin-project-lite 0.2.14", + "socket2 0.5.7", "tokio", "tower-service", "tracing", @@ -4539,27 +5248,27 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.20.8", - "rustls-native-certs 0.6.2", + "rustls 0.20.9", + "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.23.4", ] [[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", "hyper", "log", - "rustls 0.21.7", - "rustls-native-certs 0.6.2", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", "tokio", "tokio-rustls 0.24.1", - "webpki-roots 0.23.1", + "webpki-roots 0.25.4", ] [[package]] @@ -4569,20 +5278,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ "hyper", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "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", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyperspace" version = "0.1.0" dependencies = [ "anyhow", - "clap 3.2.23", + "clap 3.2.25", "hyperspace-core", "tokio", - "toml 0.7.6", + "toml 0.7.8", ] [[package]] @@ -4591,25 +5313,39 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", - "clap 3.2.23", + "borsh 0.10.3", + "clap 3.2.25", "codegen", "derive_more", "env_logger 0.9.3", "frame-support", "frame-system", "futures", + "guestchain", "hex", "hyperspace-cosmos", "hyperspace-metrics", "hyperspace-parachain", "hyperspace-primitives", - "ibc", + "hyperspace-solana", + "ibc 0.15.0", + "ibc-app-transfer-types", + "ibc-client-tendermint-types", + "ibc-core-channel-types", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", "ibc-proto 0.18.0", + "ibc-proto 0.41.0", "ibc-rpc", "ics08-wasm", "ics10-grandpa", "ics11-beefy", - "itertools", + "itertools 0.10.5", + "lib", "light-client-common", "log", "once_cell", @@ -4617,9 +5353,10 @@ dependencies = [ "pallet-ibc-ping", "parity-scale-codec", "prometheus", - "prost 0.11.6", + "prost 0.11.9", "rand 0.8.5", "scale-encode 0.1.2", + "sealable-trie", "serde", "serde_json", "sp-consensus-beefy", @@ -4631,10 +5368,11 @@ dependencies = [ "sp-trie 7.0.0", "subxt", "subxt-generated", - "tendermint-proto 0.28.0", + "tendermint-proto 0.33.2", "thiserror", "tokio", - "toml 0.7.6", + "toml 0.7.8", + "trie-ids", ] [[package]] @@ -4646,40 +5384,40 @@ dependencies = [ "bech32", "bip32", "derive_more", - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "futures", "hex", "hyperspace-primitives", - "ibc", + "ibc 0.15.0", "ibc-primitives 0.1.0", "ibc-proto 0.18.0", "ibc-rpc", "ics07-tendermint", "ics08-wasm", - "itertools", + "itertools 0.10.5", "k256 0.11.6", "log", "pallet-ibc", "parity-scale-codec", - "prost 0.11.6", + "prost 0.11.9", "quick_cache", "rand 0.8.5", "ripemd", "rs_merkle", "serde", "serde_json", - "sha2 0.10.6", - "tendermint 0.28.0", + "sha2 0.10.8", + "tendermint 0.33.2", "tendermint-light-client", - "tendermint-light-client-verifier", - "tendermint-proto 0.28.0", + "tendermint-light-client-verifier 0.33.2", + "tendermint-proto 0.33.2", "tendermint-rpc", "thiserror", - "tiny-bip39", + "tiny-bip39 1.0.0", "tokio", "tokio-stream", - "tonic", + "tonic 0.8.3", "tracing", ] @@ -4690,11 +5428,11 @@ dependencies = [ "anyhow", "futures-util", "hyper", - "ibc", + "ibc 0.15.0", "ibc-proto 0.18.0", "log", "prometheus", - "tendermint-proto 0.28.0", + "tendermint-proto 0.33.2", "thiserror", "tokio", ] @@ -4708,7 +5446,7 @@ dependencies = [ "beefy-light-client", "beefy-light-client-primitives", "beefy-prover", - "clap 3.2.23", + "clap 3.2.25", "derive_more", "finality-grandpa", "frame-support", @@ -4719,13 +5457,13 @@ dependencies = [ "hex", "hex-literal 0.3.4", "hyperspace-primitives", - "ibc", + "ibc 0.15.0", "ibc-primitives 0.1.0", "ibc-proto 0.18.0", "ibc-rpc", "ics10-grandpa", "ics11-beefy", - "itertools", + "itertools 0.10.5", "jsonrpsee", "jsonrpsee-ws-client", "light-client-common", @@ -4738,7 +5476,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "parity-scale-codec", "polkadot-core-primitives", - "prost 0.11.6", + "prost 0.11.9", "rand 0.8.5", "rs_merkle", "sc-consensus-beefy-rpc", @@ -4760,7 +5498,7 @@ dependencies = [ "ss58-registry", "subxt", "subxt-generated", - "tendermint-proto 0.28.0", + "tendermint-proto 0.33.2", "thiserror", "tokio", "tokio-stream", @@ -4774,7 +5512,7 @@ dependencies = [ "async-trait", "futures", "hex", - "ibc", + "ibc 0.15.0", "ibc-proto 0.18.0", "ibc-rpc", "ics08-wasm", @@ -4789,27 +5527,117 @@ dependencies = [ ] [[package]] -name = "hyperspace-testsuite" +name = "hyperspace-solana" version = "0.1.0" dependencies = [ + "anchor-client", + "anchor-lang", + "anchor-spl", "anyhow", "async-trait", - "finality-grandpa", + "base64 0.21.7", + "bech32", + "bincode", + "bip32", + "borsh 0.10.3", + "bs58 0.5.1", + "bytemuck", + "cf-guest 0.0.0", + "cf-guest 0.0.1", + "derive_more", + "digest 0.10.7", + "ed25519-zebra", "futures", - "grandpa-light-client-primitives", - "grandpa-light-client-verifier", + "futures-util", + "guestchain", "hex", - "hyperspace-core", - "hyperspace-cosmos", - "hyperspace-parachain", "hyperspace-primitives", - "ibc", + "ibc 0.15.0", + "ibc-app-transfer-types", + "ibc-client-tendermint-types", + "ibc-client-wasm-types", + "ibc-core-channel-types", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives 0.1.0", + "ibc-primitives 0.50.0", "ibc-proto 0.18.0", - "ics10-grandpa", - "light-client-common", - "log", - "pallet-ibc", - "pallet-ibc-ping", + "ibc-proto 0.41.0", + "ibc-rpc", + "ics07-tendermint", + "ics08-wasm", + "ics23 0.11.1", + "itertools 0.10.5", + "jito-protos", + "jito-searcher-client", + "k256 0.11.6", + "lib", + "log", + "memory", + "pallet-ibc", + "parity-scale-codec", + "prost 0.11.9", + "prost-types 0.12.3", + "quick_cache", + "rand 0.8.5", + "reqwest", + "ripemd", + "rs_merkle", + "rusqlite", + "sealable-trie", + "serde", + "serde_json", + "sha2 0.10.8", + "solana-ibc", + "solana-metrics", + "solana-signature-verifier", + "solana-transaction-status", + "solana-trie", + "solana-write-account", + "stdx", + "tendermint 0.33.2", + "tendermint 0.34.1", + "tendermint-light-client", + "tendermint-light-client-verifier 0.33.2", + "tendermint-light-client-verifier 0.34.1", + "tendermint-proto 0.33.2", + "tendermint-rpc", + "thiserror", + "tiny-bip39 1.0.0", + "tokio", + "tokio-stream", + "tonic 0.8.3", + "tracing", + "trie-ids", +] + +[[package]] +name = "hyperspace-testsuite" +version = "0.1.0" +dependencies = [ + "anchor-lang", + "anyhow", + "async-trait", + "finality-grandpa", + "futures", + "grandpa-light-client-primitives", + "grandpa-light-client-verifier", + "hex", + "hyperspace-core", + "hyperspace-cosmos", + "hyperspace-parachain", + "hyperspace-primitives", + "hyperspace-solana", + "ibc 0.15.0", + "ibc-proto 0.18.0", + "ics10-grandpa", + "light-client-common", + "log", + "pallet-ibc", + "pallet-ibc-ping", "parity-scale-codec", "polkadot-core-primitives", "rand 0.8.5", @@ -4822,33 +5650,32 @@ dependencies = [ "sp-state-machine 0.13.0", "sp-trie 7.0.0", "subxt", - "tendermint-proto 0.28.0", + "tendermint-proto 0.33.2", "tokio", - "toml 0.7.6", + "toml 0.7.8", ] [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows-core", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] @@ -4861,7 +5688,7 @@ dependencies = [ "flex-error", "hex", "ibc-core-host-types", - "ibc-derive", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "ics23 0.10.0", "log", @@ -4869,36 +5696,395 @@ dependencies = [ "num-traits", "parity-scale-codec", "primitive-types", - "prost 0.11.6", + "prost 0.11.9", "safe-regex", "scale-info", "serde", "serde_derive", "serde_json", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", "sp-core 7.0.0", "sp-std 5.0.0", "subtle-encoding", - "tendermint 0.28.0", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-proto 0.33.2", "test-log", - "time 0.3.17", + "time", "tokio", "tracing", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.18", + "uint", +] + +[[package]] +name = "ibc" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-apps", + "ibc-clients", + "ibc-core", + "ibc-core-host-cosmos", + "ibc-derive 0.6.0", + "ibc-primitives 0.50.0", +] + +[[package]] +name = "ibc-app-transfer" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-app-transfer-types", + "ibc-core", + "serde-json-wasm 1.0.1", +] + +[[package]] +name = "ibc-app-transfer-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core", + "ibc-proto 0.41.0", + "primitive-types", + "serde", "uint", ] +[[package]] +name = "ibc-apps" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-app-transfer", +] + +[[package]] +name = "ibc-client-tendermint" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "derive_more", + "ibc-client-tendermint-types", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-primitives 0.50.0", + "serde", + "tendermint 0.34.1", + "tendermint-light-client-verifier 0.34.1", +] + +[[package]] +name = "ibc-client-tendermint-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "prost 0.12.3", + "serde", + "tendermint 0.34.1", + "tendermint-light-client-verifier 0.34.1", + "tendermint-proto 0.34.1", +] + +[[package]] +name = "ibc-client-wasm-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "base64 0.21.7", + "displaydoc", + "ibc-core-client", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", +] + +[[package]] +name = "ibc-clients" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-client-tendermint", + "ibc-client-wasm-types", +] + +[[package]] +name = "ibc-core" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-core-channel", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-connection", + "ibc-core-handler", + "ibc-core-host", + "ibc-core-router", + "ibc-derive 0.6.0", + "ibc-primitives 0.50.0", +] + +[[package]] +name = "ibc-core-channel" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-core-channel-types", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-connection", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-core-router", + "ibc-primitives 0.50.0", +] + +[[package]] +name = "ibc-core-channel-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", + "sha2 0.10.8", + "subtle-encoding", + "tendermint 0.34.1", +] + +[[package]] +name = "ibc-core-client" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-client-tendermint-types", + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-primitives 0.50.0", +] + +[[package]] +name = "ibc-core-client-context" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-client-tendermint-types", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "subtle-encoding", + "tendermint 0.34.1", +] + +[[package]] +name = "ibc-core-client-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-commitment-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", + "subtle-encoding", + "tendermint 0.34.1", +] + +[[package]] +name = "ibc-core-commitment-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "ics23 0.11.1", + "serde", + "subtle-encoding", +] + +[[package]] +name = "ibc-core-connection" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-core-client", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-primitives 0.50.0", +] + +[[package]] +name = "ibc-core-connection-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", + "subtle-encoding", + "tendermint 0.34.1", +] + +[[package]] +name = "ibc-core-handler" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "ibc-client-tendermint-types", + "ibc-core-channel", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-connection", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-core-router", + "ibc-primitives 0.50.0", +] + +[[package]] +name = "ibc-core-handler-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-channel-types", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-host-types", + "ibc-core-router-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", + "subtle-encoding", + "tendermint 0.34.1", +] + +[[package]] +name = "ibc-core-host" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-core-channel-types", + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "subtle-encoding", +] + +[[package]] +name = "ibc-core-host-cosmos" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-app-transfer-types", + "ibc-client-tendermint", + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", + "sha2 0.10.8", + "subtle-encoding", + "tendermint 0.34.1", +] + [[package]] name = "ibc-core-host-types" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616955da310febbe93c0569a2feebd9f57cafed3eee5a56b0c3bb953a75f6089" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-primitives 0.50.0", + "serde", +] + +[[package]] +name = "ibc-core-router" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-core-channel-types", + "ibc-core-host-types", + "ibc-core-router-types", + "ibc-primitives 0.50.0", + "subtle-encoding", +] + +[[package]] +name = "ibc-core-router-types" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" dependencies = [ + "borsh 0.10.3", "derive_more", "displaydoc", - "ibc-primitives 0.48.1", + "ibc-core-host-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "serde", + "subtle-encoding", + "tendermint 0.34.1", ] [[package]] @@ -4912,6 +6098,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ibc-derive" +version = "0.6.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + [[package]] name = "ibc-primitives" version = "0.1.0" @@ -4920,13 +6116,13 @@ dependencies = [ "blake2", "frame-support", "hex", - "ibc", + "ibc 0.15.0", "parity-scale-codec", "ripemd", "scale-info", "serde", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", "sp-core 7.0.0", "sp-io 7.0.0", "sp-runtime 7.0.0", @@ -4937,16 +6133,17 @@ dependencies = [ [[package]] name = "ibc-primitives" -version = "0.48.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5edea4685267fd68514c87e7aa3a62712340c4cff6903f088a9ab571428a08a" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" dependencies = [ + "borsh 0.10.3", "derive_more", "displaydoc", - "ibc-proto 0.38.0", + "ibc-proto 0.41.0", "prost 0.12.3", - "tendermint 0.34.0", - "time 0.3.17", + "serde", + "tendermint 0.34.1", + "time", ] [[package]] @@ -4955,26 +6152,29 @@ version = "0.18.0" dependencies = [ "base64 0.13.1", "bytes", - "prost 0.11.6", + "prost 0.11.9", "schemars", "serde", - "tendermint-proto 0.28.0", - "tonic", + "tendermint-proto 0.33.2", + "tonic 0.8.3", ] [[package]] name = "ibc-proto" -version = "0.38.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93cbf4cbe9e5113cc7c70f3208a7029b2205c629502cbb2ae7ea0a09a97d3005" +checksum = "dd4ee32b22d3b06f31529b956f4928e5c9a068d71e46cf6abfa19c31ca550553" dependencies = [ - "base64 0.21.0", + "base64 0.21.7", + "borsh 0.10.3", "bytes", "flex-error", - "ics23 0.11.0", + "ics23 0.11.1", + "informalsystems-pbjson", "prost 0.12.3", + "serde", "subtle-encoding", - "tendermint-proto 0.34.0", + "tendermint-proto 0.34.1", ] [[package]] @@ -4983,9 +6183,9 @@ version = "0.2.0" dependencies = [ "argh", "git2", - "prost-build", + "prost-build 0.11.9", "tempdir", - "tonic-build", + "tonic-build 0.8.4", "walkdir", ] @@ -4994,8 +6194,8 @@ name = "ibc-rpc" version = "0.1.0" dependencies = [ "frame-system", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-primitives 0.1.0", "ibc-proto 0.18.0", "ibc-runtime-api", @@ -5011,7 +6211,7 @@ dependencies = [ "sp-core 7.0.0", "sp-runtime 7.0.0", "sp-trie 7.0.0", - "tendermint-proto 0.28.0", + "tendermint-proto 0.33.2", ] [[package]] @@ -5033,26 +6233,26 @@ dependencies = [ "env_logger 0.9.3", "flex-error", "hex", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "ics23 0.10.0", "log", "modelator", - "prost 0.11.6", + "prost 0.11.9", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "subtle-encoding", - "tendermint 0.28.0", - "tendermint-light-client-verifier", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-light-client-verifier 0.33.2", + "tendermint-proto 0.33.2", "tendermint-rpc", "tendermint-testgen", "test-log", - "time 0.3.17", + "time", "tracing", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.18", ] [[package]] @@ -5064,29 +6264,29 @@ dependencies = [ "cosmwasm-std", "cw-multi-test", "derive_more", - "digest 0.10.6", + "digest 0.10.7", "ed25519 1.5.3", "ed25519-consensus", "ed25519-zebra", "hex", "hyperspace-primitives", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "ics07-tendermint", "ics08-wasm", "ics23 0.10.0", "pallet-ibc", - "prost 0.11.6", + "prost 0.11.9", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.2", "serde_json", - "sha2 0.10.6", - "sha3", - "tendermint 0.28.0", - "tendermint-light-client-verifier", - "tendermint-proto 0.28.0", + "sha2 0.10.8", + "sha3 0.10.8", + "tendermint 0.33.2", + "tendermint-light-client-verifier 0.33.2", + "tendermint-proto 0.33.2", "thiserror", ] @@ -5096,11 +6296,11 @@ version = "0.1.0" dependencies = [ "cosmwasm-schema", "hex", - "ibc", + "ibc 0.15.0", "ibc-proto 0.18.0", - "prost 0.11.6", + "prost 0.11.9", "serde", - "tendermint-proto 0.28.0", + "tendermint-proto 0.33.2", ] [[package]] @@ -5119,16 +6319,16 @@ dependencies = [ "grandpa-prover", "hex", "hyperspace-core", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "jsonrpsee-ws-client", "light-client-common", "log", "parity-scale-codec", - "prost 0.11.6", - "prost-build", - "prost-types 0.11.6", + "prost 0.11.9", + "prost-build 0.11.9", + "prost-types 0.11.9", "sc-consensus-grandpa-rpc", "serde", "serde_json", @@ -5138,8 +6338,8 @@ dependencies = [ "sp-state-machine 0.13.0", "sp-trie 7.0.0", "subxt", - "tendermint 0.28.0", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-proto 0.33.2", "tokio", ] @@ -5154,34 +6354,34 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "derive_more", - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "finality-grandpa", "grandpa-light-client-primitives", "hex", "hyperspace-primitives", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "ics08-wasm", "ics10-grandpa", "ics23 0.10.0", "light-client-common", "pallet-ibc", - "prost 0.11.6", + "prost 0.11.9", "schemars", "serde", - "serde-json-wasm", + "serde-json-wasm 0.5.2", "serde_json", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", "sp-core 7.0.0", "sp-io 7.0.0", "sp-runtime 7.0.0", "sp-runtime-interface 7.0.0", "sp-std 5.0.0", - "tendermint 0.28.0", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-proto 0.33.2", "thiserror", "twox-hash", ] @@ -5199,14 +6399,14 @@ dependencies = [ "frame-support", "futures", "hyperspace-core", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "light-client-common", "parity-scale-codec", - "prost 0.11.6", - "prost-build", - "prost-types 0.11.6", + "prost 0.11.9", + "prost-build 0.11.9", + "prost-types 0.11.9", "serde", "serde_json", "sp-consensus-beefy", @@ -5217,8 +6417,8 @@ dependencies = [ "sp-storage 7.0.0", "sp-trie 7.0.0", "subxt", - "tendermint 0.28.0", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-proto 0.33.2", "tokio", ] @@ -5226,37 +6426,37 @@ dependencies = [ name = "ics13-near" version = "0.1.0" dependencies = [ - "borsh", + "borsh 0.10.3", "bytes", "derive_more", "env_logger 0.9.3", "flex-error", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-proto 0.18.0", "ics23 0.10.0", "modelator", "num-traits", "parity-scale-codec", - "prost 0.11.6", + "prost 0.11.9", "ripemd", "safe-regex", "serde", "serde_derive", "serde_json", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", "sp-core 7.0.0", "subtle-encoding", - "tendermint 0.28.0", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-proto 0.33.2", "tendermint-rpc", "tendermint-testgen", "test-log", - "time 0.3.17", + "time", "tokio", "tracing", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.18", "uint", ] @@ -5268,22 +6468,29 @@ dependencies = [ "anyhow", "bytes", "hex", - "prost 0.11.6", + "prost 0.11.9", "ripemd", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", ] [[package]] name = "ics23" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "661e2d6f79952a65bc92b1c81f639ebd37228dae6ff412a5aba7d474bdc4b957" +checksum = "dc3b8be84e7285c73b88effdc3294b552277d6b0ec728ee016c861b7b9a2c19c" dependencies = [ "anyhow", + "blake2", + "blake3", "bytes", "hex", + "informalsystems-pbjson", "prost 0.12.3", + "ripemd", + "serde", + "sha2 0.10.8", + "sha3 0.10.8", ] [[package]] @@ -5305,9 +6512,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.3.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -5315,19 +6522,19 @@ dependencies = [ [[package]] name = "if-addrs" -version = "0.7.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc0fa01ffc752e9dbc72818cdb072cd028b86be5e09dd04c5a643704fe101a9" +checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "if-watch" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9465340214b296cd17a0009acdb890d6160010b8adf8f78a00d0d7ab270f79f" +checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" dependencies = [ "async-io", "core-foundation", @@ -5342,6 +6549,22 @@ dependencies = [ "windows", ] +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "rayon", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + [[package]] name = "impl-codec" version = "0.6.0" @@ -5388,9 +6611,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", @@ -5399,19 +6622,19 @@ 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.2", ] [[package]] name = "indicatif" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" dependencies = [ "console", "instant", @@ -5420,22 +6643,44 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "informalsystems-pbjson" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa4a0980c8379295100d70854354e78df2ee1c6ca0f96ffe89afeb3140e3a3d" +dependencies = [ + "base64 0.21.7", + "serde", +] + [[package]] name = "inout" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] -name = "instant" -version = "0.1.12" +name = "insta" +version = "1.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "3eab73f58e59ca6526037208f0e98851159ec1633cf17b6cd2e1f2c3fd5d53cc" dependencies = [ - "cfg-if 1.0.0", + "console", + "lazy_static", + "linked-hash-map", + "similar", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", ] [[package]] @@ -5453,33 +6698,15 @@ dependencies = [ "num-traits", ] -[[package]] -name = "interceptor" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e8a11ae2da61704edada656798b61c94b35ecac2c58eb955156987d5e6be90b" -dependencies = [ - "async-trait", - "bytes", - "log", - "rand 0.8.5", - "rtcp", - "rtp", - "thiserror", - "tokio", - "waitgroup", - "webrtc-srtp", - "webrtc-util", -] - [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ + "hermit-abi 0.3.9", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -5490,34 +6717,39 @@ checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" [[package]] name = "ipconfig" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd302af1b90f2463a98fa5ad469fc212c8e3175a41c3068601bfa2727591c5be" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.4.9", + "socket2 0.5.7", "widestring", - "winapi", + "windows-sys 0.48.0", "winreg", ] [[package]] name = "ipnet" -version = "2.7.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.0", - "io-lifetimes", - "rustix 0.36.8", - "windows-sys 0.45.0", + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.10.5" @@ -5527,30 +6759,87 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.5" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jito-protos" +version = "0.1.0" +source = "git+https://github.com/dhruvja/searcher-examples#addf5b4ae654d79e4eaaa42131d2a05210980c59" +dependencies = [ + "bincode", + "bytes", + "prost 0.12.3", + "prost-types 0.12.3", + "solana-perf", + "solana-sdk", + "tonic 0.10.2", + "tonic-build 0.10.2", +] + +[[package]] +name = "jito-searcher-client" +version = "0.1.0" +source = "git+https://github.com/dhruvja/searcher-examples#addf5b4ae654d79e4eaaa42131d2a05210980c59" +dependencies = [ + "futures-util", + "jito-protos", + "log", + "prost-types 0.12.3", + "solana-client", + "solana-metrics", + "solana-sdk", + "solana-transaction-status", + "thiserror", + "tokio", + "tonic 0.10.2", +] [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.61" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "jsonrpsee" version = "0.16.3" @@ -5578,14 +6867,14 @@ dependencies = [ "jsonrpsee-core", "jsonrpsee-types", "pin-project", - "rustls-native-certs 0.6.2", + "rustls-native-certs 0.6.3", "soketto", "thiserror", "tokio", "tokio-rustls 0.24.1", "tokio-util", "tracing", - "webpki-roots 0.25.2", + "webpki-roots 0.25.4", ] [[package]] @@ -5595,8 +6884,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b5dde66c53d6dcdc8caea1874a45632ec0fcf5b437789f1e45766a1512ce803" dependencies = [ "anyhow", - "arrayvec 0.7.2", - "async-lock", + "arrayvec 0.7.4", + "async-lock 2.8.0", "async-trait", "beef", "futures-channel", @@ -5605,7 +6894,7 @@ dependencies = [ "globset", "hyper", "jsonrpsee-types", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "rustc-hash", "serde", @@ -5624,7 +6913,7 @@ checksum = "7e5f9fabdd5d79344728521bb65e3106b49ec405a78b66fbff073b72b389fa43" dependencies = [ "async-trait", "hyper", - "hyper-rustls 0.24.1", + "hyper-rustls 0.24.2", "jsonrpsee-core", "jsonrpsee-types", "rustc-hash", @@ -5641,7 +6930,7 @@ version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44e8ab85614a08792b9bff6c8feee23be78c98d0182d4c622c05256ab553892a" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-crate 1.3.1", "proc-macro2", "quote", @@ -5705,28 +6994,29 @@ dependencies = [ "cfg-if 1.0.0", "ecdsa 0.14.8", "elliptic-curve 0.12.3", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", ] [[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 1.0.0", - "ecdsa 0.16.7", - "elliptic-curve 0.13.6", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", "once_cell", - "sha2 0.10.6", + "sha2 0.10.8", + "signature 2.2.0", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] @@ -5860,7 +7150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf7a85fe66f9ff9cd74e169fdd2c94c6e1e74c412c99a73b4df3200b5d3760b2" dependencies = [ "kvdb", - "parking_lot 0.12.1", + "parking_lot 0.12.2", ] [[package]] @@ -5871,7 +7161,7 @@ checksum = "b644c70b92285f66bfc2032922a79000ea30af7bc2ab31902992a5dcb9b434f6" dependencies = [ "kvdb", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "regex", "rocksdb", "smallvec", @@ -5889,11 +7179,25 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" +[[package]] +name = "lib" +version = "0.0.0" +dependencies = [ + "base64 0.21.7", + "borsh 0.10.3", + "bs58 0.5.1", + "bytemuck", + "derive_more", + "sha2 0.10.8", + "solana-program", + "stdx", +] + [[package]] name = "libc" -version = "0.2.148" +version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "libgit2-sys" @@ -5911,30 +7215,30 @@ dependencies = [ [[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 1.0.0", - "winapi", + "windows-targets 0.52.5", ] [[package]] name = "libm" -version = "0.2.6" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "348108ab3fba42ec82ff6e9564fc4ca0247bdccdc68dd8af9764bbc79c3c8ffb" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libp2p" -version = "0.51.3" +version = "0.51.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" +checksum = "f35eae38201a993ece6bdc823292d6abd1bffed1c4d0f4a3517d2bd8e1d917fe" dependencies = [ "bytes", "futures", "futures-timer", - "getrandom 0.2.8", + "getrandom 0.2.15", "instant", "libp2p-allow-block-list", "libp2p-connection-limits", @@ -5952,7 +7256,6 @@ dependencies = [ "libp2p-swarm", "libp2p-tcp", "libp2p-wasm-ext", - "libp2p-webrtc", "libp2p-websocket", "libp2p-yamux", "multiaddr", @@ -6000,7 +7303,7 @@ dependencies = [ "multihash 0.17.0", "multistream-select", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "pin-project", "quick-protobuf", "rand 0.8.5", @@ -6020,7 +7323,7 @@ dependencies = [ "futures", "libp2p-core", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "smallvec", "trust-dns-resolver", ] @@ -6053,14 +7356,14 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" dependencies = [ - "bs58", - "ed25519-dalek 2.0.0", + "bs58 0.4.0", + "ed25519-dalek 2.1.1", "log", "multiaddr", "multihash 0.17.0", "quick-protobuf", "rand 0.8.5", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "zeroize", ] @@ -6071,7 +7374,7 @@ version = "0.43.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "asynchronous-codec", "bytes", "either", @@ -6085,7 +7388,7 @@ dependencies = [ "log", "quick-protobuf", "rand 0.8.5", - "sha2 0.10.6", + "sha2 0.10.8", "smallvec", "thiserror", "uint", @@ -6108,7 +7411,7 @@ dependencies = [ "log", "rand 0.8.5", "smallvec", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", "trust-dns-proto", "void", @@ -6135,7 +7438,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3673da89d29936bc6435bafc638e2f184180d554ce844db65915113f86ec5e" dependencies = [ "bytes", - "curve25519-dalek 3.2.0", + "curve25519-dalek 3.2.1", "futures", "libp2p-core", "libp2p-identity", @@ -6143,11 +7446,11 @@ dependencies = [ "once_cell", "quick-protobuf", "rand 0.8.5", - "sha2 0.10.6", + "sha2 0.10.8", "snow", "static_assertions", "thiserror", - "x25519-dalek 1.1.1", + "x25519-dalek", "zeroize", ] @@ -6182,10 +7485,10 @@ dependencies = [ "libp2p-identity", "libp2p-tls", "log", - "parking_lot 0.12.1", - "quinn-proto", + "parking_lot 0.12.2", + "quinn-proto 0.9.6", "rand 0.8.5", - "rustls 0.20.8", + "rustls 0.20.9", "thiserror", "tokio", ] @@ -6233,7 +7536,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" dependencies = [ - "heck", + "heck 0.4.1", "quote", "syn 1.0.109", ] @@ -6250,7 +7553,7 @@ dependencies = [ "libc", "libp2p-core", "log", - "socket2 0.4.9", + "socket2 0.4.10", "tokio", ] @@ -6264,12 +7567,12 @@ dependencies = [ "futures-rustls", "libp2p-core", "libp2p-identity", - "rcgen 0.10.0", - "ring", - "rustls 0.20.8", + "rcgen", + "ring 0.16.20", + "rustls 0.20.9", "thiserror", - "webpki 0.22.0", - "x509-parser 0.14.0", + "webpki 0.22.4", + "x509-parser", "yasna", ] @@ -6287,37 +7590,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "libp2p-webrtc" -version = "0.4.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" -dependencies = [ - "async-trait", - "asynchronous-codec", - "bytes", - "futures", - "futures-timer", - "hex", - "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-noise", - "log", - "multihash 0.17.0", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "rcgen 0.9.3", - "serde", - "stun", - "thiserror", - "tinytemplate", - "tokio", - "tokio-util", - "webrtc", -] - [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -6329,7 +7601,7 @@ dependencies = [ "futures-rustls", "libp2p-core", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "quicksink", "rw-stream-sink", "soketto", @@ -6350,6 +7622,16 @@ dependencies = [ "yamux", ] +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + [[package]] name = "librocksdb-sys" version = "0.11.0+8.1.1" @@ -6365,6 +7647,25 @@ dependencies = [ "tikv-jemalloc-sys", ] +[[package]] +name = "libsecp256k1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" +dependencies = [ + "arrayref", + "base64 0.12.3", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core 0.2.2", + "libsecp256k1-gen-ecmult 0.2.1", + "libsecp256k1-gen-genmult 0.2.1", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "typenum", +] + [[package]] name = "libsecp256k1" version = "0.7.1" @@ -6375,15 +7676,26 @@ dependencies = [ "base64 0.13.1", "digest 0.9.0", "hmac-drbg", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", + "libsecp256k1-core 0.3.0", + "libsecp256k1-gen-ecmult 0.3.0", + "libsecp256k1-gen-genmult 0.3.0", "rand 0.8.5", "serde", "sha2 0.9.9", "typenum", ] +[[package]] +name = "libsecp256k1-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + [[package]] name = "libsecp256k1-core" version = "0.3.0" @@ -6395,13 +7707,31 @@ dependencies = [ "subtle", ] +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" +dependencies = [ + "libsecp256k1-core 0.2.2", +] + [[package]] name = "libsecp256k1-gen-ecmult" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" dependencies = [ - "libsecp256k1-core", + "libsecp256k1-core 0.3.0", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" +dependencies = [ + "libsecp256k1-core 0.2.2", ] [[package]] @@ -6410,7 +7740,18 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" dependencies = [ - "libsecp256k1-core", + "libsecp256k1-core 0.3.0", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", ] [[package]] @@ -6429,9 +7770,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.8" +version = "1.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +checksum = "5e143b5e666b2695d28f6bca6497720813f699c9602dd7f5cac91008b8ada7f9" dependencies = [ "cc", "libc", @@ -6447,7 +7788,7 @@ dependencies = [ "async-trait", "derive_more", "hash-db", - "ibc", + "ibc 0.15.0", "ibc-proto 0.18.0", "parity-scale-codec", "serde", @@ -6459,11 +7800,28 @@ dependencies = [ "subxt", ] +[[package]] +name = "light-poseidon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9a85a9752c549ceb7578064b4ed891179d20acd85f27318573b64d2d7ee7ee" +dependencies = [ + "ark-bn254", + "ark-ff", + "num-bigint 0.4.5", + "thiserror", +] + +[[package]] +name = "linear-map" +version = "1.2.0" +source = "git+https://github.com/contain-rs/linear-map?rev=57f1432e26ff902bc883b250a85e0b5716bd241c#57f1432e26ff902bc883b250a85e0b5716bd241c" + [[package]] name = "link-cplusplus" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" dependencies = [ "cc", ] @@ -6485,9 +7843,9 @@ dependencies = [ [[package]] name = "linregress" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475015a7f8f017edb28d2e69813be23500ad4b32cfe3421c4148efc97324ee52" +checksum = "4de04dcecc58d366391f9920245b85ffa684558a5ef6e7736e754347c3aea9c2" dependencies = [ "nalgebra", ] @@ -6500,15 +7858,15 @@ checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" [[package]] name = "linux-raw-sys" -version = "0.4.8" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.9" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -6516,12 +7874,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "lru" @@ -6606,7 +7961,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -6615,7 +7970,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] @@ -6626,16 +7981,17 @@ checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "matrixmultiply" -version = "0.3.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" dependencies = [ + "autocfg", "rawpointer", ] @@ -6645,66 +8001,65 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" -[[package]] -name = "md-5" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" -dependencies = [ - "digest 0.10.6", -] - [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memfd" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" dependencies = [ - "rustix 0.36.8", + "rustix 0.38.34", ] [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] +[[package]] +name = "memory" +version = "0.0.0" +dependencies = [ + "derive_more", + "stdx", +] + [[package]] name = "memory-db" version = "0.32.0" @@ -6732,6 +8087,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "merlin" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", +] + [[package]] name = "mick-jaeger" version = "0.1.8" @@ -6743,17 +8110,11 @@ dependencies = [ "thrift", ] -[[package]] -name = "micromath" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39617bc909d64b068dcffd0e3e31679195b5576d0c83fadc52690268cc2b2b55" - [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "minimal-lexical" @@ -6763,18 +8124,18 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +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", "wasi 0.11.0+wasi-snapshot-preview1", @@ -6818,9 +8179,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" +checksum = "4c84490118f2ee2d74570d114f3d0493cbf02790df303d2707606c3e14e07c96" dependencies = [ "cfg-if 1.0.0", "downcast", @@ -6833,9 +8194,9 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" +checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if 1.0.0", "proc-macro2", @@ -6849,7 +8210,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "698fbc4b1fd2af323ed1711664a873b332faa4dc740e0f810f40210573ba36fd" dependencies = [ - "clap 3.2.23", + "clap 3.2.25", "clap_complete", "directories", "hex", @@ -6860,14 +8221,27 @@ dependencies = [ "regex", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "tempfile", "thiserror", "tracing", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.18", "ureq", ] +[[package]] +name = "mpl-token-metadata" +version = "3.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba8ee05284d79b367ae8966d558e1a305a781fc80c9df51f37775169117ba64f" +dependencies = [ + "borsh 0.10.3", + "num-derive 0.3.3", + "num-traits", + "solana-program", + "thiserror", +] + [[package]] name = "multiaddr" version = "0.17.1" @@ -6908,10 +8282,10 @@ dependencies = [ "blake2s_simd", "blake3", "core2", - "digest 0.10.6", + "digest 0.10.7", "multihash-derive", - "sha2 0.10.6", - "sha3", + "sha2 0.10.8", + "sha3 0.10.8", "unsigned-varint", ] @@ -6922,9 +8296,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835d6ff01d610179fbce3de1694d007e500bf33a7f29689838941d6bf783ae40" dependencies = [ "core2", - "digest 0.10.6", + "digest 0.10.7", "multihash-derive", - "sha2 0.10.6", + "sha2 0.10.8", "unsigned-varint", ] @@ -6974,15 +8348,15 @@ dependencies = [ [[package]] name = "nalgebra" -version = "0.32.2" +version = "0.32.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d68d47bba83f9e2006d117a9a33af1524e655516b8919caac694427a6fb1e511" +checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef" dependencies = [ "approx", "matrixmultiply", "nalgebra-macros", - "num-complex", - "num-rational", + "num-complex 0.4.6", + "num-rational 0.4.2", "num-traits", "simba", "typenum", @@ -6990,9 +8364,9 @@ dependencies = [ [[package]] name = "nalgebra-macros" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232c68884c0c99810a5a4d333ef7e47689cfd0edc85efc9e54e1e6bf5212766" +checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" dependencies = [ "proc-macro2", "quote", @@ -7015,13 +8389,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" [[package]] -name = "netlink-packet-core" -version = "0.4.2" +name = "native-tls" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ - "anyhow", - "byteorder", + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "netlink-packet-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +dependencies = [ + "anyhow", + "byteorder", "libc", "netlink-packet-utils", ] @@ -7069,9 +8461,9 @@ dependencies = [ [[package]] name = "netlink-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "260e21fbb6f3d253a14df90eb0000a6066780a15dd901a7519ce02d77a94985b" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ "bytes", "futures", @@ -7089,7 +8481,19 @@ dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", "libc", - "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", + "memoffset 0.7.1", + "pin-utils", ] [[package]] @@ -7130,26 +8534,66 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint 0.2.6", + "num-complex 0.2.4", + "num-integer", + "num-iter", + "num-rational 0.2.4", + "num-traits", +] + [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" dependencies = [ "autocfg", "num-integer", "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-complex" -version = "0.4.3" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 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" @@ -7161,43 +8605,75 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] + [[package]] name = "num-format" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "itoa", ] [[package]] name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", + "num-integer", "num-traits", ] [[package]] name = "num-rational" -version = "0.4.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" dependencies = [ "autocfg", - "num-bigint", + "num-bigint 0.2.6", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint 0.4.5", "num-integer", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -7205,14 +8681,56 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi 0.3.9", "libc", ] +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 2.0.61", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.61", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -7221,23 +8739,23 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "object" -version = "0.30.3" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "crc32fast", "hashbrown 0.13.2", - "indexmap 1.9.2", + "indexmap 1.9.3", "memchr", ] [[package]] -name = "oid-registry" -version = "0.4.0" +name = "object" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e20717fa0541f39bd146692035c37bedfa532b3e5071b35761082407546b2a" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ - "asn1-rs 0.3.1", + "memchr", ] [[package]] @@ -7246,14 +8764,14 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", ] [[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" @@ -7263,9 +8781,35 @@ checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[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 1.0.0", + "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 = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] [[package]] name = "openssl-probe" @@ -7275,11 +8819,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.80" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23bbbf7854cd45b83958ebe919f0e8e516793727652e27fda10a8384cfc790b7" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -7310,7 +8853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2871aadd82a2c216ee68a69837a526dfe788ecbe74c4c5038a6acdbff6653066" dependencies = [ "expander 0.0.6", - "itertools", + "itertools 0.10.5", "petgraph", "proc-macro-crate 1.3.1", "proc-macro2", @@ -7397,9 +8940,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.4.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "overload" @@ -7407,28 +8950,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "p256" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.6", -] - -[[package]] -name = "p384" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa" -dependencies = [ - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.6", -] - [[package]] name = "pallet-assets" version = "4.0.0-dev" @@ -7720,7 +9241,7 @@ dependencies = [ "sp-npos-elections", "sp-runtime 7.0.0", "sp-std 5.0.0", - "strum", + "strum 0.24.1", ] [[package]] @@ -7800,19 +9321,23 @@ name = "pallet-ibc" version = "0.0.1" dependencies = [ "beefy-light-client-primitives", + "borsh 0.10.3", + "cf-guest 0.0.1", "chrono", "cumulus-primitives-core", "derive_more", - "env_logger 0.10.0", + "ed25519-dalek 2.1.1", + "env_logger 0.10.2", "finality-grandpa", "frame-benchmarking", "frame-support", "frame-system", "grandpa-light-client-primitives", + "guestchain", "hex", "hex-literal 0.3.4", - "ibc", - "ibc-derive", + "ibc 0.15.0", + "ibc-derive 0.1.0", "ibc-primitives 0.1.0", "ibc-proto 0.18.0", "ics07-tendermint", @@ -7832,11 +9357,11 @@ dependencies = [ "pallet-timestamp", "parachain-info", "parity-scale-codec", - "prost 0.11.6", + "prost 0.11.9", "scale-info", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "simple-iavl", "sp-consensus-aura", "sp-consensus-grandpa", @@ -7848,9 +9373,9 @@ dependencies = [ "sp-runtime 7.0.0", "sp-std 5.0.0", "sp-trie 7.0.0", - "tendermint 0.28.0", - "tendermint-light-client-verifier", - "tendermint-proto 0.28.0", + "tendermint 0.33.2", + "tendermint-light-client-verifier 0.33.2", + "tendermint-proto 0.33.2", ] [[package]] @@ -7859,7 +9384,7 @@ version = "0.0.1" dependencies = [ "frame-support", "frame-system", - "ibc", + "ibc 0.15.0", "ibc-primitives 0.1.0", "log", "parity-scale-codec", @@ -8280,7 +9805,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -8533,7 +10058,7 @@ dependencies = [ name = "parachain-node" version = "0.1.0" dependencies = [ - "clap 4.4.6", + "clap 4.5.4", "cumulus-client-cli", "cumulus-client-collator", "cumulus-client-consensus-aura", @@ -8622,7 +10147,7 @@ dependencies = [ "frame-system-rpc-runtime-api", "frame-try-runtime", "hex-literal 0.3.4", - "ibc", + "ibc 0.15.0", "ibc-primitives 0.1.0", "ibc-runtime-api", "log", @@ -8670,9 +10195,9 @@ dependencies = [ [[package]] name = "parity-db" -version = "0.4.11" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab512a34b3c2c5e465731cc7668edf79208bbe520be03484eeb05e63ed221735" +checksum = "592a28a24b09c9dc20ac8afaa6839abc417c720afe42c12e1e4a9d6aa2508d2e" dependencies = [ "blake2", "crc32fast", @@ -8682,19 +10207,20 @@ dependencies = [ "log", "lz4", "memmap2", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "siphasher", "snap", + "winapi", ] [[package]] name = "parity-scale-codec" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dec8a8073036902368c2cdc0387e85ff9a37054d7e7c98e592145e0c92cd4fb" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "arrayvec 0.7.2", + "arrayvec 0.7.4", "bitvec", "byte-slice-cast", "bytes", @@ -8705,11 +10231,11 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.5" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312270ee71e1cd70289dacf597cab7b207aa107d2f28191c2ae45b2ece18a260" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -8729,9 +10255,9 @@ checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" [[package]] name = "parking" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" [[package]] name = "parking_lot" @@ -8746,12 +10272,12 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", - "parking_lot_core 0.9.7", + "parking_lot_core 0.9.10", ] [[package]] @@ -8763,22 +10289,22 @@ dependencies = [ "cfg-if 1.0.0", "instant", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", "winapi", ] [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-sys 0.45.0", + "windows-targets 0.52.5", ] [[package]] @@ -8789,9 +10315,18 @@ checksum = "7924d1d0ad836f665c9065e26d016c673ece3993f30d340068b16f282afc1156" [[package]] name = "paste" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pbkdf2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac 0.8.0", +] [[package]] name = "pbkdf2" @@ -8808,7 +10343,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -8854,35 +10389,36 @@ dependencies = [ ] [[package]] -name = "pem-rfc7468" -version = "0.6.0" +name = "percent-encoding" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" -dependencies = [ - "base64ct", -] +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "percent-encoding" -version = "2.2.0" +name = "percentage" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +checksum = "2fd23b938276f14057220b707937bcb42fa76dda7560e57a2da30cb52d557937" +dependencies = [ + "num", +] [[package]] name = "pest" -version = "2.5.4" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ + "memchr", "thiserror", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.5.4" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" dependencies = [ "pest", "pest_generator", @@ -8890,56 +10426,56 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.5.4" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] name = "pest_meta" -version = "2.5.4" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" dependencies = [ "once_cell", "pest", - "sha2 0.10.6", + "sha2 0.10.8", ] [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 1.9.2", + "indexmap 2.2.6", ] [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] @@ -8950,9 +10486,9 @@ checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" [[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" @@ -8960,6 +10496,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +dependencies = [ + "der 0.5.1", + "spki 0.5.4", + "zeroize", +] + [[package]] name = "pkcs8" version = "0.9.0" @@ -8976,15 +10523,21 @@ 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.26" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "plain" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "platforms" @@ -8994,9 +10547,9 @@ checksum = "e8d0eef3571242013a0d5dc84861c3ae4a652e56e12adf8bdc26ff5f8cb34c94" [[package]] name = "platforms" -version = "3.0.2" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" [[package]] name = "polkadot-approval-distribution" @@ -9077,7 +10630,7 @@ name = "polkadot-cli" version = "0.9.43" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.43#ba42b9ce51d25bdaf52d2c61e0763a6e3da50d25" dependencies = [ - "clap 4.4.6", + "clap 4.5.4", "frame-benchmarking-cli", "futures", "log", @@ -9186,7 +10739,7 @@ dependencies = [ "fatality", "futures", "futures-timer", - "indexmap 1.9.2", + "indexmap 1.9.3", "lru 0.9.0", "parity-scale-codec", "polkadot-erasure-coding", @@ -9247,7 +10800,7 @@ dependencies = [ "fatality", "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-subsystem", @@ -9288,7 +10841,7 @@ dependencies = [ "futures-timer", "kvdb", "lru 0.9.0", - "merlin", + "merlin 2.0.1", "parity-scale-codec", "polkadot-node-jaeger", "polkadot-node-primitives", @@ -9297,7 +10850,7 @@ dependencies = [ "polkadot-overseer", "polkadot-primitives", "sc-keystore", - "schnorrkel", + "schnorrkel 0.9.1", "sp-application-crypto 7.0.0", "sp-consensus", "sp-consensus-slots", @@ -9563,7 +11116,7 @@ dependencies = [ "log", "mick-jaeger", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "polkadot-node-primitives", "polkadot-primitives", "sc-network", @@ -9577,7 +11130,7 @@ name = "polkadot-node-metrics" version = "0.9.43" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.43#ba42b9ce51d25bdaf52d2c61e0763a6e3da50d25" dependencies = [ - "bs58", + "bs58 0.4.0", "futures", "futures-timer", "log", @@ -9609,7 +11162,7 @@ dependencies = [ "rand 0.8.5", "sc-authority-discovery", "sc-network", - "strum", + "strum 0.24.1", "thiserror", "tracing-gum", ] @@ -9624,7 +11177,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain", "polkadot-primitives", - "schnorrkel", + "schnorrkel 0.9.1", "serde", "sp-application-crypto 7.0.0", "sp-consensus-babe", @@ -9679,7 +11232,7 @@ dependencies = [ "fatality", "futures", "futures-channel", - "itertools", + "itertools 0.10.5", "kvdb", "lru 0.9.0", "parity-db", @@ -9712,7 +11265,7 @@ dependencies = [ "futures-timer", "lru 0.9.0", "orchestra", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "polkadot-node-metrics", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -9924,7 +11477,7 @@ dependencies = [ "frame-support", "frame-system", "impl-trait-for-tuples", - "libsecp256k1", + "libsecp256k1 0.7.1", "log", "pallet-authorship", "pallet-babe", @@ -9978,7 +11531,7 @@ name = "polkadot-runtime-metrics" version = "0.9.43" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.43#ba42b9ce51d25bdaf52d2c61e0763a6e3da50d25" dependencies = [ - "bs58", + "bs58 0.4.0", "parity-scale-codec", "polkadot-primitives", "sp-std 5.0.0", @@ -10147,7 +11700,7 @@ dependencies = [ "arrayvec 0.5.2", "fatality", "futures", - "indexmap 1.9.2", + "indexmap 1.9.3", "parity-scale-codec", "polkadot-node-network-protocol", "polkadot-node-primitives", @@ -10172,27 +11725,28 @@ dependencies = [ [[package]] name = "polling" -version = "2.5.2" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +checksum = "645493cf344456ef24219d02a768cf1fb92ddf8c92161679ae3d91b91a637be3" dependencies = [ - "autocfg", "cfg-if 1.0.0", - "libc", - "log", - "wepoll-ffi", - "windows-sys 0.42.0", + "concurrent-queue", + "hermit-abi 0.3.9", + "pin-project-lite 0.2.14", + "rustix 0.38.34", + "tracing", + "windows-sys 0.52.0", ] [[package]] name = "poly1305" -version = "0.7.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash 0.4.1", + "opaque-debug 0.3.1", + "universal-hash 0.5.1", ] [[package]] @@ -10203,27 +11757,33 @@ checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", "universal-hash 0.4.1", ] [[package]] name = "polyval" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef234e08c11dfcb2e56f79fd70f6f2eb7f025c0ce2333e82f4f0518ecad30c6" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "opaque-debug 0.3.0", - "universal-hash 0.5.0", + "opaque-debug 0.3.1", + "universal-hash 0.5.1", ] [[package]] name = "portable-atomic" -version = "1.4.3" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -10239,7 +11799,7 @@ checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "float-cmp", - "itertools", + "itertools 0.10.5", "normalize-line-endings", "predicates-core", "regex", @@ -10247,25 +11807,35 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" [[package]] name = "predicates-tree" -version = "1.0.7" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" dependencies = [ "predicates-core", "termtree", ] +[[package]] +name = "prettier-please" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" +dependencies = [ + "proc-macro2", + "syn 2.0.61", +] + [[package]] name = "prettyplease" -version = "0.1.23" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78" +checksum = "f28f53e8b192565862cf99343194579a022eb9c7dd3a8d03134734803c7b3125" dependencies = [ "proc-macro2", "syn 1.0.109", @@ -10273,19 +11843,19 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.32", + "syn 2.0.61", ] [[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", "impl-codec", @@ -10326,7 +11896,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit", + "toml_edit 0.19.15", +] + +[[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]] @@ -10361,29 +11940,29 @@ checksum = "0e99670bafb56b9a106419397343bdbc8b8742c3cc449fec6345f86173f47cd4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +checksum = "3d33c28a30771f7f96db69893f78b857f7450d7e0237e9c8fc6427a81bae7ed1" dependencies = [ "cfg-if 1.0.0", "fnv", "lazy_static", "memchr", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "thiserror", ] @@ -10395,7 +11974,7 @@ checksum = "5d6fa99d535dd930d1249e6c79cb3c2915f9172a540fe2b02a4c8f9ca954721e" dependencies = [ "dtoa", "itoa", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "prometheus-client-derive-encode", ] @@ -10407,25 +11986,24 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "proptest" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f1b898011ce9595050a68e60f90bad083ff2987a695a42357134c8381fba70" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" dependencies = [ "bit-set", - "bitflags 1.3.2", - "byteorder", + "bit-vec", + "bitflags 2.5.0", "lazy_static", "num-traits", - "quick-error 2.0.1", "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax", + "regex-syntax 0.8.3", "rusty-fork", "tempfile", "unarray", @@ -10443,12 +12021,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive 0.11.6", + "prost-derive 0.11.9", ] [[package]] @@ -10463,26 +12041,48 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", - "heck", - "itertools", + "heck 0.4.1", + "itertools 0.10.5", "lazy_static", "log", "multimap", "petgraph", - "prettyplease 0.1.23", - "prost 0.11.6", - "prost-types 0.11.6", + "prettyplease 0.1.11", + "prost 0.11.9", + "prost-types 0.11.9", "regex", "syn 1.0.109", "tempfile", "which", ] +[[package]] +name = "prost-build" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.11.0", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease 0.2.20", + "prost 0.12.3", + "prost-types 0.12.3", + "regex", + "syn 2.0.61", + "tempfile", + "which", +] + [[package]] name = "prost-derive" version = "0.9.0" @@ -10490,7 +12090,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -10498,12 +12098,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -10516,20 +12116,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools", + "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "prost-types" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes", - "prost 0.11.6", + "prost 0.11.9", ] [[package]] @@ -10541,6 +12140,17 @@ dependencies = [ "prost 0.12.3", ] +[[package]] +name = "proto-utils" +version = "0.0.0" +dependencies = [ + "const_format", + "derive_more", + "ibc-core-client-context", + "ibc-proto 0.41.0", + "prost 0.12.3", +] + [[package]] name = "psm" version = "0.1.21" @@ -10551,16 +12161,30 @@ dependencies = [ ] [[package]] -name = "quick-error" -version = "1.2.3" +name = "qstring" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +checksum = "d464fae65fff2680baf48019211ce37aaec0c78e9264c84a3e484717f965104e" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "qualifier_attr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] [[package]] name = "quick-error" -version = "2.0.1" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quick-protobuf" @@ -10590,9 +12214,9 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5253a3a0d56548d5b0be25414171dc780cc6870727746d05bd2bde352eee96c5" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", "hashbrown 0.13.2", - "parking_lot 0.12.1", + "parking_lot 0.12.2", ] [[package]] @@ -10606,29 +12230,77 @@ dependencies = [ "pin-project-lite 0.1.12", ] +[[package]] +name = "quinn" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cc2c5017e4b43d5995dcea317bc46c1e09404c0a9664d2908f7f02dfe943d75" +dependencies = [ + "bytes", + "pin-project-lite 0.2.14", + "quinn-proto 0.10.6", + "quinn-udp", + "rustc-hash", + "rustls 0.21.12", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "quinn-proto" -version = "0.9.3" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" +dependencies = [ + "bytes", + "rand 0.8.5", + "ring 0.16.20", + "rustc-hash", + "rustls 0.20.9", + "slab", + "thiserror", + "tinyvec", + "tracing", + "webpki 0.22.4", +] + +[[package]] +name = "quinn-proto" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c10f662eee9c94ddd7135043e544f3c82fa839a1e7b865911331961b53186c" +checksum = "141bf7dfde2fbc246bfd3fe12f2455aa24b0fbd9af535d8c86c7bd1381ff2b1a" dependencies = [ "bytes", "rand 0.8.5", - "ring", + "ring 0.16.20", "rustc-hash", - "rustls 0.20.8", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", "slab", "thiserror", "tinyvec", "tracing", - "webpki 0.22.0", +] + +[[package]] +name = "quinn-udp" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "055b4e778e8feb9f93c4e439f71dc2156ef13360b432b799e179a8c4cdf0b1d7" +dependencies = [ + "bytes", + "libc", + "socket2 0.5.7", + "tracing", + "windows-sys 0.48.0", ] [[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", ] @@ -10726,7 +12398,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.15", ] [[package]] @@ -10756,6 +12428,15 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -10764,9 +12445,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.6.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -10774,27 +12455,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.2" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-channel 0.5.6", "crossbeam-deque", - "crossbeam-utils 0.8.14", - "num_cpus", -] - -[[package]] -name = "rcgen" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" -dependencies = [ - "pem", - "ring", - "time 0.3.17", - "x509-parser 0.13.2", - "yasna", + "crossbeam-utils 0.8.19", ] [[package]] @@ -10804,8 +12470,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", - "ring", - "time 0.3.17", + "ring 0.16.20", + "time", "yasna", ] @@ -10827,48 +12493,66 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[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 0.2.8", - "redox_syscall", + "getrandom 0.2.15", + "libredox", "thiserror", ] [[package]] name = "reed-solomon-novelpoly" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bd8f48b2066e9f69ab192797d66da804d1935bf22763204ed3675740cb0f221" +checksum = "58130877ca403ab42c864fbac74bb319a0746c07a634a92a5cfc7f54af272582" dependencies = [ "derive_more", "fs-err", - "itertools", - "static_init 0.5.2", + "itertools 0.11.0", + "static_init", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.14" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c78fb8c9293bcd48ef6fce7b4ca950ceaf21210de6e105a883ee280c0f7b9ed" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.14" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9c0c92af03644e4806106281fe2e068ac5bc0ae74a707266d06ea27bccee5f" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] @@ -10885,13 +12569,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", ] [[package]] @@ -10900,14 +12585,31 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", ] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "remove_dir_all" @@ -10918,6 +12620,52 @@ dependencies = [ "winapi", ] +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "async-compression", + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls 0.24.2", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite 0.2.14", + "rustls 0.21.12", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + [[package]] name = "resolv-conf" version = "0.7.0" @@ -10925,7 +12673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" dependencies = [ "hostname", - "quick-error 1.2.3", + "quick-error", ] [[package]] @@ -10958,19 +12706,34 @@ 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 1.0.0", + "getrandom 0.2.15", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + [[package]] name = "ripemd" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -11086,34 +12849,22 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "rs_merkle" -version = "1.2.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a632a43487c1332be8e183588079f89b6820fab24e04db49521eacd536837372" +checksum = "3b241d2e59b74ef9e98d94c78c47623d04c8392abaf82014dfd372a16041128f" dependencies = [ - "micromath", - "sha2 0.10.6", -] - -[[package]] -name = "rtcp" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1919efd6d4a6a85d13388f9487549bb8e359f17198cc03ffd72f79b553873691" -dependencies = [ - "bytes", - "thiserror", - "webrtc-util", + "sha2 0.10.8", ] [[package]] @@ -11126,40 +12877,40 @@ dependencies = [ "log", "netlink-packet-route", "netlink-proto", - "nix", + "nix 0.24.3", "thiserror", "tokio", ] [[package]] name = "rtoolbox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] -name = "rtp" -version = "0.6.8" +name = "rusqlite" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2a095411ff00eed7b12e4c6a118ba984d113e1079582570d56a5ee723f11f80" +checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" dependencies = [ - "async-trait", - "bytes", - "rand 0.8.5", - "serde", - "thiserror", - "webrtc-util", + "bitflags 2.5.0", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", ] [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -11179,7 +12930,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.16", + "semver 1.0.23", ] [[package]] @@ -11193,12 +12944,12 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.8" +version = "0.36.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "305efbd14fde4139eb501df5f136994bb520b033fa9fbdce287507dc23b8c7ed" dependencies = [ "bitflags 1.3.2", - "errno 0.2.8", + "errno", "io-lifetimes", "libc", "linux-raw-sys 0.1.4", @@ -11207,15 +12958,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.17" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25469e9ae0f3d0047ca8b93fc56843f38e6774f0914a107ff8b41be8be8e0b7" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.0", - "errno 0.3.4", + "bitflags 2.5.0", + "errno", "libc", - "linux-raw-sys 0.4.8", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.13", + "windows-sys 0.52.0", ] [[package]] @@ -11226,33 +12977,33 @@ checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ "base64 0.13.1", "log", - "ring", + "ring 0.16.20", "sct 0.6.1", "webpki 0.21.4", ] [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", - "ring", - "sct 0.7.0", - "webpki 0.22.0", + "ring 0.16.20", + "sct 0.7.1", + "webpki 0.22.4", ] [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring", - "rustls-webpki 0.101.6", - "sct 0.7.0", + "ring 0.17.8", + "rustls-webpki", + "sct 0.7.1", ] [[package]] @@ -11269,9 +13020,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -11281,38 +13032,28 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.0", -] - -[[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.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.11" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" [[package]] name = "rusty-fork" @@ -11321,7 +13062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" dependencies = [ "fnv", - "quick-error 1.2.3", + "quick-error", "tempfile", "wait-timeout", ] @@ -11339,17 +13080,17 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.12" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "safe-proc-macro2" -version = "1.0.36" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "814c536dcd27acf03296c618dab7ad62d28e70abd7ba41d3f34a2ce707a2c666" +checksum = "7fd85be67db87168aa3c13fd0da99f48f2ab005dccad5af5626138dc1df20eb6" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -11363,18 +13104,18 @@ dependencies = [ [[package]] name = "safe-regex" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15289bf322e0673d52756a18194167f2378ec1a15fe884af6e2d2cb934822b0" +checksum = "e6ab4bc484ef480a9ce79b381efd7b6767700f514d47bc599036e9d6f7f3c49d" dependencies = [ "safe-regex-macro", ] [[package]] name = "safe-regex-compiler" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba76fae590a2aa665279deb1f57b5098cbace01a0c5e60e262fcf55f7c51542" +checksum = "6d71f8c78bffb07962595e1bfa5ed11d24dd855eedc50b6a735f5ef648ce621b" dependencies = [ "safe-proc-macro2", "safe-quote", @@ -11382,9 +13123,9 @@ dependencies = [ [[package]] name = "safe-regex-macro" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c2e96b5c03f158d1b16ba79af515137795f4ad4e8de3f790518aae91f1d127" +checksum = "0909ab4b77511df24201cd66541d6a028887c77ecc065f277c68a12a663274ef" dependencies = [ "safe-proc-macro2", "safe-regex-compiler", @@ -11392,9 +13133,9 @@ dependencies = [ [[package]] name = "safe_arch" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" dependencies = [ "bytemuck", ] @@ -11432,8 +13173,8 @@ dependencies = [ "log", "multihash 0.17.0", "parity-scale-codec", - "prost 0.11.6", - "prost-build", + "prost 0.11.9", + "prost-build 0.11.9", "rand 0.8.5", "sc-client-api", "sc-network", @@ -11513,7 +13254,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -11523,7 +13264,7 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "array-bytes 4.2.0", "chrono", - "clap 4.4.6", + "clap 4.5.4", "fdlimit", "futures", "libp2p-identity", @@ -11552,7 +13293,7 @@ dependencies = [ "sp-runtime 7.0.0", "sp-version", "thiserror", - "tiny-bip39", + "tiny-bip39 1.0.0", "tokio", ] @@ -11565,7 +13306,7 @@ dependencies = [ "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-executor", "sc-transaction-pool-api", "sc-utils", @@ -11596,7 +13337,7 @@ dependencies = [ "log", "parity-db", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-client-api", "sc-state-db", "schnellru", @@ -11620,7 +13361,7 @@ dependencies = [ "libp2p-identity", "log", "mockall", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-client-api", "sc-utils", "serde", @@ -11672,11 +13413,11 @@ dependencies = [ "fork-tree", "futures", "log", - "num-bigint", - "num-rational", + "num-bigint 0.4.5", + "num-rational 0.4.2", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-client-api", "sc-consensus", "sc-consensus-epochs", @@ -11733,7 +13474,7 @@ dependencies = [ "futures", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-client-api", "sc-consensus", "sc-keystore", @@ -11766,7 +13507,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-consensus-beefy", "sc-rpc", "serde", @@ -11794,7 +13535,7 @@ name = "sc-consensus-grandpa" version = "0.10.0-dev" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", "array-bytes 4.2.0", "async-trait", "dyn-clone", @@ -11804,7 +13545,7 @@ dependencies = [ "futures-timer", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "sc-block-builder", "sc-chain-spec", @@ -11879,7 +13620,7 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "lru 0.8.1", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-executor-common", "sc-executor-wasmtime", "sp-api", @@ -11916,7 +13657,7 @@ dependencies = [ "libc", "log", "once_cell", - "rustix 0.36.8", + "rustix 0.36.17", "sc-allocator", "sc-executor-common", "sp-runtime-interface 7.0.0", @@ -11946,7 +13687,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ "array-bytes 4.2.0", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "serde_json", "sp-application-crypto 7.0.0", "sp-core 7.0.0", @@ -11975,7 +13716,7 @@ dependencies = [ "lru 0.8.1", "mockall", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "pin-project", "rand 0.8.5", "sc-block-builder", @@ -12009,8 +13750,8 @@ dependencies = [ "futures", "libp2p-identity", "log", - "prost 0.11.6", - "prost-build", + "prost 0.11.9", + "prost-build 0.11.9", "sc-client-api", "sc-network", "sc-network-common", @@ -12033,7 +13774,7 @@ dependencies = [ "futures-timer", "libp2p-identity", "parity-scale-codec", - "prost-build", + "prost-build 0.11.9", "sc-consensus", "sc-peerset", "sc-utils", @@ -12053,7 +13794,7 @@ name = "sc-network-gossip" version = "0.10.0-dev" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", "futures", "futures-timer", "libp2p", @@ -12078,8 +13819,8 @@ dependencies = [ "libp2p-identity", "log", "parity-scale-codec", - "prost 0.11.6", - "prost-build", + "prost 0.11.9", + "prost-build 0.11.9", "sc-client-api", "sc-network", "sc-network-common", @@ -12106,8 +13847,8 @@ dependencies = [ "lru 0.8.1", "mockall", "parity-scale-codec", - "prost 0.11.6", - "prost-build", + "prost 0.11.9", + "prost-build 0.11.9", "sc-client-api", "sc-consensus", "sc-network", @@ -12161,7 +13902,7 @@ dependencies = [ "num_cpus", "once_cell", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "sc-client-api", "sc-network", @@ -12184,7 +13925,7 @@ dependencies = [ "futures", "libp2p-identity", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "partial_sort", "sc-utils", "serde_json", @@ -12210,7 +13951,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-block-builder", "sc-chain-spec", "sc-client-api", @@ -12263,7 +14004,7 @@ dependencies = [ "substrate-prometheus-endpoint", "tokio", "tower", - "tower-http 0.4.4", + "tower-http", ] [[package]] @@ -12278,7 +14019,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-chain-spec", "sc-client-api", "sc-transaction-pool-api", @@ -12305,7 +14046,7 @@ dependencies = [ "jsonrpsee", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "pin-project", "rand 0.8.5", "sc-block-builder", @@ -12349,7 +14090,7 @@ dependencies = [ "sp-transaction-storage-proof", "sp-trie 7.0.0", "sp-version", - "static_init 1.0.3", + "static_init", "substrate-prometheus-endpoint", "tempfile", "thiserror", @@ -12365,7 +14106,7 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sp-core 7.0.0", ] @@ -12374,7 +14115,7 @@ name = "sc-storage-monitor" version = "0.1.0" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ - "clap 4.4.6", + "clap 4.5.4", "fs4", "futures", "log", @@ -12432,7 +14173,7 @@ dependencies = [ "futures", "libp2p", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "pin-project", "rand 0.8.5", "sc-utils", @@ -12454,7 +14195,7 @@ dependencies = [ "libc", "log", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "regex", "rustc-hash", "sc-client-api", @@ -12469,7 +14210,7 @@ dependencies = [ "sp-tracing 6.0.0", "thiserror", "tracing", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber 0.2.25", ] @@ -12481,7 +14222,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -12496,7 +14237,7 @@ dependencies = [ "log", "num-traits", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sc-client-api", "sc-transaction-pool-api", "sc-utils", @@ -12535,7 +14276,7 @@ dependencies = [ "futures-timer", "lazy_static", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "prometheus", "sp-arithmetic 6.0.0", ] @@ -12636,9 +14377,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.9.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" dependencies = [ "bitvec", "cfg-if 1.0.0", @@ -12650,11 +14391,11 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.9.0" +version = "2.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 1.0.109", @@ -12682,18 +14423,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.52.0", ] [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "fc6e7ed6919cb46507fb01ff1654309219f62b4d603822501b0b80d42f6f21ef" dependencies = [ "dyn-clone", "schemars_derive", @@ -12703,23 +14444,23 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "185f2b7aa7e02d418e453790dde16890256bbd2bcd04b7dc5348811052b53f49" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] name = "schnellru" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772575a524feeb803e5b0fcbc6dd9f367e579488197c94c6e4023aad2305774d" +checksum = "6b0cf7da6fc4477944d5529807234f66802fcb618fc62b9c05bedca7f9be6c43" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", "cfg-if 1.0.0", "hashbrown 0.13.2", ] @@ -12734,7 +14475,7 @@ dependencies = [ "arrayvec 0.5.2", "curve25519-dalek 2.1.3", "getrandom 0.1.16", - "merlin", + "merlin 2.0.1", "rand 0.7.3", "rand_core 0.5.1", "sha2 0.8.2", @@ -12743,16 +14484,53 @@ dependencies = [ ] [[package]] -name = "scopeguard" -version = "1.1.0" +name = "schnorrkel" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "8de18f6d8ba0aad7045f5feae07ec29899c1112584a38509a84ad7b04451eaa0" +dependencies = [ + "arrayref", + "arrayvec 0.7.4", + "curve25519-dalek 4.1.1", + "getrandom_or_panic", + "merlin 3.0.0", + "rand_core 0.6.4", + "sha2 0.10.8", + "subtle", + "zeroize", +] [[package]] -name = "scratch" -version = "1.0.3" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scratch" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" + +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", +] [[package]] name = "sct" @@ -12760,30 +14538,34 @@ 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]] -name = "sdp" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d22a5ef407871893fd72b4562ee15e4742269b173959db4b8df6f538c414e13" +name = "sealable-trie" +version = "0.0.0" dependencies = [ - "rand 0.8.5", - "substring", - "thiserror", - "url", + "ascii 1.1.0", + "base64 0.21.7", + "borsh 0.10.3", + "bytemuck", + "derive_more", + "lib", + "memory", + "sha2 0.10.8", + "stdx", + "strum 0.25.0", ] [[package]] @@ -12794,7 +14576,7 @@ checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ "base16ct 0.1.1", "der 0.6.1", - "generic-array 0.14.6", + "generic-array 0.14.7", "pkcs8 0.9.0", "subtle", "zeroize", @@ -12802,13 +14584,13 @@ dependencies = [ [[package]] name = "sec1" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", - "der 0.7.8", - "generic-array 0.14.6", + "der 0.7.9", + "generic-array 0.14.7", "pkcs8 0.10.2", "subtle", "zeroize", @@ -12843,11 +14625,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.8.2" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.5.0", "core-foundation", "core-foundation-sys", "libc", @@ -12856,9 +14638,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.8.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" dependencies = [ "core-foundation-sys", "libc", @@ -12875,9 +14657,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.16" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -12890,27 +14672,36 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.188" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.5.1" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9213a07d53faa0b8dd81e767a54a8188a242fdb9be99ab75ec576a774bfdd7" +dependencies = [ + "serde", +] + +[[package]] +name = "serde-json-wasm" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" dependencies = [ "serde", ] [[package]] name = "serde_bytes" -version = "0.11.9" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] @@ -12927,31 +14718,31 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "serde_derive_internals" -version = "0.26.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] name = "serde_json" -version = "1.0.96" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -12960,57 +14751,80 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.10" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[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", ] [[package]] -name = "sha-1" -version = "0.9.8" +name = "serde_urlencoded" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug 0.3.0", + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "serde", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling 0.20.8", + "proc-macro2", + "quote", + "syn 2.0.61", ] [[package]] name = "sha-1" -version = "0.10.1" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ + "block-buffer 0.9.0", "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest 0.9.0", + "opaque-debug 0.3.1", ] [[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 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -13035,50 +14849,68 @@ dependencies = [ "cfg-if 1.0.0", "cpufeatures", "digest 0.9.0", - "opaque-debug 0.3.0", + "opaque-debug 0.3.1", ] [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "sha3" -version = "0.10.6" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha3" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] [[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", ] [[package]] -name = "shlex" +name = "shell-words" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -13089,17 +14921,17 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] [[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.6", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -13110,12 +14942,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" dependencies = [ "approx", - "num-complex", + "num-complex 0.4.6", "num-traits", "paste", "wide", ] +[[package]] +name = "similar" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" + [[package]] name = "simnode-runtime-apis" version = "0.1.0" @@ -13140,8 +14978,8 @@ dependencies = [ "ics23 0.10.0", "proptest", "rand 0.8.5", - "sha2 0.10.6", - "tendermint 0.28.0", + "sha2 0.10.8", + "tendermint 0.33.2", ] [[package]] @@ -13150,20 +14988,30 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + [[package]] name = "slab" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "slice-group-by" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" [[package]] name = "slot-range-helper" @@ -13179,47 +15027,47 @@ dependencies = [ [[package]] name = "slotmap" -version = "1.0.6" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" dependencies = [ "version_check", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +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 = "snow" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c9d1425eb528a21de2755c75af4c9b5d57f50a0d4c3b7f1828a4cd03f8ba155" +checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" dependencies = [ - "aes-gcm 0.9.4", + "aes-gcm", "blake2", "chacha20poly1305", "curve25519-dalek 4.1.1", "rand_core 0.6.4", - "ring", + "ring 0.17.8", "rustc_version", - "sha2 0.10.6", + "sha2 0.10.8", "subtle", ] [[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", @@ -13227,12 +15075,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -13249,7 +15097,821 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "sha-1 0.9.8", + "sha-1", +] + +[[package]] +name = "solana-account-decoder" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4e29f060cabd0e1bd90a63f8e1517ddd3365d3dc2eaa05f9a9fa542f4adeaaa" +dependencies = [ + "Inflector", + "base64 0.21.7", + "bincode", + "bs58 0.4.0", + "bv", + "lazy_static", + "serde", + "serde_derive", + "serde_json", + "solana-config-program", + "solana-sdk", + "spl-token", + "spl-token-2022 1.0.0", + "spl-token-group-interface", + "spl-token-metadata-interface", + "thiserror", + "zstd 0.11.2+zstd.1.5.2", +] + +[[package]] +name = "solana-allocator" +version = "0.0.3" +dependencies = [ + "bytemuck", + "solana-program", +] + +[[package]] +name = "solana-clap-utils" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e5cdc0ae0c8ae79c39a4a362066d0d61764bc7ea7e033961fd7510fd24da2a" +dependencies = [ + "chrono", + "clap 2.34.0", + "rpassword", + "solana-remote-wallet", + "solana-sdk", + "thiserror", + "tiny-bip39 0.8.2", + "uriparse", + "url", +] + +[[package]] +name = "solana-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e2301c2af7e5a1dba0855f710329a2bb993829ed9fdf8f6207d02ee6fc54a4" +dependencies = [ + "async-trait", + "bincode", + "dashmap", + "futures", + "futures-util", + "indexmap 2.2.6", + "indicatif", + "log", + "quinn", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-quic-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-rpc-client-nonce-utils", + "solana-sdk", + "solana-streamer", + "solana-thin-client", + "solana-tpu-client", + "solana-udp-client", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-config-program" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595118948b966b110aad3f9d8d8464958abe379ecfa7a813b4fc82659c8259bc" +dependencies = [ + "bincode", + "chrono", + "serde", + "serde_derive", + "solana-program-runtime", + "solana-sdk", +] + +[[package]] +name = "solana-connection-cache" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d363d6bb43e618b6010b47c2eb0579777ce4ed388ca15b84a610a738edf0b97e" +dependencies = [ + "async-trait", + "bincode", + "crossbeam-channel 0.5.12", + "futures-util", + "indexmap 2.2.6", + "log", + "rand 0.8.5", + "rayon", + "rcgen", + "solana-measure", + "solana-metrics", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-frozen-abi" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96734b05823c8b515f8e3cc02641a27aee2c9760b1a43c74cb20f2a1ab0ab76c" +dependencies = [ + "ahash 0.8.5", + "blake3", + "block-buffer 0.10.4", + "bs58 0.4.0", + "bv", + "byteorder", + "cc", + "either", + "generic-array 0.14.7", + "im", + "lazy_static", + "log", + "memmap2", + "rustc_version", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "solana-frozen-abi-macro", + "subtle", + "thiserror", +] + +[[package]] +name = "solana-frozen-abi-macro" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a0f1291a464fd046135d019d57a81be165ee3d23aa7df880b47dac683a0582a" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.61", +] + +[[package]] +name = "solana-ibc" +version = "0.0.3" +dependencies = [ + "anchor-lang", + "anchor-spl", + "base64 0.21.7", + "bytemuck", + "cf-guest 0.0.0", + "derive_more", + "guestchain", + "hex-literal 0.4.1", + "ibc 0.50.0", + "ibc-client-tendermint-types", + "ibc-proto 0.41.0", + "itertools 0.10.5", + "lib", + "linear-map", + "memory", + "primitive-types", + "prost 0.12.3", + "serde", + "serde_json", + "solana-allocator", + "solana-signature-verifier", + "solana-trie", + "spl-associated-token-account", + "spl-token", + "stdx", + "strum 0.25.0", + "tendermint 0.34.1", + "tendermint-light-client-verifier 0.34.1", + "trie-ids", + "uint", + "wasm", +] + +[[package]] +name = "solana-logger" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5977c8f24b83cf50e7139ffdb25d70bad6a177f18ccc79ca2293d6a987fa81c" +dependencies = [ + "env_logger 0.9.3", + "lazy_static", + "log", +] + +[[package]] +name = "solana-measure" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a39ef01b2c65552d05013b2642ffd73258f2c80e3a59e44c499762047df9456" +dependencies = [ + "log", + "solana-sdk", +] + +[[package]] +name = "solana-metrics" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad30ff3775412f2929d440446aef8b070676920bc5df495ea6398a8f28ce91f" +dependencies = [ + "crossbeam-channel 0.5.12", + "gethostname", + "lazy_static", + "log", + "reqwest", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-net-utils" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafd5178a38a039e12c14780f1b6a74f1e672d62357343e0aee6d0fc7e5bd18" +dependencies = [ + "bincode", + "clap 3.2.25", + "crossbeam-channel 0.5.12", + "log", + "nix 0.26.4", + "rand 0.8.5", + "serde", + "serde_derive", + "socket2 0.5.7", + "solana-logger", + "solana-sdk", + "solana-version", + "tokio", + "url", +] + +[[package]] +name = "solana-perf" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d6293cddcc98ae092d00f43f741405da30aa083acb96666606130810b064f3" +dependencies = [ + "ahash 0.8.5", + "bincode", + "bv", + "caps", + "curve25519-dalek 3.2.1", + "dlopen2", + "fnv", + "lazy_static", + "libc", + "log", + "nix 0.26.4", + "rand 0.8.5", + "rayon", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-rayon-threadlimit", + "solana-sdk", + "solana-vote-program", +] + +[[package]] +name = "solana-program" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6412447793f8a3ef7526655906728325093b472e481791ac5c584e8d272166dc" +dependencies = [ + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "base64 0.21.7", + "bincode", + "bitflags 2.5.0", + "blake3", + "borsh 0.10.3", + "borsh 0.9.3", + "bs58 0.4.0", + "bv", + "bytemuck", + "cc", + "console_error_panic_hook", + "console_log", + "curve25519-dalek 3.2.1", + "getrandom 0.2.15", + "itertools 0.10.5", + "js-sys", + "lazy_static", + "libc", + "libsecp256k1 0.6.0", + "light-poseidon", + "log", + "memoffset 0.9.1", + "num-bigint 0.4.5", + "num-derive 0.3.3", + "num-traits", + "parking_lot 0.12.2", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk-macro", + "thiserror", + "tiny-bip39 0.8.2", + "wasm-bindgen", + "zeroize", +] + +[[package]] +name = "solana-program-runtime" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1977e741a6793fca27413507457d797df0f41bc0ae634247d112bc77ab2b0325" +dependencies = [ + "base64 0.21.7", + "bincode", + "eager", + "enum-iterator", + "itertools 0.10.5", + "libc", + "log", + "num-derive 0.3.3", + "num-traits", + "percentage", + "rand 0.8.5", + "rustc_version", + "serde", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-measure", + "solana-metrics", + "solana-sdk", + "solana_rbpf", + "thiserror", +] + +[[package]] +name = "solana-pubsub-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad21dd5d6fe09116dbc29aec279b7cf08d250b564899dc87437bd780ed26290" +dependencies = [ + "crossbeam-channel 0.5.12", + "futures-util", + "log", + "reqwest", + "semver 1.0.23", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite 0.20.1", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6201869768fe133ce9b8088e4f718f53ff164b8e5df3d0d46a6563a22545924f" +dependencies = [ + "async-mutex", + "async-trait", + "futures", + "itertools 0.10.5", + "lazy_static", + "log", + "quinn", + "quinn-proto 0.10.6", + "rcgen", + "rustls 0.21.12", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-rpc-client-api", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-rayon-threadlimit" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f100d0c3214d67bb847a1eefc7079f6bb755534266423f4c994ad3b40c685ed" +dependencies = [ + "lazy_static", + "num_cpus", +] + +[[package]] +name = "solana-remote-wallet" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3328c891079086b408a04e701470a346d517c9c51c0a96f2f166f616a3e1c3c8" +dependencies = [ + "console", + "dialoguer", + "log", + "num-derive 0.3.3", + "num-traits", + "parking_lot 0.12.2", + "qstring", + "semver 1.0.23", + "solana-sdk", + "thiserror", + "uriparse", +] + +[[package]] +name = "solana-rpc-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfacf1163a375d98c29779a03ba278b2ef43494f77e33826a33f9460563c0887" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bincode", + "bs58 0.4.0", + "indicatif", + "log", + "reqwest", + "semver 1.0.23", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "tokio", +] + +[[package]] +name = "solana-rpc-client-api" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fab293a88113511e66607d76bd027edfe0b1372b467fd76bbb5af03448539a2" +dependencies = [ + "base64 0.21.7", + "bs58 0.4.0", + "jsonrpc-core", + "reqwest", + "semver 1.0.23", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e43cb51374a6ec8fd401b3387334ef93e04f6d8ae87bbb29892aff42aeb1061" +dependencies = [ + "clap 2.34.0", + "solana-clap-utils", + "solana-rpc-client", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-sdk" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de1ce8848de4198f9bc7e4574252be02b1ed86ecbc2fff506780d5f8d6e4c4a8" +dependencies = [ + "assert_matches", + "base64 0.21.7", + "bincode", + "bitflags 2.5.0", + "borsh 0.10.3", + "bs58 0.4.0", + "bytemuck", + "byteorder", + "chrono", + "derivation-path", + "digest 0.10.7", + "ed25519-dalek 1.0.1", + "ed25519-dalek-bip32", + "generic-array 0.14.7", + "hmac 0.12.1", + "itertools 0.10.5", + "js-sys", + "lazy_static", + "libsecp256k1 0.6.0", + "log", + "memmap2", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "pbkdf2 0.11.0", + "qstring", + "qualifier_attr", + "rand 0.7.3", + "rand 0.8.5", + "rustc_version", + "rustversion", + "serde", + "serde_bytes", + "serde_derive", + "serde_json", + "serde_with", + "sha2 0.10.8", + "sha3 0.10.8", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-logger", + "solana-program", + "solana-sdk-macro", + "thiserror", + "uriparse", + "wasm-bindgen", +] + +[[package]] +name = "solana-sdk-macro" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cc46bbda0a5472d8d0a4c846b22941436ac45c31456d3e885a387a5f264f7" +dependencies = [ + "bs58 0.4.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.61", +] + +[[package]] +name = "solana-security-txt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" + +[[package]] +name = "solana-signature-verifier" +version = "0.0.3" +dependencies = [ + "base64 0.21.7", + "borsh 0.10.3", + "bytemuck", + "derive_more", + "guestchain", + "lib", + "solana-program", + "stdx", +] + +[[package]] +name = "solana-streamer" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f02b475fc20c55ebbcfa5638ff93f9b780414cc6185e3a6d0992bca0ae81ee" +dependencies = [ + "async-channel", + "bytes", + "crossbeam-channel 0.5.12", + "futures-util", + "histogram", + "indexmap 2.2.6", + "itertools 0.10.5", + "libc", + "log", + "nix 0.26.4", + "pem", + "percentage", + "pkcs8 0.8.0", + "quinn", + "quinn-proto 0.10.6", + "rand 0.8.5", + "rcgen", + "rustls 0.21.12", + "smallvec", + "solana-metrics", + "solana-perf", + "solana-sdk", + "thiserror", + "tokio", + "x509-parser", +] + +[[package]] +name = "solana-thin-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6ce2304764b8bb699db734fde9cd19ace038d3895d828a557ea0ec2a9e0ecd" +dependencies = [ + "bincode", + "log", + "rayon", + "solana-connection-cache", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", +] + +[[package]] +name = "solana-tpu-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa3e2351625e26f55e5e08f8e5aadaa2380fd0649f25641d6ba3f3848dbe5c9a" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap 2.2.6", + "indicatif", + "log", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-transaction-status" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0841bbd1845c87043e4184961e45cc7c08b36d96d0d146256b26ea5c74630a0f" +dependencies = [ + "Inflector", + "base64 0.21.7", + "bincode", + "borsh 0.10.3", + "bs58 0.4.0", + "lazy_static", + "log", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "spl-associated-token-account", + "spl-memo", + "spl-token", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "solana-trie" +version = "0.0.3" +dependencies = [ + "bytemuck", + "lib", + "memory", + "sealable-trie", + "solana-program", + "stdx", +] + +[[package]] +name = "solana-udp-client" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae54a100f0b0b5be065f5d05f2259f6d4a7b39f5866d579927f3ca35a01773b" +dependencies = [ + "async-trait", + "solana-connection-cache", + "solana-net-utils", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + +[[package]] +name = "solana-version" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f69945e38d7440221e2fac0aaa57a9d72adb329b0de705ca5bd9ba981aedc16" +dependencies = [ + "log", + "rustc_version", + "semver 1.0.23", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-sdk", +] + +[[package]] +name = "solana-vote-program" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e574aafc3c5adc7106ab4605d8ad378c9a12f2cf1dec2e8ba1aa6fd97a5d5490" +dependencies = [ + "bincode", + "log", + "num-derive 0.3.3", + "num-traits", + "rustc_version", + "serde", + "serde_derive", + "solana-frozen-abi", + "solana-frozen-abi-macro", + "solana-metrics", + "solana-program", + "solana-program-runtime", + "solana-sdk", + "thiserror", +] + +[[package]] +name = "solana-write-account" +version = "0.0.3" +dependencies = [ + "solana-program", + "stdx", +] + +[[package]] +name = "solana-zk-token-sdk" +version = "1.17.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597dddc8ab46852dea7fc3d22e031fa4ffdb1b2291ac24d960605424a510a5f5" +dependencies = [ + "aes-gcm-siv", + "base64 0.21.7", + "bincode", + "bytemuck", + "byteorder", + "curve25519-dalek 3.2.1", + "getrandom 0.1.16", + "itertools 0.10.5", + "lazy_static", + "merlin 3.0.0", + "num-derive 0.3.3", + "num-traits", + "rand 0.7.3", + "serde", + "serde_json", + "sha3 0.9.1", + "solana-program", + "solana-sdk", + "subtle", + "thiserror", + "zeroize", +] + +[[package]] +name = "solana_rbpf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d457cc2ba742c120492a64b7fa60e22c575e891f6b55039f4d736568fb112a3" +dependencies = [ + "byteorder", + "combine", + "goblin", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "scroll", + "thiserror", + "winapi", ] [[package]] @@ -13283,7 +15945,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -13376,7 +16038,7 @@ dependencies = [ "log", "lru 0.8.1", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sp-api", "sp-consensus", "sp-database", @@ -13455,7 +16117,7 @@ dependencies = [ "sp-mmr-primitives", "sp-runtime 7.0.0", "sp-std 5.0.0", - "strum", + "strum 0.24.1", ] [[package]] @@ -13497,7 +16159,7 @@ dependencies = [ "bitflags 1.3.2", "blake2", "bounded-collections", - "bs58", + "bs58 0.4.0", "dyn-clonable", "ed25519-zebra", "futures", @@ -13505,17 +16167,17 @@ dependencies = [ "hash256-std-hasher", "impl-serde 0.4.0", "lazy_static", - "libsecp256k1", + "libsecp256k1 0.7.1", "log", - "merlin", + "merlin 2.0.1", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "paste", "primitive-types", "rand 0.8.5", "regex", "scale-info", - "schnorrkel", + "schnorrkel 0.9.1", "secp256k1", "secrecy", "serde", @@ -13528,7 +16190,7 @@ dependencies = [ "ss58-registry", "substrate-bip39", "thiserror", - "tiny-bip39", + "tiny-bip39 1.0.0", "zeroize", ] @@ -13542,7 +16204,7 @@ dependencies = [ "bitflags 1.3.2", "blake2", "bounded-collections", - "bs58", + "bs58 0.4.0", "dyn-clonable", "ed25519-zebra", "futures", @@ -13550,17 +16212,17 @@ dependencies = [ "hash256-std-hasher", "impl-serde 0.4.0", "lazy_static", - "libsecp256k1", + "libsecp256k1 0.7.1", "log", - "merlin", + "merlin 2.0.1", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "paste", "primitive-types", "rand 0.8.5", "regex", "scale-info", - "schnorrkel", + "schnorrkel 0.9.1", "secp256k1", "secrecy", "serde", @@ -13573,7 +16235,7 @@ dependencies = [ "ss58-registry", "substrate-bip39", "thiserror", - "tiny-bip39", + "tiny-bip39 1.0.0", "zeroize", ] @@ -13584,9 +16246,9 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "blake2b_simd", "byteorder", - "digest 0.10.6", - "sha2 0.10.6", - "sha3", + "digest 0.10.7", + "sha2 0.10.8", + "sha3 0.10.8", "sp-std 5.0.0", "twox-hash", ] @@ -13599,9 +16261,9 @@ checksum = "2ee599a8399448e65197f9a6cee338ad192e9023e35e31f22382964c3c174c68" dependencies = [ "blake2b_simd", "byteorder", - "digest 0.10.6", - "sha2 0.10.6", - "sha3", + "digest 0.10.7", + "sha2 0.10.8", + "sha3 0.10.8", "sp-std 8.0.0", "twox-hash", ] @@ -13614,7 +16276,7 @@ dependencies = [ "proc-macro2", "quote", "sp-core-hashing 5.0.0", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -13623,7 +16285,7 @@ version = "4.0.0-dev" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ "kvdb", - "parking_lot 0.12.1", + "parking_lot 0.12.2", ] [[package]] @@ -13644,7 +16306,7 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -13655,7 +16317,7 @@ checksum = "c7f531814d2f16995144c74428830ccf7d94ff4a7749632b83ad8199b181140c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -13705,7 +16367,7 @@ dependencies = [ "ed25519 1.5.3", "ed25519-dalek 1.0.1", "futures", - "libsecp256k1", + "libsecp256k1 0.7.1", "log", "parity-scale-codec", "rustversion", @@ -13732,7 +16394,7 @@ dependencies = [ "ed25519 1.5.3", "ed25519-dalek 1.0.1", "futures", - "libsecp256k1", + "libsecp256k1 0.7.1", "log", "parity-scale-codec", "rustversion", @@ -13757,7 +16419,7 @@ dependencies = [ "lazy_static", "sp-core 7.0.0", "sp-runtime 7.0.0", - "strum", + "strum 0.24.1", ] [[package]] @@ -13767,7 +16429,7 @@ source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9. dependencies = [ "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "serde", "sp-core 7.0.0", "sp-externalities 0.13.0", @@ -13782,7 +16444,7 @@ checksum = "9be3cdd67cc1d9c1db17c5cbc4ec4924054a8437009d167f21f6590797e4aa45" dependencies = [ "futures", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "sp-core 21.0.0", "sp-externalities 0.19.0", "thiserror", @@ -13972,7 +16634,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -13985,7 +16647,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -14023,7 +16685,7 @@ dependencies = [ "hash-db", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "smallvec", "sp-core 7.0.0", @@ -14044,7 +16706,7 @@ dependencies = [ "hash-db", "log", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "smallvec", "sp-core 21.0.0", @@ -14202,14 +16864,14 @@ name = "sp-trie" version = "7.0.0" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", "hash-db", "hashbrown 0.13.2", "lazy_static", "memory-db", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "scale-info", "schnellru", "sp-core 7.0.0", @@ -14226,14 +16888,14 @@ version = "22.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48e4eeb7ef23f79eba8609db79ef9cef242f994f1f87a3c0387b4b5f177fda74" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.5", "hash-db", "hashbrown 0.13.2", "lazy_static", "memory-db", "nohash-hasher", "parity-scale-codec", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "scale-info", "schnellru", "sp-core 21.0.0", @@ -14269,7 +16931,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -14337,15 +16999,31 @@ 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 = "spinners" -version = "4.1.0" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08615eea740067d9899969bc2891c68a19c315cb1f66640af9a9ecb91b13bcab" +checksum = "a0ef947f358b9c238923f764c72a4a9d42f2d637c46e059dbd319d6e7cfb4f82" dependencies = [ "lazy_static", "maplit", - "strum", + "strum 0.24.1", +] + +[[package]] +name = "spki" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +dependencies = [ + "base64ct", + "der 0.5.1", ] [[package]] @@ -14360,19 +17038,278 @@ 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]] +name = "spl-associated-token-account" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "992d9c64c2564cc8f63a4b508bf3ebcdf2254b0429b13cd1d31adb6162432a5f" +dependencies = [ + "assert_matches", + "borsh 0.10.3", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-token", + "spl-token-2022 1.0.0", + "thiserror", +] + +[[package]] +name = "spl-discriminator" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daa600f2fe56f32e923261719bae640d873edadbc5237681a39b8e37bfd4d263" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" +dependencies = [ + "quote", + "spl-discriminator-syn", + "syn 2.0.61", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.61", + "thiserror", +] + +[[package]] +name = "spl-memo" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5db7e4efb1107b0b8e52a13f035437cdcb36ef99c58f6d467f089d9b2915a" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e0657b6490196971d9e729520ba934911ff41fbb2cb9004463dbe23cf8b4b4f" +dependencies = [ + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" +dependencies = [ + "proc-macro2", + "quote", + "sha2 0.10.8", + "syn 2.0.61", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f335787add7fa711819f9e7c573f8145a5358a709446fe2d24bf2a88117c90" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-token" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "solana-program", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.3.0", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-2022" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d697fac19fd74ff472dfcc13f0b442dd71403178ce1de7b5d16f83a33561c059" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.2", + "solana-program", + "solana-security-txt", + "solana-zk-token-sdk", + "spl-memo", + "spl-pod", + "spl-token", + "spl-token-group-interface", + "spl-token-metadata-interface", + "spl-transfer-hook-interface 0.4.1", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-group-interface" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b889509d49fa74a4a033ca5dae6c2307e9e918122d97e58562f5c4ffa795c75d" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.4.0", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aabdb7c471566f6ddcee724beb8618449ea24b399e58d464d6b5bc7db550259" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution 0.5.2", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9ebd75d29c5f48de5f6a9c114e08531030b75b8ac2c557600ac7da0b73b1e8" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", ] [[package]] name = "ss58-registry" -version = "1.38.0" +version = "1.47.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40c020d72bc0a9c5660bb71e4a6fdef081493583062c474740a7d59f55f0e7b" +checksum = "4743ce898933fbff7bbf414f497c459a782d496269644b3d650a398ae6a487ba" dependencies = [ "Inflector", "num-format", @@ -14395,18 +17332,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "static_init" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11b73400442027c4adedda20a9f9b7945234a5bd8d5f7e86da22bd5d0622369c" -dependencies = [ - "cfg_aliases", - "libc", - "parking_lot 0.11.2", - "static_init_macro 0.5.0", -] - [[package]] name = "static_init" version = "1.0.3" @@ -14418,15 +17343,15 @@ dependencies = [ "libc", "parking_lot 0.11.2", "parking_lot_core 0.8.6", - "static_init_macro 1.0.2", + "static_init_macro", "winapi", ] [[package]] name = "static_init_macro" -version = "0.5.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2261c91034a1edc3fc4d1b80e89d82714faede0515c14a75da10cb941546bbf" +checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf" dependencies = [ "cfg_aliases", "memchr", @@ -14436,17 +17361,14 @@ dependencies = [ ] [[package]] -name = "static_init_macro" -version = "1.0.2" +name = "stdx" +version = "0.0.0" + +[[package]] +name = "strsim" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a2595fc3aa78f2d0e45dd425b22282dd863273761cc77780914b2cf3003acf" -dependencies = [ - "cfg_aliases", - "memchr", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "strsim" @@ -14454,13 +17376,28 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" dependencies = [ - "strum_macros", + "strum_macros 0.24.3", +] + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", ] [[package]] @@ -14469,7 +17406,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -14477,29 +17414,23 @@ dependencies = [ ] [[package]] -name = "stun" -version = "0.4.4" +name = "strum_macros" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7e94b1ec00bad60e6410e058b52f1c66de3dc5fe4d62d09b3e52bb7d3b73e25" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ - "base64 0.13.1", - "crc", - "lazy_static", - "md-5", - "rand 0.8.5", - "ring", - "subtle", - "thiserror", - "tokio", - "url", - "webrtc-util", + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.61", ] [[package]] name = "subrpcer" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92660ce1320c3b4351b025ffc2932c3d410c71625be049922acefe1cae81c2e9" +checksum = "710aa039d14d63e3fda2cc12f3549df75e1a4ea826b109eddd9ffafe2746defa" dependencies = [ "affix", "serde", @@ -14508,13 +17439,13 @@ dependencies = [ [[package]] name = "substrate-bip39" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49eee6965196b32f882dd2ee85a92b1dbead41b04e53907f269de3b0dc04733c" +checksum = "6a7590dc041b9bc2825e52ce5af8416c73dbe9d0654402bfd4b4941938b94d8f" dependencies = [ "hmac 0.11.0", "pbkdf2 0.8.0", - "schnorrkel", + "schnorrkel 0.11.4", "sha2 0.9.9", "zeroize", ] @@ -14616,22 +17547,13 @@ dependencies = [ "cargo_metadata", "filetime", "sp-maybe-compressed-blob", - "strum", + "strum 0.24.1", "tempfile", - "toml 0.7.6", + "toml 0.7.8", "walkdir", "wasm-opt", ] -[[package]] -name = "substring" -version = "1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" -dependencies = [ - "autocfg", -] - [[package]] name = "subtle" version = "2.4.1" @@ -14664,7 +17586,7 @@ dependencies = [ "either", "frame-metadata 15.1.0", "futures", - "getrandom 0.2.8", + "getrandom 0.2.15", "hex", "impl-serde 0.4.0", "jsonrpsee", @@ -14692,7 +17614,7 @@ version = "0.29.0" source = "git+https://github.com/paritytech/subxt?tag=v0.29.0#e40a8629e279e80a7fbb56ff553a430a36612956" dependencies = [ "frame-metadata 15.1.0", - "heck", + "heck 0.4.1", "hex", "jsonrpsee", "parity-scale-codec", @@ -14700,7 +17622,7 @@ dependencies = [ "quote", "scale-info", "subxt-metadata", - "syn 2.0.32", + "syn 2.0.61", "thiserror", "tokio", ] @@ -14718,10 +17640,10 @@ name = "subxt-macro" version = "0.29.0" source = "git+https://github.com/paritytech/subxt?tag=v0.29.0#e40a8629e279e80a7fbb56ff553a430a36612956" dependencies = [ - "darling 0.20.3", + "darling 0.20.8", "proc-macro-error", "subxt-codegen", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -14749,9 +17671,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2", "quote", @@ -14778,9 +17700,9 @@ dependencies = [ [[package]] name = "system-configuration" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75182f12f490e953596550b65ee31bda7c8e043d9386174b353bda50838c3fd" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -14805,9 +17727,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" [[package]] name = "tempdir" @@ -14821,57 +17743,55 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.3.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if 1.0.0", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "rustix 0.38.34", + "windows-sys 0.52.0", ] [[package]] name = "tendermint" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" dependencies = [ "bytes", - "digest 0.10.6", - "ed25519 1.5.3", + "digest 0.10.7", + "ed25519 2.2.3", "ed25519-consensus", "flex-error", "futures", - "k256 0.11.6", + "k256 0.13.3", "num-traits", "once_cell", - "prost 0.11.6", - "prost-types 0.11.6", + "prost 0.11.9", + "prost-types 0.11.9", "ripemd", "serde", "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.6", - "signature 1.6.4", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "subtle-encoding", - "tendermint-proto 0.28.0", - "time 0.3.17", + "tendermint-proto 0.33.2", + "time", "zeroize", ] [[package]] name = "tendermint" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789" +version = "0.34.1" +source = "git+https://github.com/mina86/tendermint-rs?rev=45fbd500d731effb95a98257630feb46f6c41d06#45fbd500d731effb95a98257630feb46f6c41d06" dependencies = [ "bytes", - "digest 0.10.6", - "ed25519 2.2.2", + "digest 0.10.7", + "ed25519 2.2.3", + "ed25519-consensus", "flex-error", "futures", "num-traits", @@ -14882,132 +17802,147 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "signature 2.1.0", + "sha2 0.10.8", + "signature 2.2.0", "subtle", "subtle-encoding", - "tendermint-proto 0.34.0", - "time 0.3.17", + "tendermint-proto 0.34.1", + "time", "zeroize", ] [[package]] name = "tendermint-config" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" dependencies = [ "flex-error", "serde", "serde_json", - "tendermint 0.28.0", + "tendermint 0.33.2", "toml 0.5.11", "url", ] [[package]] name = "tendermint-light-client" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" dependencies = [ "contracts", "crossbeam-channel 0.4.4", "derive_more", "flex-error", "futures", + "regex", "serde", "serde_cbor", "serde_derive", + "serde_json", "static_assertions", - "tendermint 0.28.0", - "tendermint-light-client-verifier", + "tendermint 0.33.2", + "tendermint-light-client-verifier 0.33.2", "tendermint-rpc", - "time 0.3.17", + "time", "tokio", + "tracing", ] [[package]] name = "tendermint-light-client-verifier" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" +dependencies = [ + "derive_more", + "flex-error", + "serde", + "tendermint 0.33.2", + "time", +] + +[[package]] +name = "tendermint-light-client-verifier" +version = "0.34.1" +source = "git+https://github.com/mina86/tendermint-rs?rev=45fbd500d731effb95a98257630feb46f6c41d06#45fbd500d731effb95a98257630feb46f6c41d06" dependencies = [ "derive_more", "flex-error", "serde", - "tendermint 0.28.0", - "time 0.3.17", + "tendermint 0.34.1", + "time", ] [[package]] name = "tendermint-proto" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" dependencies = [ "bytes", "flex-error", - "num-derive", + "num-derive 0.3.3", "num-traits", - "prost 0.11.6", - "prost-types 0.11.6", + "prost 0.11.9", + "prost-types 0.11.9", "serde", "serde_bytes", "subtle-encoding", - "time 0.3.17", + "time", ] [[package]] name = "tendermint-proto" -version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf" +version = "0.34.1" +source = "git+https://github.com/mina86/tendermint-rs?rev=45fbd500d731effb95a98257630feb46f6c41d06#45fbd500d731effb95a98257630feb46f6c41d06" dependencies = [ "bytes", "flex-error", - "num-derive", - "num-traits", "prost 0.12.3", "prost-types 0.12.3", "serde", "serde_bytes", "subtle-encoding", - "time 0.3.17", + "time", ] [[package]] name = "tendermint-rpc" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" dependencies = [ "async-trait", "async-tungstenite", "bytes", "flex-error", "futures", - "getrandom 0.2.8", + "getrandom 0.2.15", "http", "hyper", "hyper-proxy", "hyper-rustls 0.22.1", "peg", "pin-project", + "semver 1.0.23", "serde", "serde_bytes", "serde_json", "subtle", "subtle-encoding", - "tendermint 0.28.0", + "tendermint 0.33.2", "tendermint-config", + "tendermint-proto 0.33.2", "thiserror", - "time 0.3.17", + "time", "tokio", "tracing", "url", - "uuid 0.8.2", + "uuid", "walkdir", ] [[package]] name = "tendermint-testgen" -version = "0.28.0" -source = "git+https://github.com/informalsystems/tendermint-rs?rev=e81f7bf23d63ffbcd242381d1ce5e35da3515ff1#e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +version = "0.33.2" +source = "git+https://github.com/informalsystems/tendermint-rs?rev=4d81b67c28510db7d2d99ed62ebfa9fdf0e02141#4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" dependencies = [ "ed25519-consensus", "gumdrop", @@ -15015,30 +17950,30 @@ dependencies = [ "serde_json", "simple-error", "tempfile", - "tendermint 0.28.0", - "time 0.3.17", + "tendermint 0.33.2", + "time", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "termtree" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "test-log" -version = "0.2.11" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f0c854faeb68a048f0f2dc410c5ddae3bf83854ef0e4977d58306a5edef50e" +checksum = "4235dbf7ea878b3ef12dea20a59c134b405a66aafc4fc2c7b9935916e289e735" dependencies = [ "proc-macro2", "quote", @@ -15047,28 +17982,37 @@ dependencies = [ [[package]] name = "textwrap" -version = "0.16.0" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "textwrap" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -15079,10 +18023,11 @@ checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820" [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ + "cfg-if 1.0.0", "once_cell", ] @@ -15110,9 +18055,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-ctl" -version = "0.5.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37706572f4b151dff7a0146e040804e9c26fe3a3118591112f05cf12a4216c1" +checksum = "619bfed27d807b54f7f776b9430d4f8060e66ee138a28632ca898584d462c31c" dependencies = [ "libc", "paste", @@ -15121,9 +18066,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.5.3+5.3.0-patched" +version = "0.5.4+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a678df20055b43e57ef8cddde41cdfda9a3c1a060b67f4c5836dfb1d78543ba8" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" dependencies = [ "cc", "libc", @@ -15131,22 +18076,14 @@ dependencies = [ [[package]] name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.17" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ + "deranged", "itoa", + "num-conv", + "powerfmt", "serde", "time-core", "time-macros", @@ -15154,32 +18091,33 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.6" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] [[package]] name = "tiny-bip39" -version = "1.0.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" +checksum = "ffc59cb9dfc85bb312c3a78fd6aa8a8582e310b0fa885d5bb877f6dcc601839d" dependencies = [ "anyhow", - "hmac 0.12.1", + "hmac 0.8.1", "once_cell", - "pbkdf2 0.11.0", - "rand 0.8.5", + "pbkdf2 0.4.0", + "rand 0.7.3", "rustc-hash", - "sha2 0.10.6", + "sha2 0.9.9", "thiserror", "unicode-normalization", "wasm-bindgen", @@ -15187,13 +18125,22 @@ dependencies = [ ] [[package]] -name = "tinytemplate" -version = "1.2.1" +name = "tiny-bip39" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" dependencies = [ - "serde", - "serde_json", + "anyhow", + "hmac 0.12.1", + "once_cell", + "pbkdf2 0.11.0", + "rand 0.8.5", + "rustc-hash", + "sha2 0.10.8", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", ] [[package]] @@ -15213,19 +18160,19 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[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", "libc", "mio", "num_cpus", - "parking_lot 0.12.1", - "pin-project-lite 0.2.13", + "parking_lot 0.12.2", + "pin-project-lite 0.2.14", "signal-hook-registry", - "socket2 0.5.4", + "socket2 0.5.7", "tokio-macros", "windows-sys 0.48.0", ] @@ -15236,19 +18183,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" dependencies = [ - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tokio", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", ] [[package]] @@ -15279,9 +18236,9 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.8", + "rustls 0.20.9", "tokio", - "webpki 0.22.0", + "webpki 0.22.4", ] [[package]] @@ -15290,35 +18247,49 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.12", "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 0.2.13", + "pin-project-lite 0.2.14", "tokio", "tokio-util", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", + "tungstenite 0.20.1", + "webpki-roots 0.25.4", +] + [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-io", "futures-sink", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tokio", - "tracing", ] [[package]] @@ -15332,38 +18303,49 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.6" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.15", ] [[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.14" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", "winnow", ] +[[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", +] + [[package]] name = "tonic" version = "0.8.3" @@ -15384,9 +18366,9 @@ dependencies = [ "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.11.6", - "prost-derive 0.11.6", - "rustls-native-certs 0.6.2", + "prost 0.11.9", + "prost-derive 0.11.9", + "rustls-native-certs 0.6.3", "rustls-pemfile", "tokio", "tokio-rustls 0.23.4", @@ -15399,19 +18381,64 @@ dependencies = [ "tracing-futures", ] +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.12.3", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", + "rustls-pemfile", + "tokio", + "tokio-rustls 0.24.1", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", + "webpki-roots 0.25.4", +] + [[package]] name = "tonic-build" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" dependencies = [ - "prettyplease 0.1.23", + "prettyplease 0.1.11", "proc-macro2", - "prost-build", + "prost-build 0.11.9", "quote", "syn 1.0.109", ] +[[package]] +name = "tonic-build" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" +dependencies = [ + "prettyplease 0.2.20", + "proc-macro2", + "prost-build 0.12.3", + "quote", + "syn 2.0.61", +] + [[package]] name = "tower" version = "0.4.13" @@ -15420,9 +18447,9 @@ checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" dependencies = [ "futures-core", "futures-util", - "indexmap 1.9.2", + "indexmap 1.9.3", "pin-project", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "rand 0.8.5", "slab", "tokio", @@ -15432,39 +18459,20 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" -dependencies = [ - "bitflags 1.3.2", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite 0.2.13", - "tower", - "tower-layer", - "tower-service", -] - [[package]] name = "tower-http" version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.5.0", "bytes", "futures-core", "futures-util", "http", "http-body", "http-range-header", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tower-layer", "tower-service", ] @@ -15483,33 +18491,32 @@ 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 1.0.0", "log", - "pin-project-lite 0.2.13", + "pin-project-lite 0.2.14", "tracing-attributes", "tracing-core", ] [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", "valuable", @@ -15541,21 +18548,32 @@ name = "tracing-gum-proc-macro" version = "0.9.43" source = "git+https://github.com/paritytech/polkadot?branch=release-v0.9.43#ba42b9ce51d25bdaf52d2c61e0763a6e3da50d25" dependencies = [ - "expander 2.0.0", + "expander 2.1.0", "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] @@ -15588,15 +18606,15 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-serde", ] [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers 0.1.0", "nu-ansi-term", @@ -15609,7 +18627,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", "tracing-serde", ] @@ -15626,6 +18644,22 @@ dependencies = [ "smallvec", ] +[[package]] +name = "trie-ids" +version = "0.0.0" +dependencies = [ + "ascii 1.1.0", + "base64 0.21.7", + "borsh 0.10.3", + "bytemuck", + "derive_more", + "ibc-core-channel-types", + "ibc-core-client-types", + "ibc-core-connection-types", + "ibc-core-host-types", + "strum 0.25.0", +] + [[package]] name = "trie-root" version = "0.18.0" @@ -15653,7 +18687,7 @@ dependencies = [ "lazy_static", "rand 0.8.5", "smallvec", - "socket2 0.4.9", + "socket2 0.4.10", "thiserror", "tinyvec", "tokio", @@ -15672,7 +18706,7 @@ dependencies = [ "ipconfig", "lazy_static", "lru-cache", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "resolv-conf", "smallvec", "thiserror", @@ -15683,9 +18717,9 @@ dependencies = [ [[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 = "try-runtime-cli" @@ -15693,7 +18727,7 @@ version = "0.10.0-dev" source = "git+https://github.com/paritytech//substrate.git?branch=polkadot-v0.9.43#5e49f6e44820affccaf517fd22af564f4b495d40" dependencies = [ "async-trait", - "clap 4.4.6", + "clap 4.5.4", "frame-remote-externalities", "hex", "log", @@ -15731,9 +18765,9 @@ checksum = "f4f195fd851901624eee5a58c4bb2b4f06399148fcd0ed336e6f1cb60a9881df" [[package]] name = "tungstenite" -version = "0.17.3" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" dependencies = [ "base64 0.13.1", "byteorder", @@ -15742,12 +18776,12 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.20.8", - "sha-1 0.10.1", + "rustls 0.20.9", + "sha1", "thiserror", "url", "utf-8", - "webpki 0.22.0", + "webpki 0.22.4", ] [[package]] @@ -15763,31 +18797,13 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.7", - "rustls-native-certs 0.6.2", + "rustls 0.21.12", + "rustls-native-certs 0.6.3", "sha1", "thiserror", "url", "utf-8", -] - -[[package]] -name = "turn" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4712ee30d123ec7ae26d1e1b218395a16c87cdbaf4b3925d170d684af62ea5e8" -dependencies = [ - "async-trait", - "base64 0.13.1", - "futures", - "log", - "md-5", - "rand 0.8.5", - "ring", - "stun", - "thiserror", - "tokio", - "webrtc-util", + "webpki-roots 0.24.0", ] [[package]] @@ -15797,22 +18813,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if 1.0.0", - "digest 0.10.6", + "digest 0.10.7", "rand 0.8.5", "static_assertions", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "ucd-trie" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "uint" @@ -15834,36 +18850,36 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-bidi" -version = "0.3.10" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +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" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" [[package]] name = "unicode-xid" @@ -15877,25 +18893,34 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] [[package]] name = "universal-hash" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d3160b73c9a19f7e2939a2fdad446c57c1bbbbf4d919d3213ff1267a580d8b5" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common", "subtle", ] +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "unsigned-varint" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86a8dc7f45e4c1b0d30e43038c38f274e77af056aa5f74b93c2cf9eb3c1c836" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" dependencies = [ "asynchronous-codec", "bytes", @@ -15909,32 +18934,48 @@ 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 = "ureq" -version = "2.6.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "338b31dd1314f68f3aabf3ed57ab922df95ffcd902476ca7ba3c4ce7b908c46d" +checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", "flate2", "log", "once_cell", - "rustls 0.20.8", + "rustls 0.21.12", + "rustls-webpki", "serde", "serde_json", "url", - "webpki 0.22.0", - "webpki-roots 0.22.6", + "webpki-roots 0.25.4", +] + +[[package]] +name = "uriparse" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0200d0fc04d809396c2ad43f3c95da3582a2556eba8d453c1087f4120ee352ff" +dependencies = [ + "fnv", + "lazy_static", ] [[package]] name = "url" -version = "2.3.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.3.0", + "idna 0.5.0", "percent-encoding", ] @@ -15956,15 +18997,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -[[package]] -name = "uuid" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" -dependencies = [ - "getrandom 0.2.8", -] - [[package]] name = "valuable" version = "0.1.0" @@ -15977,6 +19009,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.4" @@ -15998,39 +19036,22 @@ dependencies = [ "libc", ] -[[package]] -name = "waitgroup" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1f50000a783467e6c0200f9d10642f4bc424e39efc1b770203e88b488f79292" -dependencies = [ - "atomic-waker", -] - -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - [[package]] name = "walkdir" -version = "2.3.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", - "winapi", "winapi-util", ] [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -16040,23 +19061,41 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasix" +version = "0.12.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" +dependencies = [ + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "wasm" +version = "0.0.0" +dependencies = [ + "const_format", + "derive_more", + "ibc-core-client-context", + "ibc-core-commitment-types", + "ibc-primitives 0.50.0", + "ibc-proto 0.41.0", + "lib", + "prost 0.12.3", + "proto-utils", +] + [[package]] name = "wasm-bindgen" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -16064,24 +19103,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.34" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -16091,9 +19130,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -16101,22 +19140,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.61", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.84" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "wasm-instrument" @@ -16132,7 +19171,7 @@ name = "wasm-loader" version = "0.20.0" source = "git+https://github.com/chevdor/subwasm?rev=1c8446be5cff9e04cbb7b41acc136f22eddd5eac#1c8446be5cff9e04cbb7b41acc136f22eddd5eac" dependencies = [ - "array-bytes 6.1.0", + "array-bytes 6.2.2", "log", "multibase", "multihash 0.19.1", @@ -16154,8 +19193,8 @@ checksum = "87fef6d0d508f08334e0ab0e6877feb4c0ecb3956bcf2cb950699b22fedf3e9c" dependencies = [ "anyhow", "libc", - "strum", - "strum_macros", + "strum 0.24.1", + "strum_macros 0.24.3", "tempfile", "thiserror", "wasm-opt-cxx-sys", @@ -16253,7 +19292,7 @@ dependencies = [ "downcast-rs", "libm", "memory_units", - "num-rational", + "num-rational 0.4.2", "num-traits", ] @@ -16263,7 +19302,7 @@ version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48134de3d7598219ab9eaf6b91b15d8e50d31da76b8519fe4ecfcec2cf35104b" dependencies = [ - "indexmap 1.9.2", + "indexmap 1.9.3", "url", ] @@ -16276,10 +19315,10 @@ dependencies = [ "anyhow", "bincode", "cfg-if 1.0.0", - "indexmap 1.9.2", + "indexmap 1.9.3", "libc", "log", - "object", + "object 0.30.4", "once_cell", "paste", "psm", @@ -16311,14 +19350,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c86437fa68626fe896e5afc69234bb2b5894949083586535f200385adfd71213" dependencies = [ "anyhow", - "base64 0.21.0", + "base64 0.21.7", "bincode", "directories-next", "file-per-thread-logger", "log", - "rustix 0.36.8", + "rustix 0.36.17", "serde", - "sha2 0.10.6", + "sha2 0.10.8", "toml 0.5.11", "windows-sys 0.45.0", "zstd 0.11.2+zstd.1.5.2", @@ -16336,9 +19375,9 @@ dependencies = [ "cranelift-frontend", "cranelift-native", "cranelift-wasm", - "gimli", + "gimli 0.27.3", "log", - "object", + "object 0.30.4", "target-lexicon", "thiserror", "wasmparser", @@ -16355,8 +19394,8 @@ dependencies = [ "anyhow", "cranelift-codegen", "cranelift-native", - "gimli", - "object", + "gimli 0.27.3", + "object 0.30.4", "target-lexicon", "wasmtime-environ", ] @@ -16369,10 +19408,10 @@ checksum = "a990198cee4197423045235bf89d3359e69bd2ea031005f4c2d901125955c949" dependencies = [ "anyhow", "cranelift-entity", - "gimli", - "indexmap 1.9.2", + "gimli 0.27.3", + "indexmap 1.9.3", "log", - "object", + "object 0.30.4", "serde", "target-lexicon", "thiserror", @@ -16386,14 +19425,14 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de48df552cfca1c9b750002d3e07b45772dd033b0b206d5c0968496abf31244" dependencies = [ - "addr2line", + "addr2line 0.19.0", "anyhow", "bincode", "cfg-if 1.0.0", "cpp_demangle", - "gimli", + "gimli 0.27.3", "log", - "object", + "object 0.30.4", "rustc-demangle", "serde", "target-lexicon", @@ -16410,9 +19449,9 @@ version = "8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e0554b84c15a27d76281d06838aed94e13a77d7bf604bbbaf548aa20eb93846" dependencies = [ - "object", + "object 0.30.4", "once_cell", - "rustix 0.36.8", + "rustix 0.36.17", ] [[package]] @@ -16435,7 +19474,7 @@ dependencies = [ "anyhow", "cc", "cfg-if 1.0.0", - "indexmap 1.9.2", + "indexmap 1.9.3", "libc", "log", "mach", @@ -16443,7 +19482,7 @@ dependencies = [ "memoffset 0.8.0", "paste", "rand 0.8.5", - "rustix 0.36.8", + "rustix 0.36.17", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", @@ -16464,9 +19503,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.61" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" dependencies = [ "js-sys", "wasm-bindgen", @@ -16478,18 +19517,18 @@ 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]] name = "webpki" -version = "0.22.0" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -16507,244 +19546,23 @@ version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" dependencies = [ - "webpki 0.22.0", + "webpki 0.22.4", ] [[package]] name = "webpki-roots" -version = "0.23.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +checksum = "b291546d5d9d1eab74f069c77749f2cb8504a12caa20f0f2de93ddbf6f411888" dependencies = [ - "rustls-webpki 0.100.3", + "rustls-webpki", ] [[package]] name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - -[[package]] -name = "webrtc" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3bc9049bdb2cea52f5fd4f6f728184225bdb867ed0dc2410eab6df5bdd67bb" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "hex", - "interceptor", - "lazy_static", - "log", - "rand 0.8.5", - "rcgen 0.9.3", - "regex", - "ring", - "rtcp", - "rtp", - "rustls 0.19.1", - "sdp", - "serde", - "serde_json", - "sha2 0.10.6", - "stun", - "thiserror", - "time 0.3.17", - "tokio", - "turn", - "url", - "waitgroup", - "webrtc-data", - "webrtc-dtls", - "webrtc-ice", - "webrtc-mdns", - "webrtc-media", - "webrtc-sctp", - "webrtc-srtp", - "webrtc-util", -] - -[[package]] -name = "webrtc-data" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef36a4d12baa6e842582fe9ec16a57184ba35e1a09308307b67d43ec8883100" -dependencies = [ - "bytes", - "derive_builder", - "log", - "thiserror", - "tokio", - "webrtc-sctp", - "webrtc-util", -] - -[[package]] -name = "webrtc-dtls" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942be5bd85f072c3128396f6e5a9bfb93ca8c1939ded735d177b7bcba9a13d05" -dependencies = [ - "aes 0.6.0", - "aes-gcm 0.10.1", - "async-trait", - "bincode", - "block-modes", - "byteorder", - "ccm", - "curve25519-dalek 3.2.0", - "der-parser 8.2.0", - "elliptic-curve 0.12.3", - "hkdf", - "hmac 0.12.1", - "log", - "oid-registry 0.6.1", - "p256", - "p384", - "rand 0.8.5", - "rand_core 0.6.4", - "rcgen 0.9.3", - "ring", - "rustls 0.19.1", - "sec1 0.3.0", - "serde", - "sha1", - "sha2 0.10.6", - "signature 1.6.4", - "subtle", - "thiserror", - "tokio", - "webpki 0.21.4", - "webrtc-util", - "x25519-dalek 2.0.0-pre.1", - "x509-parser 0.13.2", -] - -[[package]] -name = "webrtc-ice" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a03cc11e9a7d7b4f9f99870558fe37a102b65b93f8045392fef7c67b39e80" -dependencies = [ - "arc-swap", - "async-trait", - "crc", - "log", - "rand 0.8.5", - "serde", - "serde_json", - "stun", - "thiserror", - "tokio", - "turn", - "url", - "uuid 1.3.0", - "waitgroup", - "webrtc-mdns", - "webrtc-util", -] - -[[package]] -name = "webrtc-mdns" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f08dfd7a6e3987e255c4dbe710dde5d94d0f0574f8a21afa95d171376c143106" -dependencies = [ - "log", - "socket2 0.4.9", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-media" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a3c157a040324e5049bcbd644ffc9079e6738fa2cfab2bcff64e5cc4c00d7" -dependencies = [ - "byteorder", - "bytes", - "derive_builder", - "displaydoc", - "rand 0.8.5", - "rtp", - "thiserror", - "webrtc-util", -] - -[[package]] -name = "webrtc-sctp" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d47adcd9427eb3ede33d5a7f3424038f63c965491beafcc20bc650a2f6679c0" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "crc", - "log", - "rand 0.8.5", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-srtp" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6183edc4c1c6c0175f8812eefdce84dfa0aea9c3ece71c2bf6ddd3c964de3da5" -dependencies = [ - "aead 0.4.3", - "aes 0.7.5", - "aes-gcm 0.9.4", - "async-trait", - "byteorder", - "bytes", - "ctr 0.8.0", - "hmac 0.11.0", - "log", - "rtcp", - "rtp", - "sha-1 0.9.8", - "subtle", - "thiserror", - "tokio", - "webrtc-util", -] - -[[package]] -name = "webrtc-util" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f1db1727772c05cf7a2cfece52c3aca8045ca1e176cd517d323489aa3c6d87" -dependencies = [ - "async-trait", - "bitflags 1.3.2", - "bytes", - "cc", - "ipnet", - "lazy_static", - "libc", - "log", - "nix", - "rand 0.8.5", - "thiserror", - "tokio", - "winapi", -] - -[[package]] -name = "wepoll-ffi" -version = "0.1.2" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "westend-runtime" @@ -16855,20 +19673,21 @@ dependencies = [ [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix 0.38.34", ] [[package]] name = "wide" -version = "0.7.8" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b689b6c49d6549434bf944e6b0f39238cf63693cb7a147e9d887507fffa3b223" +checksum = "0f0e39d2c603fdc0504b12b458cf1f34e0b937ed2f4f2dc20796e3e86f34e11f" dependencies = [ "bytemuck", "safe_arch", @@ -16876,9 +19695,9 @@ dependencies = [ [[package]] name = "widestring" -version = "0.5.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -16898,11 +19717,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -16913,30 +19732,21 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.34.0" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45296b64204227616fdbf2614cefa4c236b98ee64dfaaaa435207ed99fe7829f" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows_aarch64_msvc 0.34.0", - "windows_i686_gnu 0.34.0", - "windows_i686_msvc 0.34.0", - "windows_x86_64_gnu 0.34.0", - "windows_x86_64_msvc 0.34.0", + "windows-core", + "windows-targets 0.48.5", ] [[package]] -name = "windows-sys" -version = "0.42.0" +name = "windows-core" +version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", + "windows-targets 0.48.5", ] [[package]] @@ -16945,7 +19755,7 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets 0.42.1", + "windows-targets 0.42.2", ] [[package]] @@ -16957,19 +19767,28 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -16987,11 +19806,27 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +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" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" [[package]] name = "windows_aarch64_gnullvm" @@ -17000,16 +19835,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "windows_aarch64_msvc" -version = "0.34.0" +name = "windows_aarch64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" @@ -17018,16 +19853,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "windows_i686_gnu" -version = "0.34.0" +name = "windows_aarch64_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" @@ -17036,16 +19871,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "windows_i686_msvc" -version = "0.34.0" +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" @@ -17054,16 +19895,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "windows_x86_64_gnu" -version = "0.34.0" +name = "windows_i686_msvc" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" @@ -17071,11 +19912,17 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" [[package]] name = "windows_x86_64_gnullvm" @@ -17084,16 +19931,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "windows_x86_64_msvc" -version = "0.34.0" +name = "windows_x86_64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" @@ -17101,22 +19948,29 @@ 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.3" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46aab759304e4d7b2075a9aecba26228bb073ee8c50db796b2c72c676b5d807" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if 1.0.0", + "windows-sys 0.48.0", ] [[package]] @@ -17134,57 +19988,27 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" dependencies = [ - "curve25519-dalek 3.2.0", + "curve25519-dalek 3.2.1", "rand_core 0.5.1", "zeroize", ] -[[package]] -name = "x25519-dalek" -version = "2.0.0-pre.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5da623d8af10a62342bcbbb230e33e58a63255a58012f8653c578e54bab48df" -dependencies = [ - "curve25519-dalek 3.2.0", - "rand_core 0.6.4", - "zeroize", -] - -[[package]] -name = "x509-parser" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9bace5b5589ffead1afb76e43e34cff39cd0f3ce7e170ae0c29e53b88eb1c" -dependencies = [ - "asn1-rs 0.3.1", - "base64 0.13.1", - "data-encoding", - "der-parser 7.0.0", - "lazy_static", - "nom", - "oid-registry 0.4.0", - "ring", - "rusticata-macros", - "thiserror", - "time 0.3.17", -] - [[package]] name = "x509-parser" version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e0ecbeb7b67ce215e40e3cc7f2ff902f94a223acf44995934763467e7b1febc8" dependencies = [ - "asn1-rs 0.5.2", + "asn1-rs", "base64 0.13.1", "data-encoding", - "der-parser 8.2.0", + "der-parser", "lazy_static", "nom", - "oid-registry 0.6.1", + "oid-registry", "rusticata-macros", "thiserror", - "time 0.3.17", + "time", ] [[package]] @@ -17253,7 +20077,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.61", ] [[package]] @@ -17265,7 +20089,7 @@ dependencies = [ "futures", "log", "nohash-hasher", - "parking_lot 0.12.1", + "parking_lot 0.12.2", "rand 0.8.5", "static_assertions", ] @@ -17282,28 +20106,47 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.17", + "time", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.61", ] [[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", ] [[package]] name = "zeroize_derive" -version = "1.3.3" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", - "synstructure", + "syn 2.0.61", ] [[package]] @@ -17346,11 +20189,25 @@ 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", ] + +[[patch.unused]] +name = "ibc-testkit" +version = "0.50.0" +source = "git+https://github.com/mina86/ibc-rs?rev=f07276383091f75b7ee8bff6fd434f8214ac5054#f07276383091f75b7ee8bff6fd434f8214ac5054" + +[[patch.unused]] +name = "tendermint-light-client" +version = "0.34.1" +source = "git+https://github.com/mina86/tendermint-rs?rev=45fbd500d731effb95a98257630feb46f6c41d06#45fbd500d731effb95a98257630feb46f6c41d06" + +[[patch.unused]] +name = "tendermint-testgen" +version = "0.34.1" +source = "git+https://github.com/mina86/tendermint-rs?rev=45fbd500d731effb95a98257630feb46f6c41d06#45fbd500d731effb95a98257630feb46f6c41d06" diff --git a/Cargo.toml b/Cargo.toml index e11faa40c..bf29a0006 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ members = [ "ibc/modules", "ibc/proto", "ibc/proto-compiler", - # ibc contracts for different blockchain runtimes "contracts/pallet-ibc/ping", "contracts/pallet-ibc/primitives", @@ -14,7 +13,6 @@ members = [ "contracts/pallet-ibc/runtime-api", "contracts/pallet-ibc", "contracts/pallet-ibc/simple-iavl", - # algorithms "algorithms/beefy/verifier", "algorithms/beefy/prover", @@ -22,37 +20,100 @@ members = [ "algorithms/grandpa/verifier", "algorithms/grandpa/prover", "algorithms/grandpa/primitives", - # ibc light clients "light-clients/common", + "light-clients/cf-guest", + "light-clients/cf-guest-cw", + # "light-clients/icsxx-cf-solana", "light-clients/ics07-tendermint", "light-clients/ics07-tendermint-cw", + "light-clients/cf-guest", + "light-clients/cf-guest-cw", "light-clients/ics08-wasm", "light-clients/ics10-grandpa", "light-clients/ics10-grandpa-cw", "light-clients/ics11-beefy", "light-clients/ics13-near", - # hyperspace "hyperspace", "hyperspace/core", "hyperspace/primitives", "hyperspace/parachain", "hyperspace/cosmos", + "hyperspace/solana", "hyperspace/testsuite", "hyperspace/metrics", - # utilities "utils/subxt/codegen", "utils/subxt/generated", "utils/parachain-node", "utils/parachain-node/runtime", -# "utils/simnode" + # "utils/simnode" ] [patch."https://github.com/paritytech/jsonrpsee"] jsonrpsee = { version = "0.16.3" } +[patch.crates-io] +aes-gcm-siv = { git = "https://github.com/RustCrypto/AEADs", rev = "6105d7a5591aefa646a95d12b5e8d3f55a9214ef" } +curve25519-dalek-new = { git = "https://github.com/dalek-cryptography/curve25519-dalek", rev = "0cd099a9fb8ff9f6fedc8723d44dbb1c743e9d35", package = "curve25519-dalek" } +curve25519-dalek = { git = "https://github.com/solana-labs/curve25519-dalek.git", rev = "b500cdc2a920cd5bff9e2dd974d7b97349d61464" } +anchor-client = { git = "https://github.com/dhruvja/anchor" } +anchor-lang = { git = "https://github.com/dhruvja/anchor" } + +ibc = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false, features = ["borsh", "serde"] } +ibc-client-tendermint-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-channel-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-client-context = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-client-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-commitment-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-connection-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-host = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-host-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-primitives = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-testkit = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +# ibc-testkit = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054" } +#ibc = { path = "../ibc-rs-mina/ibc" } +#ibc-app-nft-transfer = { path = "../ibc-rs-mina/ibc-apps/ics721-nft-transfer" } +#ibc-app-nft-transfer-types = { path = "../ibc-rs-mina/ibc-apps/ics721-nft-transfer/types" } +#ibc-app-transfer = { path = "../ibc-rs-mina/ibc-apps/ics20-transfer" } +#ibc-app-transfer-types = { path = "../ibc-rs-mina/ibc-apps/ics20-transfer/types" } +#ibc-apps = { path = "../ibc-rs-mina/ibc-apps" } +#ibc-client-tendermint = { path = "../ibc-rs-mina/ibc-clients/ics07-tendermint" } +#ibc-client-tendermint-types = { path = "../ibc-rs-mina/ibc-clients/ics07-tendermint/types" } +#ibc-client-wasm-types = { path = "../ibc-rs-mina/ibc-clients/ics08-wasm/types" } +#ibc-clients = { path = "../ibc-rs-mina/ibc-clients" } +#ibc-core = { path = "../ibc-rs-mina/ibc-core" } +#ibc-core-channel = { path = "../ibc-rs-mina/ibc-core/ics04-channel" } +#ibc-core-channel-types = { path = "../ibc-rs-mina/ibc-core/ics04-channel/types" } +#ibc-core-client = { path = "../ibc-rs-mina/ibc-core/ics02-client" } +#ibc-core-client-context = { path = "../ibc-rs-mina/ibc-core/ics02-client/context" } +#ibc-core-client-types = { path = "../ibc-rs-mina/ibc-core/ics02-client/types" } +#ibc-core-commitment-types = { path = "../ibc-rs-mina/ibc-core/ics23-commitment/types" } +#ibc-core-connection = { path = "../ibc-rs-mina/ibc-core/ics03-connection" } +#ibc-core-connection-types = { path = "../ibc-rs-mina/ibc-core/ics03-connection/types" } +#ibc-core-handler = { path = "../ibc-rs-mina/ibc-core/ics25-handler" } +#ibc-core-handler-types = { path = "../ibc-rs-mina/ibc-core/ics25-handler/types" } +#ibc-core-host = { path = "../ibc-rs-mina/ibc-core/ics24-host" } +#ibc-core-host-cosmos = { path = "../ibc-rs-mina/ibc-core/ics24-host/cosmos" } +#ibc-core-host-types = { path = "../ibc-rs-mina/ibc-core/ics24-host/types" } +#ibc-core-router = { path = "../ibc-rs-mina/ibc-core/ics26-routing" } +#ibc-core-router-types = { path = "../ibc-rs-mina/ibc-core/ics26-routing/types" } +#ibc-data-types = { path = "../ibc-rs-mina" } +#ibc-derive = { path = "../ibc-rs-mina/ibc-derive" } +#ibc-primitives = { path = "../ibc-rs-mina/ibc-primitives" } +#ibc-query = { path = "../ibc-rs-mina" } +#ibc-testkit = { path = "../ibc-rs-mina/ibc-testkit" } + +tendermint = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06" } +tendermint-light-client = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06" } +tendermint-light-client-verifier = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06" } +tendermint-proto = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06" } +tendermint-testgen = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06" } + +# cfg-expr = { git = "https://github.com/EmbarkStudios/cfg-expr", tag="0.15.0" } + + [patch."https://github.com/paritytech/substrate"] sc-executor = { git = "https://github.com/paritytech//substrate.git", branch = "polkadot-v0.9.43" } sc-executor-common = { git = "https://github.com/paritytech//substrate.git", branch = "polkadot-v0.9.43" } @@ -228,4 +289,4 @@ substrate-state-trie-migration-rpc = { git = "https://github.com/paritytech//sub substrate-wasm-builder = { git = "https://github.com/paritytech//substrate.git", branch = "polkadot-v0.9.43" } [profile.release] -overflow-checks = true \ No newline at end of file +overflow-checks = true diff --git a/config/cosmos-banksy.toml b/config/cosmos-banksy.toml new file mode 100644 index 000000000..843aa2b61 --- /dev/null +++ b/config/cosmos-banksy.toml @@ -0,0 +1,19 @@ +type = "cosmos" +name = "centauri" +rpc_url = "http://10.132.0.13:26657/" +grpc_url = "http://10.132.0.13:9999/" +websocket_url = "ws://10.132.0.13:26657/websocket" +chain_id = "banksy-testnet-5" +client_id = "07-tendermint-5" +connection_id = "connection-121" +account_prefix = "pica" +fee_denom = "ppica" +fee_amount = "10000000" +gas_limit = 100000000 +store_prefix = "ibc" +max_tx_size = 200000 +wasm_code_id = "66ce7420d21e2555b0e6ce952c0826590fb5f6508a9ac84a5c11178cec58a303" +channel_whitelist = [] +mnemonic = "peace cash suffer celery broken blade fame fiscal lesson fancy virus bless recipe inherit reason cart mask mask absurd venture culture problem reward crew" +skip_optional_client_updates = true +max_packets_to_process = 50 diff --git a/config/cosmos.toml b/config/cosmos.toml new file mode 100644 index 000000000..3b51fbf9b --- /dev/null +++ b/config/cosmos.toml @@ -0,0 +1,20 @@ +type = "cosmos" +name = "centauri" +rpc_url = "http://192.168.1.101:26657/" +grpc_url = "http://192.168.1.101:9090/" +websocket_url = "ws://192.168.1.101:26657/websocket" +chain_id = "test-1" +client_id = "07-tendermint-27" +connection_id = "connection-0" +account_prefix = "centauri" +fee_denom = "stake" +fee_amount = "10000000" +gas_limit = 100000000 +store_prefix = "ibc" +max_tx_size = 200000 +wasm_code_id = "f7c074381015210b47c1bdf57acf25c11f86068b752332374e0ed3f01226be96" +channel_whitelist = [["channel-0", "transfer"]] +mnemonic = "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" +skip_optional_client_updates = true +max_packets_to_process = 50 +client_update_interval_sec = 0 diff --git a/config/solana-devnet.toml b/config/solana-devnet.toml new file mode 100644 index 000000000..f152f9e48 --- /dev/null +++ b/config/solana-devnet.toml @@ -0,0 +1,26 @@ +type = "solana" +name = "solana" +rpc_url = "https://devnet.helius-rpc.com/?api-key=bc5c0cfc-46df-4781-978f-af6ca7a202c2" +ws_url = "wss://devnet.helius-rpc.com/?api-key=bc5c0cfc-46df-4781-978f-af6ca7a202c2" +chain_id = "solana-1" +client_id = "08-wasm-201" +connection_id = "connection-1" +account_prefix = "ibc" +fee_denom = "stake" +fee_amount = "4000" +gas_limit = 100000000 +store_prefix = "ibc" +max_tx_size = 320000 +commitment_prefix = [105, 98, 99] +channel_whitelist = [["channel-1", "transfer"]] +commitment_level = "confirmed" +private_key = [48, 123, 8, 80, 248, 0, 217, 142, 124, 193, 95, 24, 168, 139, 214, 136, 147, 210, 168, 135, 26, 36, 162, 89, 150, 185, 99, 191, 247, 135, 78, 111, 12, 8, 4, 81, 129, 165, 153, 230, 192, 225, 51, 119, 216, 14, 69, 225, 73, 7, 204, 144, 39, 213, 91, 255, 136, 38, 95, 131, 197, 4, 101, 186] +solana_ibc_program_id = "FeFjYj2YuMsk87Cp48ubzQPtW4MWDaKJrCs1TcdgosZJ" +write_program_id = "FufGpHqMQgGVjtMH9AV8YMrJYq8zaK6USRsJkZP4yDjo" +signature_verifier_program_id = "C6r1VEbn3mSpecgrZ7NdBvWUtYVJWrDPv4uU9Xs956gc" +trie_db_path = "../solana-ibc-indexer/indexer.db3" +transaction_sender = "JITO" + +[common_state_config] +skip_optional_client_updates = true +max_packets_to_process = 10 \ No newline at end of file diff --git a/contracts/pallet-ibc/Cargo.toml b/contracts/pallet-ibc/Cargo.toml index 9b6a8cfc8..1deda570c 100644 --- a/contracts/pallet-ibc/Cargo.toml +++ b/contracts/pallet-ibc/Cargo.toml @@ -33,6 +33,7 @@ derive_more = { version = "0.99.17", default-features = false, features = [ "from", "display", ] } +borsh = { version = "0.10.3", default-features = false } # substrate frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } @@ -45,10 +46,15 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } # ibc ibc-proto = { path = "../../ibc/proto", default-features = false } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } # cannot be defined as optional in workspace -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } # cannot be defined as optional in workspace +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } ics23 = { git = "https://github.com/cosmos/ics23", rev = "74ce807b7be39a7e0afb4e2efb8e28a57965f57b", default-features = false } +#guest-chain +cf-guest = { path = "../../light-clients/cf-guest" } +guestchain = { path = "../../../emulated-light-client/common/guestchain" , default-features = false } +ed25519-dalek = { version = "2.1.1", default-features = false, features = ["pkcs8"] } + grandpa-client-primitives = { package = "grandpa-light-client-primitives", path = "../../algorithms/grandpa/primitives", default-features = false } beefy-client-primitives = { package = "beefy-light-client-primitives", path = "../../algorithms/beefy/primitives", default-features = false } light-client-common = { path = "../../light-clients/common", default-features = false } @@ -81,6 +87,7 @@ finality-grandpa = { version = "0.16.2", features = [ [dependencies.ibc] path = "../../ibc/modules" default-features = false +features = ["mocks"] [dependencies.ibc-derive] path = "../../ibc/derive" @@ -94,7 +101,7 @@ default-features = false [dependencies.tendermint-light-client-verifier] git = "https://github.com/informalsystems/tendermint-rs" -rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" +rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" default-features = false [dev-dependencies] @@ -111,7 +118,7 @@ sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = prost = { version = "0.11" } #simple-iavl = { path = "simple-iavl" } sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } pallet-ibc-ping = { path = "ping", default-features = false } sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" } env_logger = "0.10.0" @@ -122,6 +129,7 @@ features = ["mocks"] [features] default = ["std"] +# testing = ["ibc/mocks"] testing = [] std = [ "codec/std", diff --git a/contracts/pallet-ibc/ping/src/lib.rs b/contracts/pallet-ibc/ping/src/lib.rs index e399575d7..d8f09169a 100644 --- a/contracts/pallet-ibc/ping/src/lib.rs +++ b/contracts/pallet-ibc/ping/src/lib.rs @@ -19,7 +19,7 @@ use ibc::{ }, ics24_host::identifier::{ChannelId, ConnectionId, PortId}, ics26_routing::context::{ - Acknowledgement as GenericAcknowledgement, Module, ModuleCallbackContext, + Acknowledgement as GenericAcknowledgement, Module as ModuleT, ModuleCallbackContext, ModuleOutputBuilder, }, }, @@ -159,7 +159,7 @@ impl core::fmt::Debug for IbcModule { } } -impl Module for IbcModule { +impl ModuleT for IbcModule { fn on_chan_open_init( &mut self, _ctx: &dyn ModuleCallbackContext, diff --git a/contracts/pallet-ibc/primitives/src/lib.rs b/contracts/pallet-ibc/primitives/src/lib.rs index fd28311f9..9fb353496 100644 --- a/contracts/pallet-ibc/primitives/src/lib.rs +++ b/contracts/pallet-ibc/primitives/src/lib.rs @@ -140,10 +140,10 @@ impl From for PacketInfo { fn from(packet: Packet) -> Self { Self { sequence: packet.sequence.into(), - source_port: packet.source_port.to_string().as_bytes().to_vec(), - source_channel: packet.source_channel.to_string().as_bytes().to_vec(), - destination_port: packet.destination_port.to_string().as_bytes().to_vec(), - destination_channel: packet.destination_channel.to_string().as_bytes().to_vec(), + source_port: packet.source_port.to_string().into_bytes(), + source_channel: packet.source_channel.to_string().into_bytes(), + destination_port: packet.destination_port.to_string().into_bytes(), + destination_channel: packet.destination_channel.to_string().into_bytes(), data: packet.data, timeout_height: ( packet.timeout_height.revision_number, diff --git a/contracts/pallet-ibc/rpc/Cargo.toml b/contracts/pallet-ibc/rpc/Cargo.toml index 6eb4d9314..a9ca86e95 100644 --- a/contracts/pallet-ibc/rpc/Cargo.toml +++ b/contracts/pallet-ibc/rpc/Cargo.toml @@ -26,7 +26,7 @@ sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "pol sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" } sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" } sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43" } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [dependencies.ibc] path = "../../../ibc/modules" diff --git a/contracts/pallet-ibc/rpc/src/events.rs b/contracts/pallet-ibc/rpc/src/events.rs index 53644a5b2..4878056d9 100644 --- a/contracts/pallet-ibc/rpc/src/events.rs +++ b/contracts/pallet-ibc/rpc/src/events.rs @@ -27,7 +27,7 @@ where let packets: Vec = api .query_send_packet_info( at, - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), port_id.as_bytes().to_vec(), vec![sequence], ) @@ -45,7 +45,7 @@ where let packets: Vec = api .query_recv_packet_info( at, - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), port_id.as_bytes().to_vec(), vec![sequence], ) @@ -63,7 +63,7 @@ where let packets: Vec = api .query_recv_packet_info( at, - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), port_id.as_bytes().to_vec(), vec![sequence], ) @@ -81,7 +81,7 @@ where let packets: Vec = api .query_send_packet_info( at, - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), port_id.as_bytes().to_vec(), vec![sequence], ) @@ -99,7 +99,7 @@ where let packets: Vec = api .query_send_packet_info( at, - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), port_id.as_bytes().to_vec(), vec![sequence], ) @@ -117,7 +117,7 @@ where let packets: Vec = api .query_send_packet_info( at, - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), port_id.as_bytes().to_vec(), vec![sequence], ) diff --git a/contracts/pallet-ibc/simple-iavl/Cargo.toml b/contracts/pallet-ibc/simple-iavl/Cargo.toml index 6ce8c5a04..efa05c444 100644 --- a/contracts/pallet-ibc/simple-iavl/Cargo.toml +++ b/contracts/pallet-ibc/simple-iavl/Cargo.toml @@ -15,7 +15,7 @@ description = """ bytes = { version = "1.1.0", default-features = false } ics23 = { git = "https://github.com/cosmos/ics23", rev = "74ce807b7be39a7e0afb4e2efb8e28a57965f57b", default-features = false } sha2 = { version = "0.10.2", default-features = false } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [dev-dependencies] proptest = "*" diff --git a/contracts/pallet-ibc/src/benchmarks/benchmarking.rs b/contracts/pallet-ibc/src/benchmarks/benchmarking.rs index 1df24f1cd..e276ced45 100644 --- a/contracts/pallet-ibc/src/benchmarks/benchmarking.rs +++ b/contracts/pallet-ibc/src/benchmarks/benchmarking.rs @@ -915,7 +915,7 @@ benchmarks! { let timeout = Timeout::Offset { timestamp: Some(1690894363), height: Some(2000) }; let transfer_params = TransferParams { - to: MultiAddress::Raw("bob".to_string().as_bytes().to_vec()), + to: MultiAddress::Raw("bob".to_string().into_bytes()), source_channel: channel_id.sequence(), timeout, }; @@ -988,7 +988,7 @@ benchmarks! { let mut output = HandlerOutputBuilder::new(); let port_id = PortId::transfer(); let channel_id = ChannelId::new(0); - let channel_ids = vec![channel_id.to_string().as_bytes().to_vec()]; + let channel_ids = vec![channel_id.to_string().into_bytes()]; ChannelIds::::put(channel_ids); let mut handler = IbcModule::::default(); }:{ @@ -1003,7 +1003,7 @@ benchmarks! { let mut output = HandlerOutputBuilder::new(); let port_id = PortId::transfer(); let channel_id = ChannelId::new(0); - let channel_ids = vec![channel_id.to_string().as_bytes().to_vec()]; + let channel_ids = vec![channel_id.to_string().into_bytes()]; ChannelIds::::put(channel_ids); let mut handler = IbcModule::::default(); }:{ @@ -1351,7 +1351,7 @@ benchmarks! { } } - let channel_id_bytes = channel_id.to_string().as_bytes().to_vec(); + let channel_id_bytes = channel_id.to_string().into_bytes(); let port_id_bytes = port_id.as_bytes().to_vec(); let (send_seq_set, _) = diff --git a/contracts/pallet-ibc/src/channel.rs b/contracts/pallet-ibc/src/channel.rs index 3a80d9325..5f26c4988 100644 --- a/contracts/pallet-ibc/src/channel.rs +++ b/contracts/pallet-ibc/src/channel.rs @@ -16,7 +16,6 @@ use crate::{ }; use ibc::{ core::{ - ics02_client::error::Error as ICS02Error, ics04_channel::{ channel::ChannelEnd, commitment::{AcknowledgementCommitment, PacketCommitment as PacketCommitmentType}, @@ -201,9 +200,7 @@ where client_id: &ClientId, height: Height, ) -> Result { - let encoded_height = height - .encode_vec() - .map_err(|e| ICS04Error::ics02_client(ICS02Error::encode(e)))?; + let encoded_height = height.encode_vec(); let client_id_bytes = client_id.as_bytes().to_vec(); let timestamp = ClientUpdateTime::::get(client_id_bytes, encoded_height).ok_or_else(|| { @@ -225,9 +222,7 @@ where client_id: &ClientId, height: Height, ) -> Result { - let encoded_height = height - .encode_vec() - .map_err(|e| ICS04Error::ics02_client(ICS02Error::encode(e)))?; + let encoded_height = height.encode_vec(); let client_id_bytes = client_id.as_bytes().to_vec(); let host_height = ClientUpdateHeight::::get(client_id_bytes, encoded_height) .ok_or_else(|| { @@ -285,7 +280,7 @@ where packet: ibc::core::ics04_channel::packet::Packet, ) -> Result<(), ICS04Error> { // store packet offchain - let channel_id = key.1.to_string().as_bytes().to_vec(); + let channel_id = key.1.to_string().into_bytes(); let port_id = key.0.as_bytes().to_vec(); let seq = u64::from(key.2); let channel_end = ChannelReader::channel_end(self, &(key.0, key.1))?; @@ -306,7 +301,7 @@ where packet: ibc::core::ics04_channel::packet::Packet, ) -> Result<(), ICS04Error> { // Store packet offchain - let channel_id = key.1.to_string().as_bytes().to_vec(); + let channel_id = key.1.to_string().into_bytes(); let port_id = key.0.as_bytes().to_vec(); let seq = u64::from(key.2); let channel_end = ChannelReader::channel_end(self, &(key.0, key.1))?; @@ -396,10 +391,8 @@ where ) -> Result<(), ICS04Error> { let conn_id = conn_id.as_bytes().to_vec(); - let port_channel_id = ( - port_channel_id.0.as_bytes().to_vec(), - port_channel_id.1.to_string().as_bytes().to_vec(), - ); + let port_channel_id = + (port_channel_id.0.as_bytes().to_vec(), port_channel_id.1.to_string().into_bytes()); if >::contains_key(conn_id.clone()) { log::trace!(target: "pallet_ibc", "in channel: [store_connection_channels] >> insert port_channel_id"); diff --git a/contracts/pallet-ibc/src/client.rs b/contracts/pallet-ibc/src/client.rs index c013659cd..1abc521cf 100644 --- a/contracts/pallet-ibc/src/client.rs +++ b/contracts/pallet-ibc/src/client.rs @@ -395,7 +395,7 @@ where timestamp: Timestamp, ) -> Result<(), ICS02Error> { log::trace!(target: "pallet_ibc", "in client: [store_update_time] >> Client Height {:?}, Host Timestamp {:?} ", height, timestamp); - let height = height.encode_vec().map_err(ICS02Error::encode)?; + let height = height.encode_vec(); let timestamp = timestamp.nanoseconds(); let client_id = client_id.as_bytes().to_vec(); ClientUpdateTime::::insert(client_id, height, timestamp); @@ -409,8 +409,8 @@ where host_height: Height, ) -> Result<(), ICS02Error> { log::trace!(target: "pallet_ibc", "in client: [store_update_height] >> Client Height {:?}, Host Height {:?} ", height, host_height); - let height = height.encode_vec().map_err(ICS02Error::encode)?; - let host_height = host_height.encode_vec().map_err(ICS02Error::encode)?; + let height = height.encode_vec(); + let host_height = host_height.encode_vec(); let client_id = client_id.as_bytes().to_vec(); ClientUpdateHeight::::insert(client_id, height, host_height); Ok(()) diff --git a/contracts/pallet-ibc/src/events.rs b/contracts/pallet-ibc/src/events.rs index 8071b78dd..d791e93e9 100644 --- a/contracts/pallet-ibc/src/events.rs +++ b/contracts/pallet-ibc/src/events.rs @@ -43,6 +43,8 @@ pub enum IbcEvent { consensus_height: u64, consensus_revision_number: u64, }, + /// Client update proposal passed + UpdateClientProposal { client_id: Vec, client_type: Vec }, /// Client upgraded UpgradeClient { client_id: Vec, @@ -236,6 +238,10 @@ impl From for IbcEvent { consensus_height: ev.0.consensus_height.revision_height, consensus_revision_number: ev.0.consensus_height.revision_number, }, + RawIbcEvent::UpdateClientProposal(ev) => IbcEvent::UpdateClientProposal { + client_id: ev.client_id().as_bytes().to_vec(), + client_type: ev.client_type().as_bytes().to_vec(), + }, RawIbcEvent::UpdateClient(ev) => IbcEvent::UpdateClient { client_id: ev.client_id().as_bytes().to_vec(), client_type: ev.client_type().as_bytes().to_vec(), @@ -311,124 +317,114 @@ impl From for IbcEvent { RawIbcEvent::OpenInitChannel(ev) => IbcEvent::OpenInitChannel { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev - .channel_id() - .map(|channel_id| channel_id.to_string().as_bytes().to_vec()), + channel_id: ev.channel_id().map(|channel_id| channel_id.to_string().into_bytes()), port_id: ev.port_id().as_bytes().to_vec(), connection_id: ev.connection_id.as_bytes().to_vec(), counterparty_port_id: ev.counterparty_port_id.as_bytes().to_vec(), counterparty_channel_id: ev .counterparty_channel_id - .map(|val| val.to_string().as_bytes().to_vec()), + .map(|val| val.to_string().into_bytes()), }, RawIbcEvent::OpenTryChannel(ev) => IbcEvent::OpenTryChannel { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev - .channel_id() - .map(|channel_id| channel_id.to_string().as_bytes().to_vec()), + channel_id: ev.channel_id().map(|channel_id| channel_id.to_string().into_bytes()), port_id: ev.port_id().as_bytes().to_vec(), connection_id: ev.connection_id.as_bytes().to_vec(), counterparty_port_id: ev.counterparty_port_id.as_bytes().to_vec(), counterparty_channel_id: ev .counterparty_channel_id - .map(|val| val.to_string().as_bytes().to_vec()), + .map(|val| val.to_string().into_bytes()), }, RawIbcEvent::OpenAckChannel(ev) => IbcEvent::OpenAckChannel { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev - .channel_id() - .map(|channel_id| channel_id.to_string().as_bytes().to_vec()), + channel_id: ev.channel_id().map(|channel_id| channel_id.to_string().into_bytes()), port_id: ev.port_id().as_bytes().to_vec(), connection_id: ev.connection_id.as_bytes().to_vec(), counterparty_port_id: ev.counterparty_port_id.as_bytes().to_vec(), counterparty_channel_id: ev .counterparty_channel_id - .map(|val| val.to_string().as_bytes().to_vec()), + .map(|val| val.to_string().into_bytes()), }, RawIbcEvent::OpenConfirmChannel(ev) => IbcEvent::OpenConfirmChannel { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev - .channel_id() - .map(|channel_id| channel_id.to_string().as_bytes().to_vec()), + channel_id: ev.channel_id().map(|channel_id| channel_id.to_string().into_bytes()), port_id: ev.port_id().as_bytes().to_vec(), connection_id: ev.connection_id.as_bytes().to_vec(), counterparty_port_id: ev.counterparty_port_id.as_bytes().to_vec(), counterparty_channel_id: ev .counterparty_channel_id - .map(|val| val.to_string().as_bytes().to_vec()), + .map(|val| val.to_string().into_bytes()), }, RawIbcEvent::CloseInitChannel(ev) => IbcEvent::CloseInitChannel { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.channel_id().to_string().into_bytes(), port_id: ev.port_id().as_bytes().to_vec(), connection_id: ev.connection_id.as_bytes().to_vec(), counterparty_port_id: ev.counterparty_port_id.as_bytes().to_vec(), counterparty_channel_id: ev .counterparty_channel_id - .map(|val| val.to_string().as_bytes().to_vec()), + .map(|val| val.to_string().into_bytes()), }, RawIbcEvent::CloseConfirmChannel(ev) => IbcEvent::CloseConfirmChannel { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, port_id: ev.port_id.as_bytes().to_vec(), - channel_id: ev - .channel_id() - .map(|channel_id| channel_id.to_string().as_bytes().to_vec()), + channel_id: ev.channel_id().map(|channel_id| channel_id.to_string().into_bytes()), connection_id: ev.connection_id.as_bytes().to_vec(), counterparty_port_id: ev.counterparty_port_id.as_bytes().to_vec(), counterparty_channel_id: ev .counterparty_channel_id - .map(|val| val.to_string().as_bytes().to_vec()), + .map(|val| val.to_string().into_bytes()), }, RawIbcEvent::SendPacket(ev) => IbcEvent::SendPacket { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.src_channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.src_channel_id().to_string().into_bytes(), port_id: ev.src_port_id().as_bytes().to_vec(), dest_port: ev.dst_port_id().as_bytes().to_vec(), - dest_channel: ev.dst_channel_id().to_string().as_bytes().to_vec(), + dest_channel: ev.dst_channel_id().to_string().into_bytes(), sequence: ev.packet.sequence.into(), }, RawIbcEvent::ReceivePacket(ev) => IbcEvent::ReceivePacket { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.src_channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.src_channel_id().to_string().into_bytes(), port_id: ev.src_port_id().as_bytes().to_vec(), dest_port: ev.dst_port_id().as_bytes().to_vec(), - dest_channel: ev.dst_channel_id().to_string().as_bytes().to_vec(), + dest_channel: ev.dst_channel_id().to_string().into_bytes(), sequence: ev.packet.sequence.into(), }, RawIbcEvent::WriteAcknowledgement(ev) => IbcEvent::WriteAcknowledgement { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.src_channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.src_channel_id().to_string().into_bytes(), port_id: ev.src_port_id().as_bytes().to_vec(), dest_port: ev.dst_port_id().as_bytes().to_vec(), - dest_channel: ev.dst_channel_id().to_string().as_bytes().to_vec(), + dest_channel: ev.dst_channel_id().to_string().into_bytes(), sequence: ev.packet.sequence.into(), }, RawIbcEvent::AcknowledgePacket(ev) => IbcEvent::AcknowledgePacket { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.src_channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.src_channel_id().to_string().into_bytes(), port_id: ev.src_port_id().as_bytes().to_vec(), sequence: ev.packet.sequence.into(), }, RawIbcEvent::TimeoutPacket(ev) => IbcEvent::TimeoutPacket { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.src_channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.src_channel_id().to_string().into_bytes(), port_id: ev.src_port_id().as_bytes().to_vec(), sequence: ev.packet.sequence.into(), }, RawIbcEvent::TimeoutOnClosePacket(ev) => IbcEvent::TimeoutOnClosePacket { revision_height: ev.height().revision_height, revision_number: ev.height().revision_number, - channel_id: ev.src_channel_id().to_string().as_bytes().to_vec(), + channel_id: ev.src_channel_id().to_string().into_bytes(), port_id: ev.src_port_id().as_bytes().to_vec(), sequence: ev.packet.sequence.into(), }, @@ -436,7 +432,7 @@ impl From for IbcEvent { RawIbcEvent::ChainError(_) => IbcEvent::ChainError, RawIbcEvent::AppModule(ev) => IbcEvent::AppModule { kind: ev.kind.as_bytes().to_vec(), - module_id: ev.module_name.to_string().as_bytes().to_vec(), + module_id: ev.module_name.to_string().into_bytes(), }, RawIbcEvent::PushWasmCode(ev) => { let wasm_checksum = ev.0; @@ -509,6 +505,14 @@ impl TryFrom for RawIbcEvent { }, header: None, })), + IbcEvent::UpdateClientProposal { client_id, client_type } => + Ok(RawIbcEvent::UpdateClientProposal(ClientEvents::UpdateClientProposal { + client_id: ClientId::from_str( + &String::from_utf8(client_id).map_err(|_| ERROR_STR)?, + ) + .map_err(|_| ERROR_STR)?, + client_type: String::from_utf8(client_type).map_err(|_| ERROR_STR)?, + })), IbcEvent::UpgradeClient { client_id, client_type, diff --git a/contracts/pallet-ibc/src/ics20/mod.rs b/contracts/pallet-ibc/src/ics20/mod.rs index c46a0d4f2..89a407e51 100644 --- a/contracts/pallet-ibc/src/ics20/mod.rs +++ b/contracts/pallet-ibc/src/ics20/mod.rs @@ -127,7 +127,7 @@ where _relayer: &Signer, ) -> Result<(), Ics04Error> { let _ = ChannelIds::::try_mutate::<_, (), _>(|channels| { - channels.push(channel_id.to_string().as_bytes().to_vec()); + channels.push(channel_id.to_string().into_bytes()); Ok(()) }); let mut ctx = Context::::default(); @@ -144,7 +144,7 @@ where _relayer: &Signer, ) -> Result<(), Ics04Error> { let _ = ChannelIds::::try_mutate::<_, (), _>(|channels| { - channels.push(channel_id.to_string().as_bytes().to_vec()); + channels.push(channel_id.to_string().into_bytes()); Ok(()) }); let mut ctx = Context::::default(); @@ -161,11 +161,8 @@ where _relayer: &Signer, ) -> Result<(), Ics04Error> { let _ = ChannelIds::::try_mutate::<_, (), _>(|channels| { - let rem = channels - .iter() - .filter(|chan| chan.as_slice() != channel_id.to_string().as_bytes()) - .cloned() - .collect(); + let channel_id = channel_id.to_string().into_bytes(); + let rem = channels.iter().filter(|chan| **chan != channel_id).cloned().collect(); *channels = rem; Ok(()) }); @@ -185,11 +182,8 @@ where _relayer: &Signer, ) -> Result<(), Ics04Error> { let _ = ChannelIds::::try_mutate::<_, (), _>(|channels| { - let rem = channels - .iter() - .filter(|chan| chan.as_slice() != channel_id.to_string().as_bytes()) - .cloned() - .collect(); + let channel_id = channel_id.to_string().into_bytes(); + let rem = channels.iter().filter(|chan| **chan != channel_id).cloned().collect(); *channels = rem; Ok(()) }); @@ -270,8 +264,8 @@ where packet.source_channel, &prefixed_denom, ), - source_channel: packet.source_channel.to_string().as_bytes().to_vec(), - destination_channel: packet.destination_channel.to_string().as_bytes().to_vec(), + source_channel: packet.source_channel.to_string().into_bytes(), + destination_channel: packet.destination_channel.to_string().into_bytes(), }); let packet = packet.clone(); Pallet::::handle_message(HandlerMessage::WriteAck { @@ -318,7 +312,7 @@ where Pallet::::deposit_event(Event::::TokenTransferCompleted { from: packet_data.sender, to: packet_data.receiver, - ibc_denom: packet_data.token.denom.to_string().as_bytes().to_vec(), + ibc_denom: packet_data.token.denom.to_string().into_bytes(), local_asset_id: T::IbcDenomToAssetIdConversion::from_denom_to_asset_id( &packet_data.token.denom.to_string(), ) @@ -329,8 +323,8 @@ where packet.source_channel, &packet_data.token.denom, ), - source_channel: packet.source_channel.to_string().as_bytes().to_vec(), - destination_channel: packet.destination_channel.to_string().as_bytes().to_vec(), + source_channel: packet.source_channel.to_string().into_bytes(), + destination_channel: packet.destination_channel.to_string().into_bytes(), }) }, Err(e) => { @@ -346,7 +340,7 @@ where Pallet::::deposit_event(Event::::TokenTransferFailed { from: packet_data.sender, to: packet_data.receiver, - ibc_denom: packet_data.token.denom.to_string().as_bytes().to_vec(), + ibc_denom: packet_data.token.denom.to_string().into_bytes(), local_asset_id: T::IbcDenomToAssetIdConversion::from_denom_to_asset_id( &packet_data.token.denom.to_string(), ) @@ -357,8 +351,8 @@ where packet.source_channel, &packet_data.token.denom, ), - source_channel: packet.source_channel.to_string().as_bytes().to_vec(), - destination_channel: packet.destination_channel.to_string().as_bytes().to_vec(), + source_channel: packet.source_channel.to_string().into_bytes(), + destination_channel: packet.destination_channel.to_string().into_bytes(), }) }, } @@ -385,7 +379,7 @@ where Pallet::::deposit_event(Event::::TokenTransferTimeout { from: packet_data.sender, to: packet_data.receiver, - ibc_denom: packet_data.token.denom.to_string().as_bytes().to_vec(), + ibc_denom: packet_data.token.denom.to_string().into_bytes(), local_asset_id: T::IbcDenomToAssetIdConversion::from_denom_to_asset_id( &packet_data.token.denom.to_string(), ) @@ -396,8 +390,8 @@ where packet.source_channel, &packet_data.token.denom, ), - source_channel: packet.source_channel.to_string().as_bytes().to_vec(), - destination_channel: packet.destination_channel.to_string().as_bytes().to_vec(), + source_channel: packet.source_channel.to_string().into_bytes(), + destination_channel: packet.destination_channel.to_string().into_bytes(), }); Ok(()) } diff --git a/contracts/pallet-ibc/src/ics23/channels.rs b/contracts/pallet-ibc/src/ics23/channels.rs index fc0e56c6a..1e0945c25 100644 --- a/contracts/pallet-ibc/src/ics23/channels.rs +++ b/contracts/pallet-ibc/src/ics23/channels.rs @@ -32,7 +32,7 @@ impl Channels { child::put( &ChildInfo::new_default(T::PalletPrefix::get()), &channel_key, - &channel_end.encode_vec().expect("encode channel end"), + &channel_end.clone().encode_vec(), ); } @@ -48,7 +48,7 @@ impl Channels { { return Some(( port_id.as_bytes().to_vec(), - channel_id.to_string().as_bytes().to_vec(), + channel_id.to_string().into_bytes(), value, )) } diff --git a/contracts/pallet-ibc/src/ics23/connections.rs b/contracts/pallet-ibc/src/ics23/connections.rs index cea7d5329..43569bdf2 100644 --- a/contracts/pallet-ibc/src/ics23/connections.rs +++ b/contracts/pallet-ibc/src/ics23/connections.rs @@ -28,7 +28,7 @@ impl Connections { child::put( &ChildInfo::new_default(T::PalletPrefix::get()), &connection_key, - &connection_end.encode_vec().expect("encode connection end"), + &connection_end.clone().encode_vec(), ); } diff --git a/contracts/pallet-ibc/src/impls.rs b/contracts/pallet-ibc/src/impls.rs index 5106b40a6..29b71823b 100644 --- a/contracts/pallet-ibc/src/impls.rs +++ b/contracts/pallet-ibc/src/impls.rs @@ -21,9 +21,7 @@ use ibc::{ msgs::transfer::MsgTransfer, relay::send_transfer::send_transfer, PrefixedCoin, }, core::{ - ics02_client::{ - client_consensus::ConsensusState, client_state::ClientState, context::ClientReader, - }, + ics02_client::{client_consensus::ConsensusState, context::ClientReader}, ics03_connection::context::ConnectionReader, ics04_channel::{ channel::ChannelEnd, @@ -507,7 +505,7 @@ where key: (PortId, ChannelId, Sequence), ack: Vec, ) -> Result<(), Error> { - let channel_id = key.1.to_string().as_bytes().to_vec(); + let channel_id = key.1.to_string().into_bytes(); let port_id = key.0.as_bytes().to_vec(); let seq = u64::from(key.2); @@ -789,7 +787,10 @@ where benchmarks::tendermint_benchmark_utils::create_mock_state, light_clients::AnyConsensusState, }; - use ibc::core::ics02_client::msgs::create_client::{MsgCreateAnyClient, TYPE_URL}; + use ibc::core::ics02_client::{ + client_state::ClientState, + msgs::create_client::{MsgCreateAnyClient, TYPE_URL}, + }; let (mock_client_state, mock_cs_state) = create_mock_state(); let client_id = ClientId::new(&mock_client_state.client_type(), 0).unwrap(); @@ -799,8 +800,7 @@ where Signer::from_str("pallet_ibc").unwrap(), ) .unwrap() - .encode_vec() - .unwrap(); + .encode_vec(); let msg = ibc_proto::google::protobuf::Any { type_url: TYPE_URL.to_string(), value: msg }; let mut ctx = Context::::new(); ibc::core::ics26_routing::handler::deliver(&mut ctx, msg).unwrap(); @@ -945,12 +945,8 @@ where .map_err(|_| IbcHandlerError::ChannelInitError { msg: None })?, }; - let msg = ibc_proto::google::protobuf::Any { - type_url: msg.type_url(), - value: msg - .encode_vec() - .map_err(|e| IbcHandlerError::Other { msg: Some(e.to_string()) })?, - }; + let msg = + ibc_proto::google::protobuf::Any { type_url: msg.type_url(), value: msg.encode_vec() }; let res = ibc::core::ics26_routing::handler::deliver::<_>(&mut ctx, msg) .map_err(|e| IbcHandlerError::ChannelInitError { msg: Some(e.to_string()) })?; Self::deposit_event(res.events.into()); @@ -1061,12 +1057,8 @@ where signer: Signer::from_str(MODULE_ID) .map_err(|_| IbcHandlerError::ChannelInitError { msg: None })?, }; - let msg = ibc_proto::google::protobuf::Any { - type_url: msg.type_url(), - value: msg - .encode_vec() - .map_err(|e| IbcHandlerError::Other { msg: Some(e.to_string()) })?, - }; + let msg = + ibc_proto::google::protobuf::Any { type_url: msg.type_url(), value: msg.encode_vec() }; let res = ibc::core::ics26_routing::handler::deliver::<_>(&mut ctx, msg) .map_err(|e| IbcHandlerError::ChannelCloseError { msg: Some(e.to_string()) })?; Self::deposit_event(res.events.into()); diff --git a/contracts/pallet-ibc/src/lib.rs b/contracts/pallet-ibc/src/lib.rs index 25562ae9f..3a56c43e2 100644 --- a/contracts/pallet-ibc/src/lib.rs +++ b/contracts/pallet-ibc/src/lib.rs @@ -961,9 +961,9 @@ pub mod pallet { &coin.denom.to_string(), ) .ok(), - ibc_denom: coin.denom.to_string().as_bytes().to_vec(), - source_channel: source_channel.to_string().as_bytes().to_vec(), - destination_channel: destination_channel.to_string().as_bytes().to_vec(), + ibc_denom: coin.denom.to_string().into_bytes(), + source_channel: source_channel.to_string().into_bytes(), + destination_channel: destination_channel.to_string().into_bytes(), }); }; @@ -1016,6 +1016,8 @@ pub mod pallet { use ibc_primitives::Error::*; match e { SendPacketError { .. } => Error::::TransferSend, + // basically that can be anything, as simple as Balance too, but how one may get + // error of it?........ SendTransferError { .. } => Error::::TransferSend, ReceivePacketError { .. } => Error::::TransferProtocol, @@ -1047,10 +1049,10 @@ pub mod pallet { &coin.denom.to_string(), ) .ok(), - ibc_denom: coin.denom.to_string().as_bytes().to_vec(), + ibc_denom: coin.denom.to_string().into_bytes(), is_sender_source, - source_channel: source_channel.to_string().as_bytes().to_vec(), - destination_channel: destination_channel.to_string().as_bytes().to_vec(), + source_channel: source_channel.to_string().into_bytes(), + destination_channel: destination_channel.to_string().into_bytes(), }); Ok(()) } @@ -1112,8 +1114,12 @@ pub mod pallet { .map_err(|_| Error::::ClientFreezeFailed)?, ) }, + AnyClientState::Guest(guest) => { + let latest_height = guest.latest_height(); + AnyClientState::wrap(&guest) + }, AnyClientState::Wasm(_) => return Err(Error::::ClientFreezeFailed.into()), - #[cfg(test)] + #[cfg(any(test, feature = "testing"))] AnyClientState::Mock(mut ms) => { ms.frozen_height = Some(Height::new(ms.latest_height().revision_number, height)); diff --git a/contracts/pallet-ibc/src/light_clients.rs b/contracts/pallet-ibc/src/light_clients.rs index 60a0ba748..011e9a355 100644 --- a/contracts/pallet-ibc/src/light_clients.rs +++ b/contracts/pallet-ibc/src/light_clients.rs @@ -1,4 +1,11 @@ -use alloc::{borrow::ToOwned, boxed::Box, format, string::ToString, vec::Vec}; +use alloc::{ + borrow::{Cow, ToOwned}, + boxed::Box, + format, + string::ToString, + vec::Vec, +}; +use borsh::maybestd::io; use frame_support::{ pallet_prelude::{StorageValue, ValueQuery}, traits::StorageInstance, @@ -49,13 +56,124 @@ use tendermint::{ Sha256 as TendermintSha256, }, merkle::{Hash, MerkleHash, NonIncremental, HASH_SIZE}, - PublicKey, Signature, + PublicKey, Signature as TmSignature, }; use tendermint_proto::Protobuf; +const GUEST_CLIENT_MESSAGE_TYPE_URL: &'static str = cf_guest::proto::ClientMessage::IBC_TYPE_URL; +const GUEST_CLIENT_STATE_TYPE_URL: &'static str = cf_guest::proto::ClientState::IBC_TYPE_URL; +const GUEST_CONSENSUS_STATE_TYPE_URL: &'static str = cf_guest::proto::ConsensusState::IBC_TYPE_URL; +const GUEST_HEADER_TYPE_URL: &'static str = cf_guest::proto::Header::IBC_TYPE_URL; +const GUEST_MISBEHAVIOUR_TYPE_URL: &'static str = cf_guest::proto::Misbehaviour::IBC_TYPE_URL; + #[derive(Clone, Default, PartialEq, Debug, Eq)] pub struct HostFunctionsManager; +/// Ed25519 public key (a.k.a. verifying key). +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct PubKey(ed25519_dalek::VerifyingKey); + +impl guestchain::PubKey for PubKey { + type Signature = Signature; + + fn to_vec(&self) -> Vec { + self.0.as_bytes().to_vec() + } + fn from_bytes(bytes: &[u8]) -> Result { + bytes.try_into().map(Self).map_err(|_| guestchain::BadFormat) + } + + fn as_bytes(&self) -> Cow<'_, [u8]> { + todo!() + } +} + +impl borsh::BorshSerialize for PubKey { + fn serialize(&self, wr: &mut W) -> io::Result<()> { + wr.write_all(self.0.as_bytes()) + } +} + +impl borsh::BorshDeserialize for PubKey { + fn deserialize_reader(rd: &mut R) -> io::Result { + let mut bytes = ed25519_dalek::pkcs8::PublicKeyBytes([0; 32]); + rd.read_exact(&mut bytes.0[..])?; + ed25519_dalek::VerifyingKey::try_from(bytes) + .map(Self) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "malformed Ed25519 public key")) + } +} + +impl PartialOrd for PubKey { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for PubKey { + fn cmp(&self, rhs: &Self) -> core::cmp::Ordering { + self.0.as_bytes().cmp(rhs.0.as_bytes()) + } +} + +/// Ed25519 signature. +#[derive(Clone, PartialEq, Eq, Debug)] +#[repr(transparent)] +pub struct Signature(ed25519_dalek::Signature); + +impl guestchain::Signature for Signature { + fn to_vec(&self) -> Vec { + self.0.to_vec() + } + fn from_bytes(bytes: &[u8]) -> Result { + ed25519_dalek::Signature::from_slice(bytes) + .map(Self) + .map_err(|_| guestchain::BadFormat) + } + + fn as_bytes(&self) -> Cow<'_, [u8]> { + todo!() + } +} + +impl borsh::BorshSerialize for Signature { + fn serialize(&self, wr: &mut W) -> io::Result<()> { + wr.write_all(self.0.r_bytes())?; + wr.write_all(self.0.s_bytes())?; + Ok(()) + } +} + +impl borsh::BorshDeserialize for Signature { + fn deserialize_reader(rd: &mut R) -> io::Result { + let mut buf = [0; 64]; + rd.read_exact(&mut buf[..])?; + Ok(Self(ed25519_dalek::Signature::from_bytes(&buf))) + } +} + +impl core::hash::Hash for Signature { + fn hash(&self, hasher: &mut H) { + hasher.write(self.0.r_bytes()); + hasher.write(self.0.s_bytes()); + } +} + +impl PartialOrd for Signature { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for Signature { + fn cmp(&self, rhs: &Self) -> core::cmp::Ordering { + let lhs = (self.0.r_bytes(), self.0.s_bytes()); + let rhs = (rhs.0.r_bytes(), rhs.0.s_bytes()); + lhs.cmp(&rhs) + } +} + impl ics23::HostFunctionsProvider for HostFunctionsManager { fn sha2_256(message: &[u8]) -> [u8; 32] { sp_io::hashing::sha2_256(message) @@ -102,7 +220,7 @@ impl Verifier for HostFunctionsManager { fn verify( pubkey: PublicKey, msg: &[u8], - signature: &Signature, + signature: &TmSignature, ) -> Result<(), TendermintCryptoError> { let signature = sp_core::ed25519::Signature::from_slice(signature.as_bytes()) .ok_or(TendermintCryptoError::MalformedSignature)?; @@ -117,6 +235,7 @@ impl Verifier for HostFunctionsManager { impl ics07_tendermint::HostFunctionsProvider for HostFunctionsManager {} pub struct GrandpaHeaderHashesStorageInstance; + impl StorageInstance for GrandpaHeaderHashesStorageInstance { fn pallet_prefix() -> &'static str { "ibc.lightclients.grandpa" @@ -124,6 +243,7 @@ impl StorageInstance for GrandpaHeaderHashesStorageInstance { const STORAGE_PREFIX: &'static str = "HeaderHashes"; } + pub type GrandpaHeaderHashesStorage = StorageValue< GrandpaHeaderHashesStorageInstance, BoundedVec>, @@ -131,6 +251,7 @@ pub type GrandpaHeaderHashesStorage = StorageValue< >; pub struct GrandpaHeaderHashesSetStorageInstance; + impl StorageInstance for GrandpaHeaderHashesSetStorageInstance { fn pallet_prefix() -> &'static str { "ibc.lightclients.grandpa" @@ -138,6 +259,7 @@ impl StorageInstance for GrandpaHeaderHashesSetStorageInstance { const STORAGE_PREFIX: &'static str = "HeaderHashesSet"; } + pub type GrandpaHeaderHashesSetStorage = StorageValue< GrandpaHeaderHashesSetStorageInstance, BoundedBTreeSet>, @@ -210,7 +332,8 @@ pub enum AnyClient { Beefy(ics11_beefy::client_def::BeefyClient), Tendermint(ics07_tendermint::client_def::TendermintClient), Wasm(ics08_wasm::client_def::WasmClient), - #[cfg(test)] + Guest(cf_guest::client_def::GuestClient), + #[cfg(any(test, feature = "testing"))] Mock(ibc::mock::client_def::MockClient), } @@ -220,7 +343,8 @@ pub enum AnyUpgradeOptions { Beefy(ics11_beefy::client_state::UpgradeOptions), Tendermint(ics07_tendermint::client_state::UpgradeOptions), Wasm(Box), - #[cfg(test)] + Guest(cf_guest::client::UpgradeOptions), + #[cfg(any(test, feature = "testing"))] Mock(()), } @@ -234,7 +358,9 @@ pub enum AnyClientState { Tendermint(ics07_tendermint::client_state::ClientState), #[ibc(proto_url = "WASM_CLIENT_STATE_TYPE_URL")] Wasm(ics08_wasm::client_state::ClientState), - #[cfg(test)] + #[ibc(proto_url = "GUEST_CLIENT_STATE_TYPE_URL")] + Guest(cf_guest::ClientState), + #[cfg(any(test, feature = "testing"))] #[ibc(proto_url = "MOCK_CLIENT_STATE_TYPE_URL")] Mock(ibc::mock::client_state::MockClientState), } @@ -272,6 +398,7 @@ impl AnyClientState { impl AnyClientState { pub fn wasm(inner: Self, checksum: Bytes) -> Result { + log::info!("This is height in any client state {:?}", inner.latest_height()); Ok(Self::Wasm( ics08_wasm::client_state::ClientState:: { data: inner.encode_to_vec()?, @@ -282,6 +409,18 @@ impl AnyClientState { }, )) } + + pub fn latest_height(&self) -> ibc::Height { + match self { + AnyClientState::Grandpa(client_state) => client_state.latest_height(), + AnyClientState::Beefy(client_state) => client_state.latest_height(), + AnyClientState::Tendermint(client_state) => client_state.latest_height(), + AnyClientState::Wasm(client_state) => client_state.latest_height(), + AnyClientState::Guest(client_state) => client_state.latest_height(), + #[cfg(any(test, feature = "testing"))] + AnyClientState::Mock(client_state) => client_state.latest_height(), + } + } } #[derive(Clone, Debug, PartialEq, Eq, ConsensusState, Protobuf)] @@ -294,7 +433,9 @@ pub enum AnyConsensusState { Tendermint(ics07_tendermint::consensus_state::ConsensusState), #[ibc(proto_url = "WASM_CONSENSUS_STATE_TYPE_URL")] Wasm(ics08_wasm::consensus_state::ConsensusState), - #[cfg(test)] + #[ibc(proto_url = "GUEST_CONSENSUS_STATE_TYPE_URL")] + Guest(cf_guest::ConsensusState), + #[cfg(any(test, feature = "testing"))] #[ibc(proto_url = "MOCK_CONSENSUS_STATE_TYPE_URL")] Mock(ibc::mock::client_state::MockConsensusState), } @@ -319,7 +460,9 @@ pub enum AnyClientMessage { Tendermint(ics07_tendermint::client_message::ClientMessage), #[ibc(proto_url = "WASM_CLIENT_MESSAGE_TYPE_URL")] Wasm(ics08_wasm::client_message::ClientMessage), - #[cfg(test)] + #[ibc(proto_url = "GUEST_CLIENT_MESSAGE_TYPE_URL")] + Guest(cf_guest::ClientMessage), + #[cfg(any(test, feature = "testing"))] #[ibc(proto_url = "MOCK_CLIENT_MESSAGE_TYPE_URL")] Mock(ibc::mock::header::MockClientMessage), } @@ -380,6 +523,18 @@ impl TryFrom for AnyClientMessage { ics07_tendermint::client_message::Misbehaviour::decode_vec(&value.value) .map_err(ics02_client::error::Error::decode_raw_header)?, ))), + GUEST_CLIENT_MESSAGE_TYPE_URL => Ok(Self::Guest( + cf_guest::ClientMessage::decode_vec(&value.value) + .map_err(ics02_client::error::Error::decode_raw_header)?, + )), + GUEST_HEADER_TYPE_URL => Ok(Self::Guest(cf_guest::ClientMessage::from( + cf_guest::Header::decode_vec(&value.value) + .map_err(ics02_client::error::Error::decode_raw_header)?, + ))), + GUEST_MISBEHAVIOUR_TYPE_URL => Ok(Self::Guest(cf_guest::ClientMessage::from( + cf_guest::Misbehaviour::decode_vec(&value.value) + .map_err(ics02_client::error::Error::decode_raw_header)?, + ))), WASM_CLIENT_MESSAGE_TYPE_URL => Ok(Self::Wasm( ics08_wasm::client_message::ClientMessage::decode_vec(&value.value) .map_err(ics02_client::error::Error::decode_raw_header)?, @@ -392,39 +547,34 @@ impl TryFrom for AnyClientMessage { impl From for Any { fn from(client_msg: AnyClientMessage) -> Self { match client_msg { - AnyClientMessage::Wasm(msg) => Any { - type_url: WASM_CLIENT_MESSAGE_TYPE_URL.to_string(), - value: msg.encode_vec().expect("encode_vec failed"), - }, + AnyClientMessage::Wasm(msg) => + Any { type_url: WASM_CLIENT_MESSAGE_TYPE_URL.to_string(), value: msg.encode_vec() }, AnyClientMessage::Grandpa(msg) => match msg { - ics10_grandpa::client_message::ClientMessage::Header(h) => Any { - type_url: GRANDPA_HEADER_TYPE_URL.to_string(), - value: h.encode_vec().expect("encode_vec failed"), - }, + ics10_grandpa::client_message::ClientMessage::Header(h) => + Any { type_url: GRANDPA_HEADER_TYPE_URL.to_string(), value: h.encode_vec() }, ics10_grandpa::client_message::ClientMessage::Misbehaviour(m) => Any { type_url: GRANDPA_MISBEHAVIOUR_TYPE_URL.to_string(), - value: m.encode_vec().expect("encode_vec failed"), + value: m.encode_vec(), }, }, - AnyClientMessage::Beefy(msg) => Any { - type_url: BEEFY_CLIENT_MESSAGE_TYPE_URL.to_string(), - value: msg.encode_vec().expect("encode_vec failed"), - }, + AnyClientMessage::Beefy(msg) => + Any { type_url: BEEFY_CLIENT_MESSAGE_TYPE_URL.to_string(), value: msg.encode_vec() }, AnyClientMessage::Tendermint(msg) => Any { type_url: TENDERMINT_CLIENT_MESSAGE_TYPE_URL.to_string(), - value: msg.encode_vec().expect("encode_vec failed"), + value: msg.encode_vec(), }, - - #[cfg(test)] + AnyClientMessage::Guest(msg) => + Any { type_url: GUEST_CLIENT_MESSAGE_TYPE_URL.to_string(), value: msg.encode_vec() }, + #[cfg(any(test, feature = "testing"))] AnyClientMessage::Mock(_msg) => panic!("MockHeader can't be serialized"), } } } -#[cfg(test)] +#[cfg(any(test, feature = "testing"))] pub use mocks::*; -#[cfg(test)] +#[cfg(any(test, feature = "testing"))] mod mocks { pub const MOCK_CLIENT_STATE_TYPE_URL: &str = "/ibc.mock.ClientState"; pub const MOCK_CLIENT_MESSAGE_TYPE_URL: &str = "/ibc.mock.ClientMessage"; diff --git a/hyperspace/core/Cargo.toml b/hyperspace/core/Cargo.toml index bfc96e0fd..6183cbbd8 100644 --- a/hyperspace/core/Cargo.toml +++ b/hyperspace/core/Cargo.toml @@ -22,6 +22,7 @@ normal = ["scale-encode"] primitives = { path = "../primitives", package = "hyperspace-primitives" } parachain = { path = "../parachain", package = "hyperspace-parachain" } cosmos = { path = "../cosmos", package = "hyperspace-cosmos", optional = true } +solana = { path = "../solana", package = "hyperspace-solana", optional = true } #near = { path = "near", package = "hyperspace-near", optional = true } metrics = { path = "../metrics", package = "hyperspace-metrics" } @@ -43,11 +44,12 @@ prometheus = { version = "0.13.0", default-features = false } rand = "0.8.5" itertools = "0.10.5" scale-encode = "0.1.2" +borsh = { version = "0.10.3", default-features = false } # ibc ibc = { path = "../../ibc/modules", features = [] } ibc-proto = { path = "../../ibc/proto" } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } ibc-rpc = { path = "../../contracts/pallet-ibc/rpc" } ics11-beefy = { path = "../../light-clients/ics11-beefy" } @@ -69,6 +71,9 @@ frame-system = { git = "https://github.com/paritytech/substrate", branch = "polk frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } prost = { version = "0.11", default-features = false } serde_json = "1.0.74" +guestchain = { path = "../../../emulated-light-client/common/guestchain" ,default-features = false } +sealable-trie = { path = "../../../emulated-light-client/common/sealable-trie" ,default-features = false } +lib = { path = "../../../emulated-light-client/common/lib" ,default-features = false } [dev-dependencies] derive_more = "0.99.17" @@ -79,6 +84,21 @@ parachain = { path = "../parachain", package = "hyperspace-parachain", features cosmos = { path = "../cosmos", package = "hyperspace-cosmos", features = [ "testing", ] } +solana = { path = "../solana", package = "hyperspace-solana" } +trie-ids = { path = "../../../emulated-light-client/common/trie-ids" ,features = ["borsh"] } + +ibc-new-primitives = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false, features = ["borsh", "serde"] , package="ibc-primitives" } +ibc-core-host-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false, features = ["borsh", "serde"]} +ibc-core-handler-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-client-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-connection-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-channel-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-app-transfer-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-commitment-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-client-tendermint-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +# ibc-testkit = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-proto-new = { version = "0.41.0", default-features = false, package="ibc-proto" } + # substrate subxt = { git = "https://github.com/paritytech/subxt", tag = "v0.29.0", features = [ @@ -93,6 +113,7 @@ sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkad build-metadata-from-ws = [] #near = ["dep:near"] cosmos = ["dep:cosmos"] -testing = ["primitives/testing", "parachain/testing", "cosmos/testing"] -default = ["cosmos"] +solana = ["dep:solana"] +testing = ["primitives/testing", "parachain/testing", "cosmos/testing", "solana/testing"] +default = ["cosmos", "solana"] composable-beefy = [] diff --git a/hyperspace/core/build.rs b/hyperspace/core/build.rs index 269b191e1..902e2121f 100644 --- a/hyperspace/core/build.rs +++ b/hyperspace/core/build.rs @@ -17,19 +17,19 @@ use once_cell::sync::Lazy; static RELAY_URL: Lazy = Lazy::new(|| { let ip = std::env::var("RELAY_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); - format!("ws://{ip}:9944") + format!("ws://{ip}:8900") }); -static PARA_URL: Lazy = Lazy::new(|| { +static SOLANA_URL: Lazy = Lazy::new(|| { let ip = std::env::var("PARA_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); - format!("ws://{ip}:9188") + format!("ws://{ip}:8900") }); #[tokio::main] async fn main() -> anyhow::Result<()> { - if cfg!(feature = "build-metadata-from-ws") { - subxt_codegen::build_script(&RELAY_URL, "polkadot").await?; - subxt_codegen::build_script(&PARA_URL, "parachain").await?; - } + // if cfg!(feature = "build-metadata-from-ws") { + // subxt_codegen::build_script(&RELAY_URL, "polkadot").await?; + // subxt_codegen::build_script(&SOLANA_URL, "parachain").await?; + // } Ok(()) } diff --git a/hyperspace/core/src/chain.rs b/hyperspace/core/src/chain.rs index 2517d8892..10084a657 100644 --- a/hyperspace/core/src/chain.rs +++ b/hyperspace/core/src/chain.rs @@ -30,6 +30,7 @@ use ibc::{ applications::transfer::PrefixedCoin, core::{ ics02_client::{ + client_consensus::ConsensusState, client_state::ClientType, events::{Checksum, UpdateClient}, msgs::{create_client::MsgCreateAnyClient, update_client::MsgUpdateAnyClient}, @@ -69,6 +70,8 @@ use primitives::{ MisbehaviourHandler, UpdateType, }; use serde::{Deserialize, Serialize}; +#[cfg(feature = "solana")] +use solana::{SolanaClient, SolanaClientConfig}; use std::{pin::Pin, time::Duration}; use tendermint_proto::Protobuf; use thiserror::Error; @@ -99,6 +102,8 @@ chains! { PicassoKusama(ParachainClientConfig, ParachainClient), #[cfg(feature = "cosmos")] Cosmos(CosmosClientConfig, CosmosClient), + #[cfg(feature = "solana")] + Solana(SolanaClientConfig, SolanaClient), } fn wrap_any_msg_into_wasm(msg: Any, checksum: Bytes) -> Result { @@ -118,13 +123,23 @@ fn wrap_any_msg_into_wasm(msg: Any, checksum: Bytes) -> Result { let mut msg_decoded = MsgCreateAnyClient::::decode_vec(&msg.value).unwrap(); + log::info!( + "THis is consensus state in wrap any message {:?}", + msg_decoded.consensus_state.timestamp() + ); msg_decoded.consensus_state = AnyConsensusState::wasm(msg_decoded.consensus_state)?; msg_decoded.client_state = AnyClientState::wasm(msg_decoded.client_state, checksum)?; + log::info!( + "THis is consensus state in wrap any message with wasm {:?}", + msg_decoded.consensus_state.timestamp() + ); msg_decoded.to_any() }, CONN_OPEN_TRY_TYPE_URL => { + log::info!("I am in connection open try"); let msg_decoded = MsgConnectionOpenTry::::decode_vec(&msg.value).unwrap(); + log::info!("This is msg decoded {:?} {:?}", msg_decoded, msg); msg_decoded.to_any() }, CONN_OPEN_ACK_TYPE_URL => { @@ -137,6 +152,7 @@ fn wrap_any_msg_into_wasm(msg: Any, checksum: Bytes) -> Result::decode_vec(&msg.value).unwrap(); msg_decoded.client_message = AnyClientMessage::wasm(msg_decoded.client_message)?; + log::info!("This is msg decoded {:?}", msg_decoded.clone().to_any()); msg_decoded.to_any() }, _ => msg, diff --git a/hyperspace/core/src/command.rs b/hyperspace/core/src/command.rs index eb4e4e4bb..7b34f001b 100644 --- a/hyperspace/core/src/command.rs +++ b/hyperspace/core/src/command.rs @@ -69,7 +69,7 @@ pub struct Cmd { port_id: Option, /// Connection delay period in seconds #[clap(long)] - delay_period: Option, + delay_period: Option, /// Channel order #[clap(long)] order: Option, @@ -140,6 +140,8 @@ impl Cmd { let config = self.parse_config().await?; let chain_a = config.chain_a.into_client().await?; let chain_b = config.chain_b.into_client().await?; + // log::info!("This is config A {:?}", chain_a); + // log::info!("This is config B {:?}", chain_b); let registry = Registry::new_custom(None, None).expect("this can only fail if the prefix is empty"); @@ -191,7 +193,7 @@ impl Cmd { } pub async fn create_connection(&self) -> Result { - let delay_period_seconds: NonZeroU64 = self + let delay_period_seconds: u16 = self .delay_period .expect("delay_period should be provided when creating a connection") .into(); diff --git a/hyperspace/core/src/events.rs b/hyperspace/core/src/events.rs index 937d4517a..03f60f54a 100644 --- a/hyperspace/core/src/events.rs +++ b/hyperspace/core/src/events.rs @@ -16,6 +16,7 @@ use crate::send_packet_relay::packet_relay_status; use crate::Mode; use codec::Encode; +use core::time::Duration; use ibc::{ core::{ ics02_client::client_state::ClientState as ClientStateT, @@ -66,10 +67,18 @@ pub async fn parse_events( ) -> Result, anyhow::Error> { let mut messages = vec![]; // 1. translate events to messages + let mut is_connection_delay = false; for event in events { + if matches!(event, IbcEvent::SendPacket(_)) || + matches!(event, IbcEvent::WriteAcknowledgement(_)) && is_connection_delay + { + log::info!("Skipping due to connection delay {:?}", event); + continue + } match event { IbcEvent::OpenInitConnection(open_init) => { if let Some(connection_id) = open_init.connection_id() { + log::info!("I am in open init connection with open init {:?}", open_init); let connection_id = connection_id.clone(); // Get connection end with proof let connection_response = source @@ -87,6 +96,7 @@ pub async fn parse_events( let connection_proof = CommitmentProofBytes::try_from(connection_response.proof)?; + log::info!("Connection Proof {:?}", connection_proof.as_bytes()); let prefix: CommitmentPrefix = source.connection_prefix(); let client_state_response = source .query_client_state( @@ -96,15 +106,21 @@ pub async fn parse_events( .await?; let proof_height = connection_response.proof_height.ok_or_else(|| Error::Custom("[get_messages_for_events - open_conn_init] Proof height not found in response".to_string()))?; - let proof_height = - Height::new(proof_height.revision_number, proof_height.revision_height); + let proof_height = Height::new(1, proof_height.revision_height); + // client_state.latest_height(); let client_state_proof = CommitmentProofBytes::try_from(client_state_response.proof).ok(); - let client_state = client_state_response .client_state + .clone() .map(AnyClientState::try_from) .ok_or_else(|| Error::Custom("Client state is empty".to_string()))??; + + log::info!( + "This is client state {:?} and in any {:?}", + client_state, + client_state_response.client_state + ); let consensus_proof = source .query_client_consensus( open_init.height(), @@ -116,6 +132,11 @@ pub async fn parse_events( query_host_consensus_state_proof(sink, client_state.clone()).await?; // Construct OpenTry + log::info!( + "This was the delay period {:?} in nanos: {:?}", + connection_end.delay_period(), + connection_end.delay_period().as_nanos() + ); let msg = MsgConnectionOpenTry:: { client_id: counterparty.client_id().clone(), // client state proof is mandatory in conn_open_try @@ -140,19 +161,29 @@ pub async fn parse_events( signer: sink.account_id(), host_consensus_state_proof, }; - - let value = msg.encode_vec()?; + log::info!( + "Constructed open try {:?} with client height {:?}", + proof_height, + client_state.latest_height() + ); + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) } }, IbcEvent::OpenTryConnection(open_try) => { if let Some(connection_id) = open_try.connection_id() { + log::info!( + "THis is open try {:?} and connection id {:?}", + open_try, + connection_id + ); let connection_id = connection_id.clone(); // Get connection end with proof let connection_response = source .query_connection_end(open_try.height(), connection_id.clone()) .await?; + log::info!("This is connection open ack from cosmos {:?}", connection_response); let connection_end = ConnectionEnd::try_from( connection_response.connection.ok_or_else(|| { Error::Custom(format!( @@ -161,6 +192,11 @@ pub async fn parse_events( )) })?, )?; + log::info!("This is the connection end in open ack {:?}", connection_end); + log::info!( + "Encoded connection end in open ack {:?}", + connection_end.clone().encode_vec() + ); let counterparty = connection_end.counterparty(); let connection_proof = @@ -176,11 +212,20 @@ pub async fn parse_events( let proof_height = Height::new(proof_height.revision_number, proof_height.revision_height); let client_state_proof = - CommitmentProofBytes::try_from(client_state_response.proof).ok(); - let client_state = client_state_response + CommitmentProofBytes::try_from(client_state_response.clone().proof).ok(); + log::info!( + "This is from cosmos {:?}", + client_state_response.clone().client_state + ); + let client_state: AnyClientState = client_state_response .client_state .map(AnyClientState::try_from) .ok_or_else(|| Error::Custom("Client state is empty".to_string()))??; + log::info!("THis is the client state of solana on cosmos {:?}", client_state); + log::info!( + "This is encoded client state in open ack {:?}", + client_state.clone().encode_vec() + ); let consensus_proof = source .query_client_consensus( open_try.height(), @@ -191,6 +236,9 @@ pub async fn parse_events( let host_consensus_state_proof = query_host_consensus_state_proof(sink, client_state.clone()).await?; // Construct OpenAck + println!("-----------------"); + println!("OpenAck consensus height {:?}", client_state.latest_height()); + println!("-----------------"); let msg = MsgConnectionOpenAck:: { connection_id: counterparty .connection_id() @@ -224,7 +272,7 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) } @@ -255,6 +303,14 @@ pub async fn parse_events( let proof_height = Height::new(proof_height.revision_number, proof_height.revision_height); + println!("-----------------"); + println!( + "Proof Height for OpenConfirm {:?} {:?}", + proof_height, + open_ack.height() + ); + println!("-----------------"); + // Construct OpenConfirm let msg = MsgConnectionOpenConfirm { connection_id: counterparty @@ -267,7 +323,7 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) } @@ -334,7 +390,7 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) } @@ -371,7 +427,7 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) }, @@ -403,7 +459,7 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) }, @@ -435,15 +491,17 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) }, IbcEvent::SendPacket(send_packet) => { #[cfg(feature = "testing")] if !packet_relay_status() { + log::info!("Skipping packet relay status"); continue } + log::info!("Found send packet {:?}", send_packet); // can we send this packet? // 1. query the connection and get the connection delay. // 2. if none, send message immediately @@ -473,18 +531,19 @@ pub async fn parse_events( })?)?; if !connection_end.delay_period().is_zero() { // We can't send this packet immediately because of connection delays - log::debug!( + log::info!( target: "hyperspace", "Skipping packet relay because of connection delays {:?}", connection_end.delay_period() ); + is_connection_delay = true; continue } let seq = u64::from(send_packet.packet.sequence); let packet = send_packet.packet; if packet.timeout_height.is_zero() && packet.timeout_timestamp.nanoseconds() == 0 { - log::warn!( + log::info!( target: "hyperspace", "Skipping packet relay because packet timeout is zero: {}", packet.sequence @@ -503,16 +562,17 @@ pub async fn parse_events( .expect("Proof height should be present"); let proof_height = Height::new(proof_height.revision_number, proof_height.revision_height); + log::info!("Proof height while sending receive packet {:?}", proof_height); let msg = MsgRecvPacket { packet: packet.clone(), proofs: Proofs::new(commitment_proof, None, None, None, proof_height)?, signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg); - log::debug!(target: "hyperspace", "Sending packet {:?}", packet); + log::info!(target: "hyperspace", "Sending packet {:?}", packet); }, IbcEvent::WriteAcknowledgement(write_ack) => { let port_id = &write_ack.packet.destination_port.clone(); @@ -539,9 +599,10 @@ pub async fn parse_events( Error::Custom(format!("ConnectionEnd not found for {connection_id:?}")) })?)?; if !connection_end.delay_period().is_zero() { - log::debug!(target: "hyperspace", "Skipping write acknowledgement because of connection delay {:?}", - connection_end.delay_period()); + log::debug!(target: "hyperspace", "Skipping write acknowledgement because of + connection delay {:?}", connection_end.delay_period()); // We can't send this packet immediately because of connection delays + is_connection_delay = true; continue } let seq = u64::from(write_ack.packet.sequence); @@ -558,6 +619,7 @@ pub async fn parse_events( .expect("Proof height should be present"); let proof_height = Height::new(proof_height.revision_number, proof_height.revision_height); + log::info!("Proof height while sending acknowledgement {:?}", proof_height); let msg = MsgAcknowledgement { packet, acknowledgement: acknowledgement.into(), @@ -566,7 +628,7 @@ pub async fn parse_events( signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; messages.push(msg) }, diff --git a/hyperspace/core/src/lib.rs b/hyperspace/core/src/lib.rs index ff5adb5b6..22a0f7af6 100644 --- a/hyperspace/core/src/lib.rs +++ b/hyperspace/core/src/lib.rs @@ -30,6 +30,7 @@ use events::{has_packet_events, parse_events}; use futures::{future::ready, StreamExt, TryFutureExt}; use ibc::{events::IbcEvent, Height}; use ibc_proto::google::protobuf::Any; +use itertools::Itertools; use metrics::handler::MetricsHandler; use primitives::{Chain, IbcProvider, UndeliveredType, UpdateType}; use std::collections::HashSet; @@ -66,11 +67,13 @@ where tokio::select! { // new finality event from chain A result = chain_a_finality.next(), if !first_executed => { + log::info!("Got {} finality", chain_a.name()); first_executed = true; process_finality_event(&mut chain_a, &mut chain_b, &mut chain_a_metrics, mode, result, &mut chain_a_finality, &mut chain_b_finality).await?; } // new finality event from chain B result = chain_b_finality.next() => { + log::info!("Got {} finality", chain_b.name()); first_executed = false; process_finality_event(&mut chain_b, &mut chain_a, &mut chain_b_metrics, mode, result, &mut chain_b_finality, &mut chain_a_finality).await?; } @@ -153,7 +156,7 @@ async fn process_finality_event( match result { // stream closed None => { - log::warn!("Stream closed for {}", source.name()); + log::info!("Stream closed for {}", source.name()); *stream_source = loop { match source.finality_notifications().await { Ok(stream) => break RecentStream::new(stream), @@ -218,7 +221,7 @@ async fn process_some_finality_event( log::trace!(target: "hyperspace", "Received updates count: {}", updates.len()); // query packets that can now be sent, at this sink height because of connection // delay. - let (ready_packets, timeout_msgs) = + let (ready_packets, mut timeout_msgs) = packets::query_ready_and_timed_out_packets(&*source, &*sink) .await .map_err(|e| anyhow!("Failed to parse events: {:?}", e))?; @@ -247,11 +250,68 @@ async fn process_some_finality_event( timeout_msgs.len() ); - process_updates(source, sink, metrics, mode, updates, &mut msgs).await?; + process_updates(source, sink, metrics, mode, updates, &mut msgs, ready_packets.clone()).await?; msgs.extend(ready_packets); process_messages(sink, metrics, msgs).await?; + + if sink.name() == "solana" && timeout_msgs.len() > 0 { + log::info!("Inside timeout msgs fetching height"); + let mut timeout_heights = Vec::new(); + if timeout_msgs.len() > 0 { + for msg in timeout_msgs.iter() { + let my_message = ibc::core::ics26_routing::msgs::Ics26Envelope::< + primitives::mock::LocalClientTypes, + >::try_from(msg.clone()) + .unwrap(); + let timeout_msg = match my_message { + ibc::core::ics26_routing::msgs::Ics26Envelope::Ics4PacketMsg(packet_msg) => + match packet_msg { + ibc::core::ics04_channel::msgs::PacketMsg::ToPacket(msg) => msg, + _ => continue, + }, + _ => continue, + }; + timeout_heights.push(timeout_msg.proofs.height().revision_height); + } + loop { + let largest_height = timeout_heights.iter().max().unwrap(); + let latest_height_on_solana = sink.latest_height_and_timestamp().await.unwrap().0; + if latest_height_on_solana.revision_height >= *largest_height { + log::info!("Latest height is finalized"); + break + } + log::info!("Waiting for next block {:?} to be finalized", latest_height_on_solana); + core::time::Duration::from_secs(1); + } + let (updates, heights) = sink.fetch_mandatory_updates(source).await.unwrap(); + let updates_to_be_sent: Vec = heights + .iter() + .enumerate() + .filter_map(|(index, event)| { + let height = match event.clone() { + ibc::events::IbcEvent::NewBlock( + ibc::core::ics02_client::events::NewBlock { height }, + ) => height, + _ => panic!("Only expected new block event"), + }; + if timeout_heights.contains(&height.revision_height) { + return Some(updates[index].clone()) + } + None + }) + .collect(); + // Reverse the updates so that the latest update is sent at end + let mut reversed_updates = updates_to_be_sent.iter().rev().cloned().collect::>(); + reversed_updates + .iter() + .for_each(|update| timeout_msgs.insert(0, update.clone())); + // timeout_msgs = (reversed_updates.as_slice(), timeout_msgs.as_slice()).concat(); + // timeout_msgs.append(&mut reversed_updates); + } + } + process_timeouts(source, metrics, timeout_msgs).await?; Ok(()) } @@ -263,6 +323,7 @@ async fn process_updates( mode: Option, updates: Vec<(Any, Height, Vec, UpdateType)>, msgs: &mut Vec, + timeout_msgs: Vec, ) -> anyhow::Result<()> { // for timeouts we need both chains to be up to date let sink_has_undelivered_acks = sink.has_undelivered_sequences(UndeliveredType::Recvs) || @@ -277,6 +338,96 @@ async fn process_updates( HashSet::new() }; + log::info!("Updates on {} are {}", source.name(), updates.len()); + + let mut timeout_heights = Vec::new(); + let mut updates_to_be_added = Vec::new(); + if timeout_msgs.len() > 0 && source.name() == "solana" { + log::info!("Inside sending updates in fetching height"); + for msg in timeout_msgs.iter() { + let my_message = ibc::core::ics26_routing::msgs::Ics26Envelope::< + primitives::mock::LocalClientTypes, + >::try_from(msg.clone()) + .unwrap(); + let height = match my_message { + ibc::core::ics26_routing::msgs::Ics26Envelope::Ics4PacketMsg(packet_msg) => + match packet_msg { + ibc::core::ics04_channel::msgs::PacketMsg::ToPacket(msg) => + msg.proofs.height(), + ibc::core::ics04_channel::msgs::PacketMsg::AckPacket(msg) => + msg.proofs.height(), + ibc::core::ics04_channel::msgs::PacketMsg::RecvPacket(msg) => + msg.proofs.height(), + ibc::core::ics04_channel::msgs::PacketMsg::ToClosePacket(msg) => + msg.proofs.height(), + _ => continue, + }, + _ => continue, + }; + timeout_heights.push(height); + } + let latest_update_height = + updates.last().map_or(0, |(_, height, _, _)| height.revision_height); + let height_is_greater = timeout_heights + .iter() + .any(|height| height.revision_height > latest_update_height); + + if height_is_greater { + loop { + let largest_height = timeout_heights.iter().max().unwrap(); + let latest_height_on_solana = source.latest_height_and_timestamp().await.unwrap().0; + log::info!( + "This is the largest height {:?} {:?}", + largest_height, + latest_height_on_solana + ); + if latest_height_on_solana.revision_height > largest_height.revision_height { + log::info!("Latest height is finalized and sleeping for 5 seconds"); + std::thread::sleep(core::time::Duration::from_secs(5)); + break + } + log::info!("Waiting for next block {:?} to be finalized", latest_height_on_solana); + std::thread::sleep(core::time::Duration::from_secs(1)); + } + let (mandatory_updates, heights) = source.fetch_mandatory_updates(sink).await.unwrap(); + // log::info!("Height is greater than timeout height {:?}", ); + log::info!("These are heights {:?}", heights); + let updates_to_be_sent: Vec = heights + .iter() + .enumerate() + .filter_map(|(index, event)| { + let height = match event.clone() { + ibc::events::IbcEvent::NewBlock( + ibc::core::ics02_client::events::NewBlock { height }, + ) => height, + _ => panic!("Only expected new block event"), + }; + let temp_height = Height::new(1, height.revision_height); + if timeout_heights.contains(&temp_height) && + height.revision_height > latest_update_height + { + return Some(mandatory_updates[index].clone()) + } + None + }) + .collect(); + log::info!("Updates to be sent {:?}", updates_to_be_sent); + updates_to_be_added = updates_to_be_sent; + updates_to_be_added.reverse(); + } + } + log::info!( + "Update heights {:?} and timeout heights {:?}", + updates.iter().map(|(_, height, ..)| height).collect::>(), + timeout_heights + ); + + let update_max_height = updates + .iter() + .map(|(_, height, ..)| height.clone()) + .max() + .unwrap_or(Height::new(1, 0)); + for (msg_update_client, height, events, update_type) in updates { if let Some(metrics) = metrics.as_mut() { if let Err(e) = metrics.handle_events(events.as_slice()).await { @@ -284,11 +435,20 @@ async fn process_updates( } } + // println!("These are events {:?} from chain {:?}", events, source.name()); let event_types = events.iter().map(|ev| ev.event_type()).collect::>(); let mut messages = parse_events(source, sink, events, mode) .await .map_err(|e| anyhow!("Failed to parse events: {:?}", e))?; + // if let Some(index) = messages + // .iter() + // .position(|value| value.type_url == "/ibc.core.connection.v1.MsgConnectionOpenTry") + // { + // log::info!("Remvoign open try"); + // messages.swap_remove(index); + // } + log::trace!( target: "hyperspace", "Received messages count: {}, is the update optional: {}", @@ -301,6 +461,10 @@ async fn process_updates( let common_state = source.common_state(); let skip_optional_updates = common_state.skip_optional_client_updates; + // println!("These are messages len {}", messages.len()); + // println!("update type: {:?}, skip_optional_updates {:?}", update_type, + // skip_optional_updates); + // We want to send client update if packet messages exist but where not sent due // to a connection delay even if client update message is optional match ( @@ -310,7 +474,8 @@ async fn process_updates( // search, which won't work in this case skip_optional_updates && update_type.is_optional() && - !need_to_send_proofs_for_sequences, + !need_to_send_proofs_for_sequences && + !timeout_heights.contains(&height), has_packet_events(&event_types), messages.is_empty(), ) { @@ -321,15 +486,41 @@ async fn process_updates( }, (false, _, true) => if update_type.is_optional() && need_to_send_proofs_for_sequences { - log::info!("Sending an optional update because source ({}) chain has undelivered sequences", sink.name()); + log::info!("Sending an optional update because source ({}) chain has undelivered sequences at height{}", sink.name(), height.revision_height); } else { - log::info!("Sending mandatory client update message for {}", sink.name()) + log::info!( + "Sending mandatory client update message for {} at height {}", + sink.name(), + height.revision_height + ) }, - _ => log::info!("Received finalized events from: {} {event_types:#?}", source.name()), + _ => log::info!( + "Received finalized events from: {} at height {} {event_types:#?}", + source.name(), + height.revision_height + ), }; + log::info!( + "pushed msg update client for {} with msg {} of len {}", + source.name(), + msg_update_client.type_url, + msg_update_client.value.len() + ); + if (height.revision_height != update_max_height.revision_height && + messages.is_empty() && + update_type.is_optional()) + { + log::info!( + "Skipping update for {} at height {} because it is not the latest update", + source.name(), + height.revision_height + ); + continue + } msgs.push(msg_update_client); msgs.append(&mut messages); } + msgs.append(&mut updates_to_be_added); Ok(()) } @@ -342,12 +533,33 @@ async fn process_messages( if let Some(metrics) = metrics.as_ref() { metrics.handle_messages(msgs.as_slice()).await; } - let type_urls = msgs.iter().map(|msg| msg.type_url.as_str()).collect::>(); + let type_urls = msgs + .iter() + .filter_map(|msg| { + let type_url = msg.type_url.as_str(); + if type_url == "" { + return None + }; + Some(type_url) + }) + .collect::>(); log::info!("Submitting messages to {}: {type_urls:#?}", sink.name()); - queue::flush_message_batch(msgs, metrics.as_ref(), &*sink) - .await - .map_err(|e| anyhow!("Failed to submit messages: {:?}", e))?; + let filtered_msgs: Vec<_> = msgs + .iter() + .filter_map(|msg| { + if msg.type_url == "" { + return None + } + Some(msg.clone()) + }) + .collect(); + + if !filtered_msgs.is_empty() { + queue::flush_message_batch(filtered_msgs, metrics.as_ref(), &*sink) + .await + .map_err(|e| anyhow!("Failed to submit messages: {:?}", e))?; + } log::debug!(target: "hyperspace", "Successfully submitted messages to {}", sink.name()); } Ok(()) diff --git a/hyperspace/core/src/packets.rs b/hyperspace/core/src/packets.rs index 77f43ee9b..d04aadfa4 100644 --- a/hyperspace/core/src/packets.rs +++ b/hyperspace/core/src/packets.rs @@ -30,7 +30,6 @@ use crate::packets::utils::{ get_timeout_proof_height, verify_delay_passed, VerifyDelayOn, }; use ibc::{ - applications::transfer::packet::PacketData, core::{ ics02_client::client_state::ClientState as ClientStateT, ics03_connection::connection::ConnectionEnd, @@ -194,7 +193,7 @@ pub async fn query_ready_and_timed_out_packets( .take(max_packets_to_process) .collect::>(); - log::debug!(target: "hyperspace", "Found {} undelivered packets for {:?}/{:?} for {seqs:?}", seqs.len(), channel_id, port_id.clone()); + log::info!(target: "hyperspace", "Found {} undelivered packets for {:?}/{:?} for {seqs:?}", seqs.len(), channel_id, port_id.clone()); let mut send_packets = source.query_send_packets(channel_id, port_id.clone(), seqs).await?; log::trace!(target: "hyperspace", "SendPackets count before deduplication: {}", send_packets.len()); @@ -206,6 +205,7 @@ pub async fn query_ready_and_timed_out_packets( let sink = Arc::new(sink.clone()); let timeout_packets_count = Arc::new(AtomicUsize::new(0)); let send_packets_count = Arc::new(AtomicUsize::new(0)); + let acks_packets_count = Arc::new(AtomicUsize::new(0)); for send_packets in send_packets.chunks(PROCESS_PACKETS_BATCH_SIZE) { for send_packet in send_packets.iter().cloned() { let source_connection_end = source_connection_end.clone(); @@ -228,8 +228,12 @@ pub async fn query_ready_and_timed_out_packets( Error::Custom(format!("Packet height not found for packet {packet:?}")) })?; + log::info!("sink_height = {sink_height:?}, timeout_height = {:?}, timeout_timestamp = {}, seq = {}", packet.timeout_height, packet.timeout_timestamp, packet.sequence); + if packet.timed_out(&sink_timestamp, sink_height) { - timeout_packets_count.fetch_add(1, Ordering::SeqCst); + source.common_state().ignored_timeouted_sequences.lock().await.insert( + packet.sequence.0 + ); // so we know this packet has timed out on the sink, we need to find the maximum // consensus state height at which we can generate a non-membership proof of the // packet for the sink's client on the source. @@ -238,6 +242,7 @@ pub async fn query_ready_and_timed_out_packets( &**source, &**sink, source_height, + source_timestamp, sink_height, sink_timestamp, latest_sink_height_on_source, @@ -248,6 +253,7 @@ pub async fn query_ready_and_timed_out_packets( { proof_height } else { + timeout_packets_count.fetch_add(1, Ordering::SeqCst); log::trace!(target: "hyperspace", "Skipping packet as no timeout proof height could be found: {:?}", packet); return Ok(None) }; @@ -282,7 +288,7 @@ pub async fn query_ready_and_timed_out_packets( .await?; return Ok(Some(Left(msg))) } else { - log::trace!(target: "hyperspace", "The packet has not timed out yet: {:?}", packet); + log::info!(target: "hyperspace", "The packet has not timed out yet: {:?}", packet); } // If packet has not timed out but channel is closed on sink we skip @@ -303,19 +309,21 @@ pub async fn query_ready_and_timed_out_packets( // If sink does not have a client height that is equal to or greater than the packet // creation height, we can't send it yet, packet_info.height should represent the packet // creation height on source chain - if packet_height > latest_source_height_on_sink.revision_height { + if source.get_proof_height(Height::new(source_height.revision_number, packet_height)).await.revision_height > latest_source_height_on_sink.revision_height { // Sink does not have client update required to prove recv packet message - log::debug!(target: "hyperspace", "Skipping packet {:?} as sink does not have client update required to prove recv packet message", packet); + log::info!(target: "hyperspace", "Skipping packet as sink does not have client update required to prove recv packet message: {:?}", packet); recv_packets_count.fetch_add(1, Ordering::SeqCst); return Ok(None) } + let start_height = Height::new(latest_source_height_on_sink.revision_number, packet_height); let proof_height = if let Some(proof_height) = find_suitable_proof_height_for_client( &**source, &**sink, sink_height, source.client_id(), - Height::new(latest_source_height_on_sink.revision_number, packet_height), + start_height, + Some(start_height), None, latest_source_height_on_sink, ) @@ -323,7 +331,7 @@ pub async fn query_ready_and_timed_out_packets( { proof_height } else { - log::trace!(target: "hyperspace", "Skipping packet {:?} as no proof height could be found", packet); + log::info!(target: "hyperspace", "Skipping packet as no proof height could be found: {:?}", packet); return Ok(None) }; @@ -340,7 +348,7 @@ pub async fn query_ready_and_timed_out_packets( ) .await? { - log::trace!(target: "hyperspace", "Skipping packet as connection delay has not passed {:?}", packet); + log::info!(target: "hyperspace", "Skipping packet as connection delay has not passed {:?}", packet); return Ok(None) } @@ -349,22 +357,9 @@ pub async fn query_ready_and_timed_out_packets( return Ok(None) } - let list = &source.common_state().skip_tokens_list; - - let decoded_dara: PacketData = serde_json::from_str(&String::from_utf8_lossy(packet.data.as_ref())).map_err(|e| { - Error::Custom(format!( - "Failed to decode packet data for packet {:?}: {:?}", - packet, e - )) - })?; - - if list.iter().any(|skiped_denom| decoded_dara.token.denom.base_denom.as_str() == skiped_denom) { - log::info!(target: "hyperspace", "Skipping packet with ignored token: {:?}", packet); - return Ok(None) - } - let msg = construct_recv_message(&**source, &**sink, packet, proof_height).await?; Ok(Some(Right(msg))) + // return Ok(None) }); } } @@ -411,8 +406,7 @@ pub async fn query_ready_and_timed_out_packets( source.query_received_packets(channel_id, port_id.clone(), acks).await?; log::trace!(target: "hyperspace", "Got acknowledgements for channel {:?}: {:?}", channel_id, acknowledgements); let mut acknowledgements_join_set: JoinSet> = JoinSet::new(); - sink.on_undelivered_sequences(!acknowledgements.is_empty(), UndeliveredType::Acks) - .await; + for acknowledgements in acknowledgements.chunks(PROCESS_PACKETS_BATCH_SIZE) { for acknowledgement in acknowledgements.iter().cloned() { let source_connection_end = source_connection_end.clone(); @@ -421,6 +415,7 @@ pub async fn query_ready_and_timed_out_packets( let duration1 = Duration::from_millis( rand::thread_rng().gen_range(1..source.rpc_call_delay().as_millis() as u64), ); + let acks_packets_count = acks_packets_count.clone(); acknowledgements_join_set.spawn(async move { sleep(duration1).await; let source = &source; @@ -441,30 +436,33 @@ pub async fn query_ready_and_timed_out_packets( let ack_height = acknowledgement.height.ok_or_else(|| { Error::Custom(format!("Packet height not found for packet {packet:?}")) })?; - if ack_height > latest_source_height_on_sink.revision_height { + + if source.get_proof_height(Height::new(source_height.revision_number, ack_height)).await.revision_height > latest_source_height_on_sink.revision_height { // Sink does not have client update required to prove acknowledgement packet message - log::trace!(target: "hyperspace", "Skipping acknowledgement for packet {:?} as sink does not have client update required to prove acknowledgement packet message", packet); + log::info!(target: "hyperspace", "Skipping acknowledgement for packet {:?} as sink does not have client update required to prove acknowledgement packet message", packet); + acks_packets_count.fetch_add(1, Ordering::SeqCst); return Ok(None) } - log::trace!(target: "hyperspace", "sink_height: {:?}, latest_source_height_on_sink: {:?}, acknowledgement.height: {}", sink_height, latest_source_height_on_sink, ack_height); + log::info!(target: "hyperspace", "sink_height: {:?}, latest_source_height_on_sink: {:?}, acknowledgement.height: {}", sink_height, latest_source_height_on_sink, ack_height); + let start_height = Height::new(latest_source_height_on_sink.revision_number, ack_height); let proof_height = if let Some(proof_height) = find_suitable_proof_height_for_client( &**source, &**sink, sink_height, source.client_id(), - Height::new(latest_source_height_on_sink.revision_number, ack_height), + start_height, + Some(start_height), None, latest_source_height_on_sink, ) .await { - log::trace!(target: "hyperspace", "Using proof height: {}", proof_height); + log::info!(target: "hyperspace", "Using proof height: {}", proof_height); proof_height } else { - log::trace!(target: "hyperspace", "Skipping acknowledgement for packet {:?} as no proof height could be found", packet); - return Ok(None) + log::info!(target: "hyperspace", "Skipping acknowledgement for packet {:?} as no proof height could be found", packet); return Ok(None) }; if !verify_delay_passed( @@ -480,7 +478,7 @@ pub async fn query_ready_and_timed_out_packets( ) .await? { - log::trace!(target: "hyperspace", "Skipping acknowledgement for packet as connection delay has not passed {:?}", packet); + log::info!(target: "hyperspace", "Skipping acknowledgement for packet as connection delay has not passed {:?}", packet); return Ok(None) } @@ -494,6 +492,12 @@ pub async fn query_ready_and_timed_out_packets( let Some(msg) = result?? else { continue }; messages.push(msg) } + + sink.on_undelivered_sequences( + acks_packets_count.load(Ordering::SeqCst) != 0, + UndeliveredType::Acks, + ) + .await; } Ok((messages, timeout_messages)) diff --git a/hyperspace/core/src/packets/connection_delay.rs b/hyperspace/core/src/packets/connection_delay.rs index cd472be42..4af1dab23 100644 --- a/hyperspace/core/src/packets/connection_delay.rs +++ b/hyperspace/core/src/packets/connection_delay.rs @@ -25,7 +25,7 @@ pub fn has_delay_elapsed( delay_period_time: Duration, delay_period_blocks: u64, ) -> Result { - log::trace!(target: "hyperspace", + log::info!(target: "hyperspace", "Checking if delay has elapsed: current_time: {}, current_height: {}, client_update_time: {}, client_update_height: {}, delay_period_time: {:?}, delay_period_blocks: {}", current_time, current_height, client_update_time, client_update_height, delay_period_time, delay_period_blocks ); diff --git a/hyperspace/core/src/packets/utils.rs b/hyperspace/core/src/packets/utils.rs index 47ff0113a..62bc7f838 100644 --- a/hyperspace/core/src/packets/utils.rs +++ b/hyperspace/core/src/packets/utils.rs @@ -15,7 +15,6 @@ use crate::packets::connection_delay::has_delay_elapsed; use ibc::{ core::{ - ics02_client::client_state::ClientState as ClientStateT, ics04_channel::{ channel::{ChannelEnd, Order, State}, context::calculate_block_delay, @@ -36,9 +35,10 @@ use ibc::{ Height, }; use ibc_proto::google::protobuf::Any; +use lib::hash::CryptoHash; use pallet_ibc::light_clients::AnyClientState; use primitives::{find_suitable_proof_height_for_client, Chain}; -use std::time::Duration; +use std::{str::FromStr, time::Duration}; use tendermint_proto::Protobuf; #[allow(clippy::too_many_arguments)] @@ -46,6 +46,7 @@ pub async fn get_timeout_proof_height( source: &impl Chain, sink: &impl Chain, source_height: Height, + source_timestamp: Timestamp, sink_height: Height, sink_timestamp: Timestamp, latest_client_height_on_source: Height, @@ -57,48 +58,70 @@ pub async fn get_timeout_proof_height( source.name(), sink.name(), timeout_variant, source_height, sink_height, sink_timestamp, latest_client_height_on_source, packet_creation_height, packet); match timeout_variant { - TimeoutVariant::Height => + TimeoutVariant::Height => { + let start_height = packet.timeout_height; find_suitable_proof_height_for_client( sink, source, source_height, sink.client_id(), - packet.timeout_height, + start_height, + Some(start_height), None, latest_client_height_on_source, ) - .await, + .await + }, TimeoutVariant::Timestamp => { // Get approximate number of blocks contained in this timestamp so we can have a lower // bound for where to start our search // We offset the sink height when this packet was created with the approximate number of // blocks contained in the difference in timestamp at packet creation until timeout - let height = Height::new(source_height.revision_number, packet_creation_height); - log::trace!( - target: "hyperspace", - "Querying client state at {height}" + + /* + 1. Calculate packet creation time on A. + 2. Calculate time difference between the current time and the packet creation time (dTa) + 3. Calculate the number of blocks contained in dTb (nTb) + 4. Calculate the height of the packet on B (Hb) by subtracting nTb from the current height of B (Tb = Hb - nTb) + 5. Calculate timeout block on B (TOb) by adding the timeout duration (dTO) in B blocks to Hb + */ + + let timeout_ns = packet.timeout_timestamp.nanoseconds(); + let sink_ns = sink_timestamp.nanoseconds(); + if timeout_ns > sink_ns { + return None + } + + let packet_lifetime_blocks_on_a = + source_height.revision_height.saturating_sub(packet_creation_height); + let packet_timestamp = (source_timestamp - + source.expected_block_time() * packet_lifetime_blocks_on_a as u32) + .ok()?; + let timeout_timestamp_relative = Duration::from_nanos( + packet + .timeout_timestamp + .nanoseconds() + .saturating_sub(packet_timestamp.nanoseconds()), ); - let sink_client_state = - source.query_client_state(height, sink.client_id()).await.ok()?; - let sink_client_state = - AnyClientState::try_from(sink_client_state.client_state?).ok()?; - let height = sink_client_state.latest_height(); - let timestamp_at_creation = - sink.query_timestamp_at(height.revision_height).await.ok()?; - // may underflow if the user have chosen timeout less than the block timestamp at which - // the packet was created, so we use `saturating_sub` - let period = - packet.timeout_timestamp.nanoseconds().saturating_sub(timestamp_at_creation); - let period = Duration::from_nanos(period); - let start_height = height.revision_height + - calculate_block_delay(period, sink.expected_block_time()).saturating_sub(1); - let start_height = Height::new(sink_height.revision_number, start_height); + let packet_lifetime_timestamp = + source.expected_block_time() * (packet_lifetime_blocks_on_a as u32); + let packet_lifetime_blocks_on_b = (packet_lifetime_timestamp.as_nanos() / + sink.expected_block_time().as_nanos()) as u64; + let packet_height_on_b = + sink_height.revision_height.saturating_sub(packet_lifetime_blocks_on_b); + let timeout_block_on_b = (packet_height_on_b + + (timeout_timestamp_relative.as_nanos() / sink.expected_block_time().as_nanos()) + as u64) + .saturating_sub(1); + + let start_height = Height::new(sink_height.revision_number, timeout_block_on_b); find_suitable_proof_height_for_client( sink, source, source_height, sink.client_id(), start_height, + None, Some(packet.timeout_timestamp), latest_client_height_on_source, ) @@ -107,36 +130,43 @@ pub async fn get_timeout_proof_height( TimeoutVariant::Both => { // Get approximate number of blocks contained in this timestamp so we can have a lower // bound for where to start our search - let sink_client_state = source - .query_client_state( - Height::new(source_height.revision_number, packet_creation_height), - sink.client_id(), - ) - .await + let timeout_ns = packet.timeout_timestamp.nanoseconds(); + let sink_ns = sink_timestamp.nanoseconds(); + if timeout_ns > sink_ns { + return None + } + + let packet_lifetime_blocks_on_a = + source_height.revision_height.saturating_sub(packet_creation_height); + let packet_timestamp = (source_timestamp - + source.expected_block_time() * packet_lifetime_blocks_on_a as u32) .ok()?; - let sink_client_state = - AnyClientState::try_from(sink_client_state.client_state?).ok()?; - let height = sink_client_state.latest_height(); - let timestamp_at_creation = - sink.query_timestamp_at(height.revision_height).await.ok()?; - // may underflow if the user have chosen timeout less than the block timestamp at which - // the packet was created, so we use `saturating_sub` - let period = - packet.timeout_timestamp.nanoseconds().saturating_sub(timestamp_at_creation); - let period = Duration::from_nanos(period); - let start_height = height.revision_height + - calculate_block_delay(period, sink.expected_block_time()).saturating_sub(1); - let start_height = if start_height < packet.timeout_height.revision_height { - packet.timeout_height - } else { - Height::new(packet.timeout_height.revision_number, start_height) - }; + let timeout_timestamp_relative = Duration::from_nanos( + packet + .timeout_timestamp + .nanoseconds() + .saturating_sub(packet_timestamp.nanoseconds()), + ); + let packet_lifetime_timestamp = + source.expected_block_time() * (packet_lifetime_blocks_on_a as u32); + let packet_lifetime_blocks_on_b = (packet_lifetime_timestamp.as_nanos() / + sink.expected_block_time().as_nanos()) as u64; + let packet_height_on_b = + sink_height.revision_height.saturating_sub(packet_lifetime_blocks_on_b); + let timeout_block_on_b = (packet_height_on_b + + (timeout_timestamp_relative.as_nanos() / sink.expected_block_time().as_nanos()) + as u64) + .saturating_sub(1); + let start_height = Height::new(sink_height.revision_number, timeout_block_on_b) + .min(packet.timeout_height); + find_suitable_proof_height_for_client( sink, source, source_height, sink.client_id(), start_height, + Some(packet.timeout_height), Some(packet.timeout_timestamp), latest_client_height_on_source, ) @@ -236,6 +266,8 @@ pub async fn construct_timeout_message( next_sequence_recv: u64, proof_height: Height, ) -> Result { + log::trace!(target: "hyperspace", "construct_timeout_message: source: {}, sink: {}, sink_channel_end: {:?}, packet: {:?}, next_sequence_recv: {}, proof_height: {}, data: {}", + source.name(), sink.name(), sink_channel_end, packet, next_sequence_recv, proof_height, String::from_utf8_lossy(&packet.data)); let path_type = if sink_channel_end.ordering == Order::Ordered { KeyPathType::SeqRecv } else { @@ -245,11 +277,20 @@ pub async fn construct_timeout_message( let proof_unreceived = sink.query_proof(proof_height, vec![key]).await?; let proof_unreceived = CommitmentProofBytes::try_from(proof_unreceived)?; + let actual_proof_height = if sink.name() == "solana" { + log::info!("Getting proof height from solana"); + let mut proof_bytes = proof_unreceived.clone(); + let (header, _): (guestchain::BlockHeader, sealable_trie::proof::Proof) = + borsh::BorshDeserialize::deserialize_reader(&mut proof_bytes.as_bytes())?; + Height::new(1, header.block_height.into()) + } else { + log::info!("Getting proof height from cosmos"); + sink.get_proof_height(proof_height).await + }; let msg = if sink_channel_end.state == State::Closed { let channel_key = get_key_path(KeyPathType::ChannelPath, &packet).into_bytes(); let proof_closed = sink.query_proof(proof_height, vec![channel_key]).await?; let proof_closed = CommitmentProofBytes::try_from(proof_closed)?; - let actual_proof_height = sink.get_proof_height(proof_height).await; let msg = MsgTimeoutOnClose { packet, next_sequence_recv: next_sequence_recv.into(), @@ -262,10 +303,9 @@ pub async fn construct_timeout_message( )?, signer: source.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); Any { value, type_url: msg.type_url() } } else { - let actual_proof_height = sink.get_proof_height(proof_height).await; log::debug!(target: "hyperspace", "actual_proof_height={actual_proof_height}"); let msg = MsgTimeout { packet, @@ -273,7 +313,7 @@ pub async fn construct_timeout_message( proofs: Proofs::new(proof_unreceived, None, None, None, actual_proof_height)?, signer: source.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); Any { value, type_url: msg.type_url() } }; Ok(msg) @@ -288,13 +328,22 @@ pub async fn construct_recv_message( let key = get_key_path(KeyPathType::CommitmentPath, &packet).into_bytes(); let proof = source.query_proof(proof_height, vec![key]).await?; let commitment_proof = CommitmentProofBytes::try_from(proof)?; - let actual_proof_height = source.get_proof_height(proof_height).await; + let actual_proof_height = if source.name() == "solana" { + log::info!("Getting proof height from solana"); + let mut proof_bytes = commitment_proof.clone(); + let (header, _): (guestchain::BlockHeader, sealable_trie::proof::Proof) = + borsh::BorshDeserialize::deserialize_reader(&mut proof_bytes.as_bytes())?; + Height::new(1, header.block_height.into()) + } else { + log::info!("Getting proof height from cosmos"); + source.get_proof_height(proof_height).await + }; let msg = MsgRecvPacket { packet, proofs: Proofs::new(commitment_proof, None, None, None, actual_proof_height)?, signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; Ok(msg) } @@ -310,14 +359,25 @@ pub async fn construct_ack_message( log::debug!(target: "hyperspace", "query proof for acks path: {:?}", key); let proof = source.query_proof(proof_height, vec![key.into_bytes()]).await?; let commitment_proof = CommitmentProofBytes::try_from(proof)?; - let actual_proof_height = source.get_proof_height(proof_height).await; + let actual_proof_height = if source.name() == "solana" { + log::info!("Getting proof height from solana"); + let mut proof_bytes = commitment_proof.clone(); + let (header, _): (guestchain::BlockHeader, sealable_trie::proof::Proof) = + borsh::BorshDeserialize::deserialize_reader(&mut proof_bytes.as_bytes())?; + Height::new(1, header.block_height.into()) + } else { + log::info!("Getting proof height from cosmos"); + source.get_proof_height(proof_height).await + }; + + log::info!("This is ack {:?}", CryptoHash::digest(&ack)); let msg = MsgAcknowledgement { packet, proofs: Proofs::new(commitment_proof, None, None, None, actual_proof_height)?, acknowledgement: ack.into(), signer: sink.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); let msg = Any { value, type_url: msg.type_url() }; Ok(msg) } diff --git a/hyperspace/cosmos/Cargo.toml b/hyperspace/cosmos/Cargo.toml index 43d3a941b..444dc509d 100644 --- a/hyperspace/cosmos/Cargo.toml +++ b/hyperspace/cosmos/Cargo.toml @@ -47,21 +47,21 @@ pallet-ibc = { path = "../../contracts/pallet-ibc" } tracing = "0.1.36" # tendermint -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false, features = [ +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false, features = [ "secp256k1", ] } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false, features = [ +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false, features = [ "http-client", "websocket-client", ] } -tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false, features = [ +tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false, features = [ "rpc-client", "secp256k1", "unstable", # "testing" ] } -tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [features] testing = [ diff --git a/hyperspace/cosmos/src/chain.rs b/hyperspace/cosmos/src/chain.rs index 34e2498f9..ab2f08856 100644 --- a/hyperspace/cosmos/src/chain.rs +++ b/hyperspace/cosmos/src/chain.rs @@ -132,6 +132,7 @@ where } async fn submit(&self, messages: Vec) -> Result { + log::info!("This is the submitted message {:?}", messages[0].type_url); let hash = self.submit_call(messages).await?; log::debug!(target: "hyperspace_cosmos", "Submitted. Tx hash: {}", hash); Ok(Self::TransactionId { hash }) diff --git a/hyperspace/cosmos/src/client.rs b/hyperspace/cosmos/src/client.rs index e78608c6a..b151b340c 100644 --- a/hyperspace/cosmos/src/client.rs +++ b/hyperspace/cosmos/src/client.rs @@ -38,7 +38,7 @@ use std::{ collections::HashSet, str::FromStr, sync::{Arc, Mutex}, - time::Duration, + time::{Duration, SystemTime}, }; use tendermint::{block::Height as TmHeight, Hash}; use tendermint_light_client::components::io::{AtHeight, Io}; @@ -51,7 +51,7 @@ use tokio::{ }; const DEFAULT_FEE_DENOM: &str = "stake"; -const DEFAULT_FEE_AMOUNT: &str = "4000"; +const DEFAULT_FEE_AMOUNT: &str = "400000000000000000"; const DEFAULT_GAS_LIMIT: u64 = (i64::MAX - 1) as u64; fn default_gas_limit() -> u64 { @@ -275,7 +275,7 @@ where }) .map_err(|e| e.to_string())?; - let rpc_call_delay = Duration::from_millis(1000); + let rpc_call_delay = Duration::from_millis(50); Ok(Self { name: config.name, chain_id, @@ -306,7 +306,11 @@ where initial_rpc_call_delay: rpc_call_delay, misbehaviour_client_msg_queue: Arc::new(AsyncMutex::new(vec![])), max_packets_to_process: config.common.max_packets_to_process as usize, - skip_tokens_list: config.skip_tokens_list.unwrap_or_default(), + // skip_tokens_list: config.skip_tokens_list.unwrap_or_default(), + ignored_timeouted_sequences: Arc::new(AsyncMutex::new(HashSet::new())), + client_update_interval: Duration::from_secs(1), + last_client_update_time: SystemTime::now(), + handshake_completed: false, }, join_handles: Arc::new(TokioMutex::new(vec![ws_driver_jh])), }) @@ -365,17 +369,21 @@ where self.get_fee(), )?; + log::info!("i came here 1"); + // Simulate transaction let res = simulate_tx(self.grpc_url.clone(), tx, tx_bytes.clone()).await?; res.result - .map(|r| log::debug!(target: "hyperspace_cosmos", "Simulated transaction: events: {:?}\nlogs: {}", r.events, r.log)); + .map(|r| log::info!(target: "hyperspace_cosmos", "Simulated transaction: events: {:?}\nlogs: {}", r.events, r.log)); + log::info!("i came here 2"); // Broadcast transaction let hash = broadcast_tx(&self.rpc_client, tx_bytes).await?; - log::debug!(target: "hyperspace_cosmos", "🤝 Transaction sent with hash: {:?}", hash); + log::info!(target: "hyperspace_cosmos", "🤝 Transaction sent with hash: {:?}", hash); // wait for confirmation confirm_tx(&self.rpc_client, hash).await + // Ok(hash) } pub async fn fetch_light_block_with_cache( @@ -385,12 +393,14 @@ where ) -> Result { let fut = async move { sleep(sleep_duration).await; - self.light_client.io.fetch_light_block(AtHeight::At(height)).map_err(|e| { - Error::from(format!( - "Failed to fetch light block for chain {:?} with error {:?}", - self.name, e - )) - }) + self.fetch_light_block(AtHeight::At(height), self.light_client.peer_id.clone()) + .await + .map_err(|e| { + Error::from(format!( + "Failed to fetch light block for chain {:?} with error {:?}", + self.name, e + )) + }) }; self.light_block_cache.get_or_insert_async(&height, fut).await } @@ -406,7 +416,7 @@ where let heightss = (from.value()..=to.value()).collect::>(); let client = Arc::new(self.clone()); let delay_to = self.rpc_call_delay().as_millis(); - for heights in heightss.chunks(5) { + for heights in heightss.chunks(100) { let mut join_set = JoinSet::, Elapsed>>::new(); for height in heights.to_owned() { let client = client.clone(); @@ -509,7 +519,7 @@ where return Err(Error::from(format!( "Query failed with code {:?} and log {:?}", response.code, response.log - ))) + ))); } if prove && response.proof.is_none() { @@ -517,7 +527,7 @@ where return Err(Error::from(format!( "Query failed due to empty proof for chain {}", self.name - ))) + ))); } let merkle_proof = response diff --git a/hyperspace/cosmos/src/events.rs b/hyperspace/cosmos/src/events.rs index b4e71ef8a..ac2ed06f7 100644 --- a/hyperspace/cosmos/src/events.rs +++ b/hyperspace/cosmos/src/events.rs @@ -19,6 +19,7 @@ use ibc::{ events::{self as channel_events, Attributes as ChannelAttributes}, packet::Packet, }, + ics24_host::identifier::ClientId, }, events::{Error as IbcEventError, IbcEvent, IbcEventType}, protobuf::Protobuf, @@ -103,8 +104,14 @@ pub fn ibc_event_try_from_abci_event( Ok(IbcEventType::CreateClient) => Ok(IbcEvent::CreateClient( create_client_try_from_abci_event(abci_event, height).map_err(IbcEventError::client)?, )), - Ok(IbcEventType::UpdateClient) => Ok(IbcEvent::UpdateClient( - update_client_try_from_abci_event(abci_event, height).map_err(IbcEventError::client)?, + Ok(IbcEventType::UpdateClient) => + return Ok(IbcEvent::UpdateClient( + update_client_try_from_abci_event(abci_event, height) + .map_err(IbcEventError::client)?, + )), + Ok(IbcEventType::UpdateClientProposal) => Ok(IbcEvent::UpdateClientProposal( + update_client_proposal_try_from_abci_event(abci_event, height) + .map_err(IbcEventError::client)?, )), Ok(IbcEventType::UpgradeClient) => Ok(IbcEvent::UpgradeClient( upgrade_client_try_from_abci_event(abci_event, height) @@ -187,13 +194,30 @@ pub fn update_client_try_from_abci_event( client_extract_attributes_from_tx(abci_event, height).map(|attributes| { client_events::UpdateClient { common: attributes, - header: extract_header_from_tx(abci_event) - .ok() - .map(|h| h.encode_vec().expect("header should encode")), + header: extract_header_from_tx(abci_event).ok().map(|h| h.encode_vec()), } }) } +pub fn update_client_proposal_try_from_abci_event( + abci_event: &AbciEvent, + _height: Height, +) -> Result { + let mut client_id = ClientId::default(); + let mut client_type = String::default(); + for tag in &abci_event.attributes { + let key = tag.key.as_str(); + let value = tag.value.as_str(); + match key { + client_events::SUBJECT_CLIENT_ID_ATTRIBUTE_KEY => + client_id = value.parse().map_err(ClientError::invalid_client_identifier)?, + client_events::CLIENT_TYPE_ATTRIBUTE_KEY => client_type = value.to_owned(), + _ => {}, + } + } + Ok(client_events::UpdateClientProposal { client_id, client_type }) +} + pub fn upgrade_client_try_from_abci_event( abci_event: &AbciEvent, height: Height, @@ -391,10 +415,18 @@ pub fn client_extract_attributes_from_tx( attr.client_type = value .parse() .map_err(|_| ClientError::unknown_client_type(value.to_string()))?, - client_events::CONSENSUS_HEIGHT_ATTRIBUTE_KEY => - attr.consensus_height = value + client_events::CONSENSUS_HEIGHT_ATTRIBUTE_KEY => { + let r = value .parse() - .map_err(|e| ClientError::invalid_string_as_height(value.to_string(), e))?, + .map_err(|e| ClientError::invalid_string_as_height(value.to_string(), e)); + match r { + Ok(r) => attr.consensus_height = r, + Err(e) => { + //skip error. This is a workaround for the fact that the height is not + // always present in the event and is just a empty string + }, + } + }, client_events::HEIGHT_ATTRIBUTE_KEY => attr.height = value.parse().map_err(|e| { ClientError::invalid_string_as_height( diff --git a/hyperspace/cosmos/src/light_client.rs b/hyperspace/cosmos/src/light_client.rs index 539857272..496441e30 100644 --- a/hyperspace/cosmos/src/light_client.rs +++ b/hyperspace/cosmos/src/light_client.rs @@ -63,10 +63,12 @@ impl LightClient { TMHeight::try_from(trusted.revision_height).map_err(|e| Error::from(e.to_string()))?; use tendermint_light_client::components::io::Io; + println!("Inside prepare state 1 {}", trusted_height); let trusted_block = self .io .fetch_light_block(AtHeight::At(trusted_height)) .map_err(|e| Error::from(e.to_string()))?; + println!("Inside prepare state 2"); let mut store = MemoryStore::new(); store.insert(trusted_block, Status::Trusted); Ok(LightClientState::new(store)) @@ -79,12 +81,16 @@ impl LightClient { target: Height, client_state: &ClientState, ) -> Result { + println!("Inside verify 1"); let target_height = TMHeight::try_from(target.revision_height).map_err(|e| Error::from(e.to_string()))?; + println!("Inside verify 2"); let client = self.prepare_tendermint_light_client(client_state)?; + println!("Inside verify 3"); let mut state = self.prepare_state(trusted)?; + println!("Inside verify 4"); // Verify the target header let target = client .verify_to_target(target_height, &mut state) diff --git a/hyperspace/cosmos/src/provider.rs b/hyperspace/cosmos/src/provider.rs index 0499457e0..0184e990f 100644 --- a/hyperspace/cosmos/src/provider.rs +++ b/hyperspace/cosmos/src/provider.rs @@ -83,9 +83,17 @@ use tendermint_rpc::{ }; use tokio::{task::JoinSet, time::sleep}; +use tendermint::{ + account::Id as TMAccountId, block::signed_header::SignedHeader, + validator::Set as TMValidatorSet, +}; +use tendermint_light_client::components::io::{AtHeight, IoError}; +use tendermint_light_client_verifier::types::{LightBlock, PeerId}; +use tendermint_rpc::Paging; + // At least one *mandatory* update should happen during that period // TODO: make it configurable -pub const NUMBER_OF_BLOCKS_TO_PROCESS_PER_ITER: u64 = 500; +// pub const NUMBER_OF_BLOCKS_TO_PROCESS_PER_ITER: u64 = 500; #[derive(Clone, Debug)] pub enum FinalityEvent { @@ -115,34 +123,78 @@ where where C: Chain, { + log::info!("Fetching latest cosmos ibc events"); let finality_event_height = match finality_event { FinalityEvent::Tendermint { from: _, to } => to, }; let client_id = self.client_id(); - let latest_cp_height = counterparty.latest_height_and_timestamp().await?.0; + let (latest_cp_height, latest_cp_time) = counterparty.latest_height_and_timestamp().await?; let latest_cp_client_state = counterparty.query_client_state(latest_cp_height, client_id.clone()).await?; let client_state_response = latest_cp_client_state .client_state .ok_or_else(|| Error::Custom("counterparty returned empty client state".to_string()))?; let client_state = - ClientState::::decode_vec(&client_state_response.value) - .map_err(|_| Error::Custom("failed to decode client state response".to_string()))?; + ics07_tendermint::client_state::ClientState::::decode_vec( + &client_state_response.value, + ) + .map_err(|_| Error::Custom("failed to decode client state response".to_string()))?; let latest_cp_client_height = client_state.latest_height().revision_height; + log::info!( + "This is solana (cp) height on cosmos {:?} {:?}", + client_state.latest_height(), + client_state.chain_id() + ); let latest_height = self.latest_height_and_timestamp().await?.0; let latest_revision = latest_height.revision_number; + let trusted_latest_h = client_state.latest_height(); + + // let (_, last_update_time) = counterparty + // .query_client_update_time_and_height(client_id.clone(), trusted_latest_h) + // .await?; + let from = TmHeight::try_from(latest_cp_client_height).unwrap(); - let to = finality_event_height.min( - TmHeight::try_from(latest_cp_client_height + NUMBER_OF_BLOCKS_TO_PROCESS_PER_ITER) - .expect("should not overflow"), + let to = finality_event_height; + log::info!(target: "hyperspace_cosmos", "--------------------------Getting blocks {}..{}----------------------", from, to); + + // let time_passed_since_last_update = + // latest_cp_time.duration_since(&last_update_time).unwrap_or_else(|| { log::warn!(target: + // "hyperspace_cosmos", "Last update time {last_update_time} > {latest_cp_time} (current + // time on the counterparty chain)", ); Duration::from_secs(0) + // }); + log::info!("Latest height {:?} and trusted height {:?}", latest_height, trusted_latest_h); + let time_passed_since_last_update = Duration::from_secs( + (latest_height.revision_height - trusted_latest_h.revision_height) * + self.expected_block_time().as_secs(), + ); + log::info!( + "Time passed since last update on cosmos {:?}", + time_passed_since_last_update.as_secs() ); - log::info!(target: "hyperspace_cosmos", "Getting blocks {}..{}", from, to); + let mut force_update_at = None; + // Force update if the finality event height is reached and the client was not + // updated for the trusting period / 2 to avoid client expiration + if time_passed_since_last_update > Duration::from_secs(30 * 60) { + // This fixation on the block is needed to wait for the proof for the same block + // in the next iterations, instead of requesting a new proof for another block + // and never using it + let fixed_update_height = finality_event_height.value(); + + log::debug!(target: "hyperspace_cosmos", "Time passed since last update: {}, trusting period: {}", time_passed_since_last_update.as_secs(), client_state.trusting_period.as_secs()); + + force_update_at = Some(Height::new(latest_height.revision_number, fixed_update_height)); + } + + if let Some(height) = force_update_at { + log::info!(target: "hyperspace_cosmos", "Forcing update at height: {height}"); + } // query (exclusively) up to `to`, because the proof for the event at `to - 1` will be // contained at `to` and will be fetched below by `msg_update_client_header` let update_headers = - self.msg_update_client_header(from, to, client_state.latest_height).await?; + self.msg_update_client_header(from, to, client_state.latest_height()).await?; + // log::info!(target: "hyperspace_cosmos", "These are update headers {:?}", update_headers); let mut block_events = Vec::new(); let mut join_set: JoinSet> = JoinSet::new(); let range = (from.value()..to.value()).collect::>(); @@ -185,9 +237,9 @@ where .zip(update_headers) .enumerate() { - if i == NUMBER_OF_BLOCKS_TO_PROCESS_PER_ITER as usize - 1 { - update_type = UpdateType::Mandatory; - } + // if i == NUMBER_OF_BLOCKS_TO_PROCESS_PER_ITER as usize - 1 { + // update_type = UpdateType::Mandatory; + // } let height = update_header.height(); let update_client_header = { let msg = MsgUpdateAnyClient:: { @@ -197,11 +249,16 @@ where )), signer: counterparty.account_id(), }; - let value = msg.encode_vec().map_err(|e| { - Error::from(format!("Failed to encode MsgUpdateClient {msg:?}: {e:?}")) - })?; + let value = msg.clone().encode_vec(); Any { value, type_url: msg.type_url() } }; + + if Some(height) == force_update_at { + update_type = UpdateType::Mandatory; + log::info!(target: "hyperspace_cosmos", "Forcing update to mandatory at height: {:?}", height); + } + + // println!("These are events caught query latest events {:?}", events); updates.push((update_client_header, height, events, update_type)); } Ok(updates) @@ -212,6 +269,7 @@ where async fn ibc_events(&self) -> Pin + Send + 'static>> { // Create websocket client. Like what `EventMonitor::subscribe()` does in `hermes` let ws_client = self.rpc_client.clone(); + log::info!("Inside cosmos ibc events"); let query_all = vec![ Query::from(EventType::NewBlock), @@ -667,7 +725,7 @@ where port_id: PortId, seqs: Vec, ) -> Result, Self::Error> { - log::debug!( + log::info!( target: "hyperspace_cosmos", "query_send_packets: channel_id: {}, port_id: {}, seqs: {:?}", channel_id, port_id, seqs ); @@ -1065,12 +1123,13 @@ where &self, ) -> Result<(AnyClientState, AnyConsensusState), Self::Error> { let latest_height_timestamp = self.latest_height_and_timestamp().await?; + println!("This is height on cosmos {:?}", latest_height_timestamp); let client_state = ClientState::new( self.chain_id.clone(), TrustThreshold::default(), - Duration::from_secs(64000), + Duration::from_secs(640000), Duration::from_secs(1814400), - Duration::new(15, 0), + Duration::new(1500000, 0), latest_height_timestamp.0, ProofSpecs::default(), vec!["upgrade".to_string(), "upgradedIBCState".to_string()], @@ -1082,6 +1141,9 @@ where .await .map_err(|e| Error::from(format!("Invalid light block {e}")))?; let consensus_state = ConsensusState::from(light_block.signed_header.header); + println!("--------------------------------------------"); + println!("This is consensus state timestamp {:?}", consensus_state.timestamp); + println!("--------------------------------------------"); Ok(( AnyClientState::Tendermint(client_state), AnyConsensusState::Tendermint(consensus_state), @@ -1293,6 +1355,7 @@ where async fn upload_wasm(&self, wasm: Vec) -> Result, Self::Error> { let msg = MsgPushNewWasmCode { signer: self.account_id(), code: wasm }; + // log::info!("This is the msg {:?}", msg); let hash = self.submit(vec![msg.into()]).await?; let resp = self.wait_for_tx_result(hash).await?; let height = Height::new( @@ -1337,6 +1400,60 @@ impl CosmosClient where H: 'static + Clone + Send + Sync, { + async fn fetch_validator_set( + &self, + height: AtHeight, + proposer_address: Option, + ) -> Result { + let height = match height { + AtHeight::Highest => return Err(IoError::invalid_height()), + AtHeight::At(height) => height, + }; + + let client = &self.rpc_client; + let response = client.validators(height, Paging::All).await.map_err(IoError::rpc)?; + + let validator_set = match proposer_address { + Some(proposer_address) => + TMValidatorSet::with_proposer(response.validators, proposer_address) + .map_err(IoError::invalid_validator_set)?, + None => TMValidatorSet::without_proposer(response.validators), + }; + + Ok(validator_set) + } + + async fn fetch_signed_header(&self, height: AtHeight) -> Result { + let client = self.rpc_client.clone(); + let res = match height { + AtHeight::Highest => client.latest_commit().await, + AtHeight::At(height) => client.commit(height).await, + }; + + match res { + Ok(response) => Ok(response.signed_header), + Err(err) => Err(IoError::rpc(err)), + } + } + + pub async fn fetch_light_block( + &self, + height: AtHeight, + peer_id: PeerId, + ) -> Result { + let signed_header = self.fetch_signed_header(height).await?; + let height = signed_header.header.height; + let proposer_address = signed_header.header.proposer_address; + + let validator_set = self.fetch_validator_set(height.into(), Some(proposer_address)).await?; + let next_validator_set = self.fetch_validator_set(height.increment().into(), None).await?; + + let light_block = + LightBlock::new(signed_header, validator_set, next_validator_set, peer_id); + + Ok(light_block) + } + async fn parse_ibc_events_at( &self, counterparty: &C, @@ -1366,8 +1483,16 @@ where for event in events { let mut channel_and_port_ids = self.channel_whitelist(); channel_and_port_ids.extend(counterparty.channel_whitelist()); + // log::info!("host channel and port ids {:?} ", self.channel_whitelist()); + // log::info!("counterparty channel and port ids {:?}, ", + // counterparty.channel_whitelist()); log::info!("Host connection {:?} counterparty + // {:?}", self.connection_id(), counterparty.connection_id()); log::info!("Host clientID + // {:?} counterparty {:?}", self.client_id(), counterparty.client_id()); let ibc_event = ibc_event_try_from_abci_event(&event, ibc_height).ok(); + if matches!(ibc_event, ibc::prelude::Some(IbcEvent::OpenTryConnection(_))) { + println!("-------------------------OpenTryConnection found --------------"); + } match ibc_event { Some(mut ev) => { let is_filtered = filter_events_by_ids( @@ -1380,12 +1505,19 @@ where &channel_and_port_ids, ); + if matches!(ev, IbcEvent::OpenTryConnection(_)) { + if is_filtered { + println!("This is is_filtered") + } + } + if is_filtered { ev.set_height(ibc_height); log::debug!(target: "hyperspace_cosmos", "Encountered event at {height}: {:?}", event.kind); ibc_events.push(ev); } else { - log::debug!(target: "hyperspace_cosmos", "Filtered out event: {:?}", event.kind); + log::debug!(target: "hyperspace_cosmos", "Filtered out event: {:?}", + event.kind); } }, None => { diff --git a/hyperspace/cosmos/src/tx.rs b/hyperspace/cosmos/src/tx.rs index afdfce376..cc9feeb56 100644 --- a/hyperspace/cosmos/src/tx.rs +++ b/hyperspace/cosmos/src/tx.rs @@ -67,18 +67,23 @@ pub async fn simulate_tx( tx: Some(tx), // needed for simulation to go through with Cosmos SDK < 0.43 tx_bytes, // needed for simulation to go through with Cosmos SDk >= 0.43 }; + log::info!("before conn"); let mut client = ServiceClient::connect(grpc_url.clone().to_string()) .await .map_err(|e| Error::from(e.to_string()))?; let request = tonic::Request::new(req); + log::info!("after conn, before request"); let response = tokio::time::timeout( Duration::from_secs(15), - client.simulate(request).map_err(|e| Error::from(e.to_string())), + client + .simulate(request) + .map_err(|e| format!("This is while making request {}", Error::from(e.to_string()))), ) .await .map_err(|_| Error::from("simulation timeout".to_string()))?? .into_inner(); + log::info!("after requst"); Ok(response) } @@ -87,6 +92,7 @@ pub async fn broadcast_tx(rpc_client: &WebSocketClient, tx_bytes: Vec) -> Re .broadcast_tx_sync(tx_bytes) .await .map_err(|e| Error::from(format!("failed to broadcast transaction {e:?}")))?; + log::info!("This is the response {:?}", response); Ok(response.hash) } diff --git a/hyperspace/metrics/Cargo.toml b/hyperspace/metrics/Cargo.toml index 100373cbb..e135ed075 100644 --- a/hyperspace/metrics/Cargo.toml +++ b/hyperspace/metrics/Cargo.toml @@ -15,4 +15,4 @@ anyhow = "1.0.65" # ibc ibc = { path = "../../ibc/modules" } ibc-proto = { path = "../../ibc/proto" } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } diff --git a/hyperspace/near/Cargo.toml b/hyperspace/near/Cargo.toml index 3c5291303..d90007b63 100644 --- a/hyperspace/near/Cargo.toml +++ b/hyperspace/near/Cargo.toml @@ -34,7 +34,7 @@ sp-keystore = "0.12.0" # ibc ibc = { path = "../../ibc/modules", features = [] } ibc-proto = { path = "../../ibc/proto" } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } # near near-crypto = "0.14.0" diff --git a/hyperspace/parachain/Cargo.toml b/hyperspace/parachain/Cargo.toml index 5ea2ecf7d..4ad66a4bd 100644 --- a/hyperspace/parachain/Cargo.toml +++ b/hyperspace/parachain/Cargo.toml @@ -65,7 +65,7 @@ sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polka # composable ibc = { path = "../../ibc/modules", features = [] } ibc-proto = { path = "../../ibc/proto" } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } light-client-common = { path = "../../light-clients/common" } ibc-rpc = { path = "../../contracts/pallet-ibc/rpc" } pallet-ibc = { path = "../../contracts/pallet-ibc" } diff --git a/hyperspace/parachain/src/finality_protocol.rs b/hyperspace/parachain/src/finality_protocol.rs index f8e7dc5c6..2ab320729 100644 --- a/hyperspace/parachain/src/finality_protocol.rs +++ b/hyperspace/parachain/src/finality_protocol.rs @@ -236,7 +236,7 @@ where let max_height_for_timeouts = query_maximum_height_for_timeout_proofs(counterparty, source).await; let timeout_update_required = if let Some(max_height) = max_height_for_timeouts { - let max_height = max_height as u32; + let max_height = max_height.revision_height as u32; finalized_blocks.contains(&max_height) } else { false @@ -304,9 +304,9 @@ where if timeout_update_required { let max_height_for_timeouts = max_height_for_timeouts.unwrap(); - if max_height_for_timeouts > client_state.latest_height().revision_height { + if max_height_for_timeouts > client_state.latest_height() { let max_timeout_height = <::Header as Header>::Number::from( - max_height_for_timeouts as u32, + max_height_for_timeouts.revision_height as u32, ); headers_with_events.insert(max_timeout_height); } @@ -350,7 +350,7 @@ where })), signer: counterparty.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); Any { value, type_url: msg.type_url() } }; @@ -569,7 +569,7 @@ where let max_height_for_timeouts = query_maximum_height_for_timeout_proofs(counterparty, source).await; let timeout_update_required = if let Some(max_height) = max_height_for_timeouts { - let max_height = max_height as u32; + let max_height = max_height.revision_height as u32; finalized_blocks.contains(&max_height) } else { false @@ -621,9 +621,9 @@ where if timeout_update_required { let max_height_for_timeouts = max_height_for_timeouts.unwrap(); - if max_height_for_timeouts > client_state.latest_height().revision_height { + if max_height_for_timeouts > client_state.latest_height() { let max_timeout_height = <::Header as Header>::Number::from( - max_height_for_timeouts as u32, + max_height_for_timeouts.revision_height as u32, ); headers_with_events.insert(max_timeout_height); } @@ -687,7 +687,7 @@ where client_message: AnyClientMessage::Grandpa(ClientMessage::Header(grandpa_header)), signer: counterparty.account_id(), }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); Any { value, type_url: msg.type_url() } }; diff --git a/hyperspace/parachain/src/light_client_sync.rs b/hyperspace/parachain/src/light_client_sync.rs index e4e614c11..7c32344ae 100644 --- a/hyperspace/parachain/src/light_client_sync.rs +++ b/hyperspace/parachain/src/light_client_sync.rs @@ -351,7 +351,7 @@ where client_message: AnyClientMessage::Grandpa(ClientMessage::Header(grandpa_header)), signer, }; - let value = msg.encode_vec()?; + let value = msg.clone().encode_vec(); Result::<_, anyhow::Error>::Ok(( Any { value, type_url: msg.type_url() }, events, diff --git a/hyperspace/primitives/src/lib.rs b/hyperspace/primitives/src/lib.rs index 957c9219b..d2791feeb 100644 --- a/hyperspace/primitives/src/lib.rs +++ b/hyperspace/primitives/src/lib.rs @@ -27,6 +27,7 @@ use ibc_proto::{ connection::v1::QueryConnectionResponse, }, }; +use log::info; use rand::Rng; use serde::{Deserialize, Serialize}; use std::{ @@ -35,7 +36,7 @@ use std::{ pin::Pin, str::FromStr, sync::{Arc, Mutex}, - time::Duration, + time::{Duration, SystemTime}, }; use tokio::{sync::Mutex as AsyncMutex, task::JoinSet, time::sleep}; @@ -53,7 +54,7 @@ use ibc::{ ics04_channel::{ channel::{ChannelEnd, Order}, context::calculate_block_delay, - packet::Packet, + packet::{Packet, Sequence}, }, ics23_commitment::commitment::CommitmentPrefix, ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}, @@ -78,7 +79,7 @@ pub enum UpdateMessage { Batch(Vec), } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq)] pub enum UpdateType { // contains an authority set change. Mandatory, @@ -112,6 +113,23 @@ pub struct CommonClientConfig { pub skip_optional_client_updates: bool, #[serde(default = "max_packets_to_process")] pub max_packets_to_process: u32, + /// Minimal time that should pass between two client updates + #[serde(default)] + pub client_update_interval_sec: u32, + + #[serde(default)] + pub handshake_completed: bool, +} + +impl Default for CommonClientConfig { + fn default() -> Self { + Self { + skip_optional_client_updates: default_skip_optional_client_updates(), + max_packets_to_process: max_packets_to_process(), + client_update_interval_sec: 10, + handshake_completed: false, + } + } } /// A common data that all clients should keep. @@ -132,7 +150,16 @@ pub struct CommonClientState { pub initial_rpc_call_delay: Duration, pub misbehaviour_client_msg_queue: Arc>>, pub max_packets_to_process: usize, - pub skip_tokens_list: Vec, + pub ignored_timeouted_sequences: Arc>>, + /// Minimal time that should pass between two client updates + pub client_update_interval: Duration, + /// Last time when client was updated + pub last_client_update_time: SystemTime, + /// Flag which provides information if handshake is completed + /// + /// Used to prevent finding proof for client state, connection state and channel state + /// once the handshake is completed. + pub handshake_completed: bool, } impl Default for CommonClientState { @@ -145,12 +172,30 @@ impl Default for CommonClientState { initial_rpc_call_delay: rpc_call_delay, misbehaviour_client_msg_queue: Arc::new(Default::default()), max_packets_to_process: 100, - skip_tokens_list: Default::default(), + ignored_timeouted_sequences: Arc::new(Default::default()), + client_update_interval: Default::default(), + last_client_update_time: SystemTime::now(), + handshake_completed: false, } } } impl CommonClientState { + pub fn from_config(config: &CommonClientConfig) -> Self { + Self { + skip_optional_client_updates: config.skip_optional_client_updates, + maybe_has_undelivered_packets: Default::default(), + rpc_call_delay: Duration::from_millis(10), + initial_rpc_call_delay: Duration::from_millis(10), + misbehaviour_client_msg_queue: Arc::new(Default::default()), + max_packets_to_process: config.max_packets_to_process as usize, + ignored_timeouted_sequences: Arc::new(Default::default()), + client_update_interval: Duration::from_secs(config.client_update_interval_sec.into()), + last_client_update_time: SystemTime::now(), + handshake_completed: config.handshake_completed, + } + } + pub async fn on_undelivered_sequences(&self, has: bool, kind: UndeliveredType) { log::trace!( target: "hyperspace", @@ -189,6 +234,7 @@ pub fn apply_prefix(mut commitment_prefix: Vec, path: impl Into>) -> /// - acknowledgement packet (`Acks`), /// - receive packet (`Recvs`) /// - timeout packet (`Timeouts`) +/// - proofs for the packets (`Proofs`) #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum UndeliveredType { Acks, @@ -293,7 +339,7 @@ pub trait IbcProvider { seq: u64, ) -> Result; - /// Return latest finalized height and timestamp + /// Return latest finalized height and timestamp specifically for the chain. async fn latest_height_and_timestamp(&self) -> Result<(Height, Timestamp), Self::Error>; async fn query_packet_commitments( @@ -600,12 +646,15 @@ pub async fn query_undelivered_sequences( ) .map_err(|e| Error::Custom(e.to_string()))?; // First we fetch all packet commitments from source + // let _ignored_timeouts = source.common_state().ignored_timeouted_sequences.lock().await; let seqs = source .query_packet_commitments(source_height, channel_id, port_id.clone()) .await? .into_iter() + // .filter(|seq| !ignored_timeouts.contains(seq)) .collect::>(); log::trace!(target: "hyperspace", "Seqs: {:?}", seqs); + let counterparty_channel_id = channel_end .counterparty() .channel_id @@ -649,6 +698,12 @@ pub async fn query_undelivered_acks( .ok_or_else(|| Error::Custom("ChannelEnd not could not be decoded".to_string()))?, ) .map_err(|e| Error::Custom(e.to_string()))?; + let counterparty_channel_id = channel_end + .counterparty() + .channel_id + .ok_or_else(|| Error::Custom("Expected counterparty channel id".to_string()))?; + let counterparty_port_id = channel_end.counterparty().port_id.clone(); + // First we fetch all packet acknowledgements from source let seqs = source .query_packet_acknowledgements(source_height, channel_id, port_id.clone()) @@ -658,11 +713,6 @@ pub async fn query_undelivered_acks( "Found {} packet acks from {} chain", seqs.len(), source.name() ); - let counterparty_channel_id = channel_end - .counterparty() - .channel_id - .ok_or_else(|| Error::Custom("Expected counterparty channel id".to_string()))?; - let counterparty_port_id = channel_end.counterparty().port_id.clone(); let mut undelivered_acks = sink .query_unreceived_acknowledgements( @@ -708,115 +758,72 @@ pub async fn find_suitable_proof_height_for_client( at: Height, client_id: ClientId, start_height: Height, + height_to_match: Option, timestamp_to_match: Option, latest_client_height: Height, ) -> Option { - log::trace!( + log::info!( target: "hyperspace", "Searching for suitable proof height for client {} ({}) starting at {}, {:?}, latest_client_height={}", client_id, sink.name(), start_height, timestamp_to_match, latest_client_height ); - // If searching for existence of just a height we use a pure linear search because there's no - // valid comparison to be made and there might be missing values for some heights - if timestamp_to_match.is_none() { - // try to find latest states first, because relayer's strategy is to submit the most - // recent ones - for height in start_height.revision_height..=latest_client_height.revision_height { - let temp_height = Height::new(start_height.revision_number, height); - let consensus_state = - sink.query_client_consensus(at, client_id.clone(), temp_height).await.ok(); - let decoded = consensus_state - .map(|x| x.consensus_state.map(AnyConsensusState::try_from)) - .flatten(); - if !matches!(decoded, Some(Ok(_))) { - continue - } - let proof_height = source.get_proof_height(temp_height).await; - let has_client_state = sink - .query_client_update_time_and_height(client_id.clone(), proof_height) - .await - .ok() - .is_some(); - if !has_client_state { - continue - } - log::info!("Found proof height on {} as {}:{}", sink.name(), temp_height, proof_height); - return Some(temp_height) - } - } else { - let timestamp_to_match = timestamp_to_match.unwrap(); - let mut start = start_height.revision_height; - let mut end = latest_client_height.revision_height; - let mut last_known_valid_height = None; - if start > end { - return None - } - - log::debug!( - target: "hyperspace", - "Entered binary search for proof height on {} for client {} starting at {}", sink.name(), client_id, start_height - ); - while end - start > 1 { - let mid = (end + start) / 2; - let temp_height = Height::new(start_height.revision_number, mid); - let consensus_state = - sink.query_client_consensus(at, client_id.clone(), temp_height).await.ok(); - let Some(Ok(consensus_state)) = consensus_state - .map(|x| x.consensus_state.map(AnyConsensusState::try_from)) - .flatten() - else { - start += 1; - continue - }; - let proof_height = source.get_proof_height(temp_height).await; - let has_client_state = sink - .query_client_update_time_and_height(client_id.clone(), proof_height) - .await - .ok() - .is_some(); - if !has_client_state { - start += 1; - continue - } - - if consensus_state.timestamp().nanoseconds() < timestamp_to_match.nanoseconds() { - start = mid + 1; - continue - } else { - last_known_valid_height = Some(temp_height); - end = mid; - } + let start_height = source.get_proof_height(start_height).await; + + // We use pure linear search because there's no valid comparison to be made and there might be + // missing values for some heights + for height in start_height.revision_height..=latest_client_height.revision_height { + let mut temp_height = Height::new(start_height.revision_number, height); + + if sink + .query_client_update_time_and_height(client_id.clone(), temp_height) + .await + .ok() + .is_none() + { + continue } - let start_height = Height::new(start_height.revision_number, start); let consensus_state = - sink.query_client_consensus(at, client_id.clone(), start_height).await.ok(); - if let Some(Ok(consensus_state)) = consensus_state + sink.query_client_consensus(at, client_id.clone(), temp_height).await.ok(); + let decoded = consensus_state .map(|x| x.consensus_state.map(AnyConsensusState::try_from)) - .flatten() - { + .flatten(); + if !matches!(decoded, Some(Ok(_))) { + continue + } + let mut matches = false; + if let Some(timestamp_to_match) = ×tamp_to_match { + let consensus_state = decoded.unwrap().unwrap(); + if consensus_state.timestamp().nanoseconds() >= timestamp_to_match.nanoseconds() { - let proof_height = source.get_proof_height(start_height).await; - let has_client_state = sink - .query_client_update_time_and_height(client_id.clone(), proof_height) - .await - .ok() - .is_some(); - if has_client_state { - return Some(start_height) - } + matches = true; + } + } + if let Some(height_to_match) = &height_to_match { + if temp_height >= *height_to_match { + matches = true; } } + if !matches { + continue + } - return last_known_valid_height + let proof_height = source.get_proof_height(temp_height).await; + if proof_height != temp_height { + temp_height.revision_height -= + proof_height.revision_height - temp_height.revision_height; + } + info!("Found proof height on {} as {}:{}", sink.name(), temp_height, proof_height); + return Some(temp_height) } None } +// TODO: query_maximum_height_for_timeout_proofs: return Result, _> pub async fn query_maximum_height_for_timeout_proofs( source: &impl Chain, sink: &impl Chain, -) -> Option { +) -> Option { let (source_height, ..) = source.latest_height_and_timestamp().await.ok()?; let (sink_height, ..) = sink.latest_height_and_timestamp().await.ok()?; let mut join_set: JoinSet> = JoinSet::new(); @@ -861,27 +868,27 @@ pub async fn query_maximum_height_for_timeout_proofs( sink.query_timestamp_at(height.revision_height).await.ok()?; let period = send_packet.timeout_timestamp.saturating_sub(timestamp_at_creation); if period == 0 { - return Some(send_packet.timeout_height.revision_height) + return Some(Height::from(send_packet.timeout_height)) } let period = Duration::from_nanos(period); let period = calculate_block_delay(period, sink.expected_block_time()).saturating_add(1); let approx_height = revision_height + period; let timeout_height = if send_packet.timeout_height.revision_height < approx_height { - send_packet.timeout_height.revision_height + Height::from(send_packet.timeout_height) } else { - approx_height + Height::new(send_packet.timeout_height.revision_number, approx_height) }; Some(timeout_height) }); } } - let mut min_timeout_height = None; + let mut max_timeout_height = None; while let Some(timeout_height) = join_set.join_next().await { - min_timeout_height = min_timeout_height.max(timeout_height.ok()?) + max_timeout_height = max_timeout_height.max(timeout_height.ok()?) } - min_timeout_height + max_timeout_height } pub fn filter_events_by_ids( @@ -937,6 +944,7 @@ pub fn filter_events_by_ids( IbcEvent::TimeoutOnClosePacket(e) => filter_packet(&e.packet), IbcEvent::CreateClient(e) => filter_client_attributes(&e.0), IbcEvent::UpdateClient(e) => filter_client_attributes(&e.common), + IbcEvent::UpdateClientProposal(e) => client_ids.contains(&e.client_id), IbcEvent::UpgradeClient(e) => filter_client_attributes(&e.0), IbcEvent::ClientMisbehaviour(e) => filter_client_attributes(&e.0), IbcEvent::OpenInitConnection(e) => filter_connection_attributes(&e.0), @@ -962,7 +970,7 @@ pub fn filter_events_by_ids( IbcEvent::ChainError(_) => true, }; if !v { - log::debug!(target: "hyperspace_parachain", "Filtered out event: {:?}", ev); + log::debug!(target: "hyperspace", "Filtered out event: {:?}", ev); } v } diff --git a/hyperspace/primitives/src/utils.rs b/hyperspace/primitives/src/utils.rs index 961c82cee..05f134805 100644 --- a/hyperspace/primitives/src/utils.rs +++ b/hyperspace/primitives/src/utils.rs @@ -18,7 +18,10 @@ use crate::{mock::LocalClientTypes, Chain}; use futures::{future, StreamExt}; use ibc::{ core::{ - ics02_client::msgs::create_client::MsgCreateAnyClient, + ics02_client::{ + client_consensus::ConsensusState, + msgs::{create_client::MsgCreateAnyClient, update_client::MsgUpdateAnyClient}, + }, ics03_connection::{connection::Counterparty, msgs::conn_open_init::MsgConnectionOpenInit}, ics04_channel, ics04_channel::{ @@ -33,7 +36,7 @@ use ibc::{ tx_msg::Msg, }; use ibc_proto::google::protobuf::Any; -use std::{future::Future, time::Duration}; +use std::{future::Future, thread::sleep, time::Duration}; pub async fn timeout_future(future: T, secs: u64, reason: String) -> T::Output { let duration = Duration::from_secs(secs); @@ -67,33 +70,54 @@ pub async fn create_clients( chain_a: &mut impl Chain, chain_b: &mut impl Chain, ) -> Result<(ClientId, ClientId), anyhow::Error> { - let (client_state_a, cs_state_a) = chain_a.initialize_client_state().await?; + println!("In clients"); let (client_state_b, cs_state_b) = chain_b.initialize_client_state().await?; let msg = MsgCreateAnyClient:: { - client_state: client_state_b, - consensus_state: cs_state_b, + client_state: client_state_b.clone(), + consensus_state: cs_state_b.clone(), signer: chain_a.account_id(), }; - let msg = Any { type_url: msg.type_url(), value: msg.encode_vec()? }; + let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; + println!("In clients"); let tx_id = chain_a.submit(vec![msg]).await?; + println!("In clients with tx_id {:?}", tx_id); + // sleep(Duration::from_secs(5)); + // let client_id_b_on_a = ClientId::new("9999-mock", 0).unwrap(); let client_id_b_on_a = chain_a.query_client_id_from_tx_hash(tx_id).await?; - chain_a.set_client_id(client_id_b_on_a.clone()); + let (client_state_a, cs_state_a) = chain_a.initialize_client_state().await?; + + log::info!("This is timestamp of cs state {:?}", cs_state_a.timestamp()); let msg = MsgCreateAnyClient:: { client_state: client_state_a, consensus_state: cs_state_a, signer: chain_b.account_id(), }; - let msg = Any { type_url: msg.type_url(), value: msg.encode_vec()? }; + let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; + + // let tx_id = chain_a.submit(vec![msg.clone()]).await?; + // let client_id_b_on_a = chain_a.query_client_id_from_tx_hash(tx_id).await?; + // chain_a.set_client_id(client_id_b_on_a.clone()); let tx_id = chain_b.submit(vec![msg]).await?; let client_id_a_on_b = chain_b.query_client_id_from_tx_hash(tx_id).await?; chain_a.set_client_id(client_id_b_on_a.clone()); + // let msg = MsgUpdateAnyClient:: { + // signer: chain_a.account_id(), + // client_id: client_id_b_on_a, + // client_message: Any { type_url: "/ibc.lightclients.tendermint.v1.Header".to_owned(), value: + // Vec::new() }, }; + + // let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; + + // println!("In clients"); + // let tx_id = chain_a.submit(vec![msg]).await?; + Ok((client_id_a_on_b, client_id_b_on_a)) } @@ -112,7 +136,7 @@ pub async fn create_connection( signer: chain_a.account_id(), }; - let msg = Any { type_url: msg.type_url(), value: msg.encode_vec()? }; + let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; let tx_id = chain_a.submit(vec![msg]).await?; let connection_id_a = chain_a.query_connection_id_from_tx_hash(tx_id).await?; @@ -169,7 +193,7 @@ pub async fn create_channel( let msg = MsgChannelOpenInit::new(port_id, channel, chain_a.account_id()); - let msg = Any { type_url: msg.type_url(), value: msg.encode_vec()? }; + let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; let tx_id = chain_a.submit(vec![msg]).await?; let channel_id_a = chain_a.query_channel_id_from_tx_hash(tx_id).await?; @@ -197,5 +221,11 @@ pub async fn create_channel( got => panic!("Last event should be OpenConfirmChannel: {got:?}"), }; + let chain_a_common_client_config = chain_a.common_state_mut(); + let chain_b_common_client_config = chain_b.common_state_mut(); + + chain_a_common_client_config.handshake_completed = true; + chain_b_common_client_config.handshake_completed = true; + Ok((channel_id_a, channel_id_b)) } diff --git a/hyperspace/solana/Cargo.toml b/hyperspace/solana/Cargo.toml new file mode 100644 index 000000000..ea527aeea --- /dev/null +++ b/hyperspace/solana/Cargo.toml @@ -0,0 +1,123 @@ +[package] +name = "hyperspace-solana" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +primitives = { path = "../primitives", package = "hyperspace-primitives" } + +# crates.io +anyhow = "1.0.65" +futures = "0.3.21" +async-trait = "0.1.53" +log = "0.4.17" +hex = "0.4.3" +tokio = { version = "1.32.0", features = ["macros", "sync"] } +rs_merkle = "1.2.0" +codec = { package = "parity-scale-codec", version = "3.0.0", features = ["derive"] } +serde_json = "1.0.74" +derive_more = { version = "0.99", features = ["from"] } +serde = {version="1.0.137", features = ["derive"]} +tokio-stream = { version = "0.1.14", features = ["sync"]} +thiserror = "1.0.31" +itertools = "0.10.3" +prost = { version = "0.11" } +k256 = { version = "0.11.6", features = ["ecdsa-core", "ecdsa", "sha256"] } +tonic = { version = "0.8", features = ["tls", "tls-roots"] } +bech32 = "0.9.1" +bip32 = "0.4.0" +ed25519-zebra = { version = "3.1.0" } +tiny-bip39 = "1.0.0" +sha2 = "0.10.6" +ripemd = "0.1.3" +digest = "0.10.6" +quick_cache = "0.3.0" +rand = "0.8.5" +anchor-client = {version = "0.29.0", features = ["async"] } +anchor-lang = "0.29.0" +anchor-spl = "0.29.0" +solana-transaction-status = "=1.17.31" +base64 = { version = "0.21.4", default-features = false, features = ["alloc"] } +borsh = { version = "0.10.3", default-features = false } +bytemuck = { version = "1.14", default-features = false } +reqwest = "0.11.24" +futures-util = "0.3.28" +jito-searcher-client = { git = "https://github.com/dhruvja/searcher-examples" } +jito-protos = { git = "https://github.com/dhruvja/searcher-examples" } +prost-types = "0.12" +solana-metrics = "=1.17.31" +rusqlite = { version = "0.29.0", features = ["bundled"] } + +bs58 = { version = "0.5.0", features = ["alloc"] } +bincode = { version = "1.3.3" } + +# New IBC +ibc-new-primitives = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false, features = ["borsh", "serde"] , package="ibc-primitives" } +ibc-core-host-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false, features = ["borsh", "serde"]} +ibc-core-handler-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-client-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-connection-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-channel-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-app-transfer-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-commitment-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-client-tendermint-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-client-wasm-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false} +# ibc-testkit = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-proto-new = { version = "0.41.0", default-features = false, package="ibc-proto" } + +ics23 = { version = "0.11.1" } + + + +# Old IBC +ibc = { path = "../../ibc/modules", features = [] } +ibc-proto = { path = "../../ibc/proto", package="ibc-proto" } +ibc-primitives = { path = "../../contracts/pallet-ibc/primitives" } +ics07-tendermint = { path = "../../light-clients/ics07-tendermint", features = ["dummy"] } +ics08-wasm = { path = "../../light-clients/ics08-wasm" } +ibc-rpc = { path = "../../contracts/pallet-ibc/rpc" } +pallet-ibc = { path = "../../contracts/pallet-ibc", features = ["testing"]} + +# Trie +lib = { path = "../../../emulated-light-client/common/lib" } +memory = { path = "../../../emulated-light-client/common/memory" } +sealable-trie = { path = "../../../emulated-light-client/common/sealable-trie" ,features = ["borsh"] } +stdx = { path = "../../../emulated-light-client/common/stdx" } +solana-trie = { path = "../../../emulated-light-client/solana/trie" } +trie-ids = { path = "../../../emulated-light-client/common/trie-ids" ,features = ["borsh"] } +cf-guest = { path = "../../light-clients/cf-guest", default-features = false } +cf-guest-og = { path = "../../../emulated-light-client/common/cf-guest" ,package = "cf-guest" } +guestchain = { path = "../../../emulated-light-client/common/guestchain" ,default-features = false } + +#Contract +solana-ibc = { path = "../../../emulated-light-client/solana/solana-ibc/programs/solana-ibc" ,features = ["no-entrypoint"]} +solana-write-account = { path = "../../../emulated-light-client/solana/write-account" ,features = ["library"] } +solana-signature-verifier = { path = "../../../emulated-light-client/solana/signature-verifier" } + +tracing = "0.1.36" + +# tendermint +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false, features = [ + "secp256k1", +] } +tendermint_new = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false, package = "tendermint" } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false, features = [ + "http-client", + "websocket-client", +] } +tendermint-light-client = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false, features = [ + "rpc-client", + "secp256k1", + "unstable", +# "testing" +] } +tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-light-client-verifier_new = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false, package = "tendermint-light-client-verifier" } + +[features] +testing = [ + "primitives/testing" +] diff --git a/hyperspace/solana/src/client.rs b/hyperspace/solana/src/client.rs new file mode 100644 index 000000000..b9ff020e3 --- /dev/null +++ b/hyperspace/solana/src/client.rs @@ -0,0 +1,1135 @@ +use anchor_client::{ + solana_client::{ + nonblocking::rpc_client::RpcClient as AsyncRpcClient, rpc_config::RpcSendTransactionConfig, + }, + solana_sdk::{ + address_lookup_table::program, + commitment_config::{CommitmentConfig, CommitmentLevel}, + compute_budget::ComputeBudgetInstruction, + instruction::Instruction, + pubkey::ParsePubkeyError, + signature::{Keypair, Signature}, + signer::Signer as AnchorSigner, + transaction::Transaction, + }, + Client as AnchorClient, Cluster, Program, +}; +use anchor_lang::{prelude::*, system_program}; +use anchor_spl::associated_token::get_associated_token_address; +use core::{str::FromStr, time::Duration}; +use futures::future::join_all; +use ibc::{ + applications::transfer::{msgs::transfer::MsgTransfer, PrefixedCoin}, + core::{ + ics02_client::client_state::ClientType, + ics23_commitment::commitment::CommitmentPrefix, + ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}, + }, +}; +use ibc_app_transfer_types::{ + is_receiver_chain_source, is_sender_chain_source, Coin, PrefixedDenom, TracePrefix, +}; +use ibc_core_handler_types::msgs::MsgEnvelope; +use ibc_core_host_types::identifiers::ClientId as ClientIdNew; +use itertools::izip; +use lib::hash::CryptoHash; +use primitives::{CommonClientConfig, CommonClientState, IbcProvider}; +use serde::{Deserialize, Serialize}; +use sigverify::ed25519_program::{new_instruction, Entry}; +use solana_transaction_status::UiTransactionEncoding; +use std::{ + collections::HashSet, + ops::Deref, + rc::Rc, + result::Result, + sync::{Arc, Mutex}, + thread::sleep, +}; +use tendermint_light_client_verifier_new::types::{TrustedBlockState, UntrustedBlockState}; +use tendermint_rpc::Url; + +use super::{CHAIN_SEED, SOLANA_IBC_STORAGE_SEED, TRIE_SEED}; +use crate::{ + error::Error, + utils::{new_ed25519_instruction_with_signature, non_absent_vote}, +}; +use solana_ibc::{ + chain::ChainData, events::BlockFinalised, ix_data_account, storage::PrivateStorage, +}; +use tendermint_new::vote::{SignedVote, ValidatorIndex}; + +#[derive(Debug)] +pub enum DeliverIxType { + UpdateClient { + client_message: ibc_proto_new::google::protobuf::Any, + client_id: ClientIdNew, + }, + Recv { + token: Coin, + port_id: ibc_core_host_types::identifiers::PortId, + channel_id: ibc_core_host_types::identifiers::ChannelId, + receiver: String, + }, + Timeout { + token: Coin, + port_id: ibc_core_host_types::identifiers::PortId, + channel_id: ibc_core_host_types::identifiers::ChannelId, + sender_account: String, + }, + Acknowledgement { + sender: Pubkey, + }, + Normal, +} + +/// Implements the [`crate::Chain`] trait for solana +#[derive(Clone)] +pub struct SolanaClient { + /// Chain name + pub name: String, + /// rpc url for solana + pub rpc_url: String, + /// websocket url for solana + pub ws_url: String, + /// Solana chain Id + pub chain_id: String, + /// Light client id on counterparty chain + pub client_id: Arc>>, + /// Connection Id + pub connection_id: Arc>>, + /// Account prefix + pub account_prefix: String, + pub fee_denom: String, + /// The key that signs transactions + pub keybase: KeyEntry, + /// Maximun transaction size + pub max_tx_size: usize, + pub commitment_level: CommitmentLevel, + pub solana_ibc_program_id: Pubkey, + pub write_program_id: Pubkey, + pub signature_verifier_program_id: Pubkey, + pub common_state: CommonClientState, + pub client_type: ClientType, + pub last_searched_sig_for_send_packets: Arc>, + pub last_searched_sig_for_recv_packets: Arc>, + /// Reference to commitment + pub commitment_prefix: CommitmentPrefix, + /// Channels cleared for packet relay + pub channel_whitelist: Arc>>, + // Trie db path + pub trie_db_path: String, + // Sets whether to use JITO or RPC for submitting transactions + pub transaction_sender: TransactionSender, +} + +#[derive(std::fmt::Debug, Serialize, Deserialize, Clone)] +pub struct SolanaClientConfig { + /// Chain name + pub name: String, + /// rpc url for solana + pub rpc_url: Url, + /// websocket url for solana + pub ws_url: Url, + /// Solana chain Id + pub chain_id: String, + /// Light client id on counterparty chain + pub client_id: Option, + /// Connection Id + pub connection_id: Option, + /// Account prefix + pub account_prefix: String, + /// Fee denom + pub fee_denom: String, + /// Fee amount + pub fee_amount: String, + /// Fee amount + pub gas_limit: u64, + /// Store prefix + pub store_prefix: String, + /// Maximun transaction size + pub max_tx_size: usize, + /// All the client states and headers will be wrapped in WASM ones using the WASM code ID. + pub wasm_checksum: Option, + pub common_state_config: CommonClientConfig, + /// Reference to commitment + pub commitment_prefix: Vec, + /// Channels cleared for packet relay + pub channel_whitelist: Vec<(ChannelId, PortId)>, + pub commitment_level: String, + pub private_key: Vec, + pub solana_ibc_program_id: String, + pub write_program_id: String, + pub signature_verifier_program_id: String, + pub trie_db_path: String, + pub transaction_sender: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum TransactionSender { + JITO, + RPC, +} + +#[derive(Debug, Clone)] +pub enum FinalityEvent { + Guest { blockhash: CryptoHash, block_height: u64 }, +} + +#[derive(Debug)] +struct Trie { + #[allow(dead_code)] + id: i32, + height: i32, + data: Vec, + state_root: Vec, + match_block_state_root: bool, +} + +#[derive(Clone)] +pub struct KeyEntry { + pub public_key: Pubkey, + pub private_key: Vec, +} + +impl KeyEntry { + pub fn keypair(&self) -> Keypair { + Keypair::from_bytes(&self.private_key).unwrap() + } +} + +impl From> for KeyEntry { + fn from(value: Vec) -> Self { + let keypair = Keypair::from_bytes(&value).unwrap(); + Self { public_key: keypair.pubkey(), private_key: value } + } +} + +impl SolanaClient { + pub fn get_trie_key(&self) -> Pubkey { + let trie_seeds = &[TRIE_SEED]; + let trie = Pubkey::find_program_address(trie_seeds, &self.solana_ibc_program_id).0; + trie + } + + pub fn get_ibc_storage_key(&self) -> Pubkey { + let storage_seeds = &[SOLANA_IBC_STORAGE_SEED]; + let ibc_storage = + Pubkey::find_program_address(storage_seeds, &self.solana_ibc_program_id).0; + ibc_storage + } + + pub fn get_chain_key(&self) -> Pubkey { + let chain_seeds = &[CHAIN_SEED]; + let chain = Pubkey::find_program_address(chain_seeds, &self.solana_ibc_program_id).0; + chain + } + + pub fn get_mint_auth_key(&self) -> Pubkey { + let mint_auth_seeds = &[solana_ibc::MINT_ESCROW_SEED]; + let mint_auth = + Pubkey::find_program_address(mint_auth_seeds, &self.solana_ibc_program_id).0; + mint_auth + } + + pub fn get_fee_collector_key(&self) -> Pubkey { + let fee_collector_seeds = &[solana_ibc::FEE_SEED]; + let fee_collector = + Pubkey::find_program_address(fee_collector_seeds, &self.solana_ibc_program_id).0; + fee_collector + } + + /// Returns trie at a particular height or the latest one if not available + pub async fn get_trie( + &self, + at: u64, + require_proof: bool, + ) -> (solana_trie::TrieAccount>, bool) { + let connection = self.get_db(); + if require_proof { + let row = connection.query_row("SELECT * FROM Trie WHERE height=?1", [at], |row| { + Ok(Trie { + id: row.get(0)?, + height: row.get(1)?, + data: row.get(2)?, + state_root: row.get(3)?, + match_block_state_root: row.get(4)?, + }) + }); + if let Ok(trie) = row { + log::info!("Does block state roots match {}", trie.match_block_state_root); + if trie.match_block_state_root { + return ( + solana_trie::TrieAccount::new(trie.data).unwrap(), + trie.match_block_state_root, + ); + } + } + } + let trie_key = self.get_trie_key(); + let rpc_client = self.rpc_client(); + let trie_account = rpc_client + .get_account_with_commitment(&trie_key, CommitmentConfig::processed()) + .await + .unwrap() + .value + .unwrap(); + let trie = solana_trie::TrieAccount::new(trie_account.data).unwrap(); + (trie, false) + } + + pub async fn get_ibc_storage(&self) -> PrivateStorage { + let program = self.program(); + let ibc_storage_key = self.get_ibc_storage_key(); + let storage: PrivateStorage = program.account(ibc_storage_key).await.unwrap(); + // let storage = tokio::task::spawn_blocking(move || { + // program.account(ibc_storage_key).unwrap() + // }).await.unwrap(); + storage + } + + pub async fn get_chain_storage(&self) -> ChainData { + let program = self.program(); + let chain_storage_key = self.get_chain_key(); + let storage = program.account(chain_storage_key).await.unwrap(); + storage + } + + pub fn rpc_client(&self) -> AsyncRpcClient { + let program = self.program(); + program.async_rpc() + } + + pub fn client(&self) -> AnchorClient> { + let cluster = Cluster::from_str(&self.rpc_url).unwrap(); + let signer = self.keybase.keypair(); + let authority = Arc::new(signer); + let client = + AnchorClient::new_with_options(cluster, authority, CommitmentConfig::processed()); + client + } + + pub fn get_db(&self) -> rusqlite::Connection { + let db_url = self.trie_db_path.as_str(); + rusqlite::Connection::open(db_url).unwrap() + } + + pub fn program(&self) -> Program> { + let anchor_client = self.client(); + anchor_client.program(self.solana_ibc_program_id).unwrap() + } + + #[allow(dead_code)] + pub async fn new(config: SolanaClientConfig) -> Result { + let db_url = config.trie_db_path.as_str(); + let conn = rusqlite::Connection::open(db_url).unwrap(); + let count = conn.query_row("SELECT COUNT(*) FROM Trie", [], |row| { + log::info!("This is row"); + Ok(()) + }); + log::info!("This is count {:?}", count); + let transaction_sender_str = config.transaction_sender.to_ascii_uppercase(); + let transaction_sender = match transaction_sender_str.as_str() { + "JITO" => TransactionSender::JITO, + "RPC" => TransactionSender::RPC, + _ => panic!("Invalid param transaction sender: Expected JITO/RPC"), + }; + Ok(Self { + name: config.name, + rpc_url: config.rpc_url.to_string(), + ws_url: config.ws_url.to_string(), + chain_id: config.chain_id, + client_id: Arc::new(Mutex::new(config.client_id)), + connection_id: Arc::new(Mutex::new(config.connection_id)), + account_prefix: config.account_prefix, + fee_denom: config.fee_denom, + keybase: config.private_key.into(), + max_tx_size: config.max_tx_size, + commitment_level: CommitmentLevel::from_str(&config.commitment_level).unwrap(), + solana_ibc_program_id: Pubkey::from_str(&config.solana_ibc_program_id).unwrap(), + write_program_id: Pubkey::from_str(&config.write_program_id).unwrap(), + signature_verifier_program_id: Pubkey::from_str(&config.signature_verifier_program_id) + .unwrap(), + common_state: CommonClientState { + handshake_completed: config.common_state_config.handshake_completed, + ..Default::default() + }, + client_type: "07-tendermint".to_string(), + last_searched_sig_for_send_packets: Arc::new( + tokio::sync::Mutex::new(String::default()), + ), + last_searched_sig_for_recv_packets: Arc::new( + tokio::sync::Mutex::new(String::default()), + ), + commitment_prefix: CommitmentPrefix::try_from(config.commitment_prefix).unwrap(), + channel_whitelist: Arc::new(Mutex::new(config.channel_whitelist.into_iter().collect())), + trie_db_path: config.trie_db_path, + transaction_sender, + }) + } + + pub async fn send_deliver( + &self, + instruction_type: DeliverIxType, + + chunk_account: Pubkey, + max_tries: u8, + ) -> Result<(Vec, Vec), Error> { + // log::info!("This is ix type {:?}", instruction_type); + let program = self.program(); + let signer = self.keybase.keypair(); + let authority = Arc::new(signer); + let rpc = self.rpc_client(); + let mut tries = 0; + let mut signature = String::new(); + let solana_ibc_storage_key = self.get_ibc_storage_key(); + let trie_key = self.get_trie_key(); + let chain_key = self.get_chain_key(); + // while tries < max_tries { + // println!("Try For Tx: {}", tries); + // let mut status = true; + // let sig = + match instruction_type { + DeliverIxType::UpdateClient { ref client_message, ref client_id } => { + let header = + ibc_client_tendermint_types::Header::try_from(client_message.clone()).unwrap(); + let trusted_state = { + let storage = self.get_ibc_storage().await; + log::info!("This is client ID {:?}", client_id); + let client_store = storage + .clients + .iter() + .find(|&client| client.client_id.as_str() == client_id.as_str()) + .ok_or("Client not found with the given client id while sending update client message".to_owned()) + .unwrap(); + let serialized_consensus_state = client_store + .consensus_states + .deref() + .get( + &ibc_core_client_types::Height::new( + header.trusted_height.revision_number(), + header.trusted_height.revision_height(), + ) + .unwrap(), + ) + .ok_or(Error::Custom("No value at given key".to_owned())) + .unwrap(); + let consensus_state = serialized_consensus_state + .state() + .map_err(|_| { + Error::Custom( + "Could not +deserialize consensus state" + .to_owned(), + ) + }) + .unwrap(); + let trusted_consensus_state = match consensus_state { + solana_ibc::consensus_state::AnyConsensusState::Tendermint(e) => e, + _ => panic!(), + }; + + header + .check_trusted_next_validator_set::( + trusted_consensus_state.inner(), + ) + .unwrap(); + + TrustedBlockState { + chain_id: &self.chain_id.to_string().try_into().unwrap(), + header_time: trusted_consensus_state.timestamp(), + height: header.trusted_height.revision_height().try_into().unwrap(), + next_validators: &header.trusted_next_validator_set, + next_validators_hash: trusted_consensus_state.next_validators_hash(), + } + }; + + let untrusted_state = UntrustedBlockState { + signed_header: &header.signed_header, + validators: &header.validator_set, + // NB: This will skip the + // VerificationPredicates::next_validators_match check for the + // untrusted state. + next_validators: None, + }; + let signed_header = untrusted_state.signed_header; + let validator_set = trusted_state.next_validators; + let signatures = &signed_header.commit.signatures; + // log::info!("These are signatures {:?}", signatures); + + let mut seen_validators = HashSet::new(); + + // Get non-absent votes from the signatures + let non_absent_votes = + signatures.iter().enumerate().flat_map(|(idx, signature)| { + non_absent_vote( + signature, + ValidatorIndex::try_from(idx).unwrap(), + &signed_header.commit, + ) + .map(|vote| (signature, vote)) + }); + let mut pubkeys = Vec::new(); + let mut final_signatures = Vec::new(); + let mut messages = Vec::new(); + for (_signature, vote) in non_absent_votes { + // Ensure we only count a validator's power once + if seen_validators.contains(&vote.validator_address) { + // return Err(VerificationError::duplicate_validator( + // vote.validator_address, + // )) + panic!("Duplicate validator"); + } else { + seen_validators.insert(vote.validator_address); + } + + let validator = match validator_set.validator(vote.validator_address) { + Some(validator) => validator, + None => continue, // Cannot find matching validator, so we skip the vote + }; + + let signed_vote = + SignedVote::from_vote(vote.clone(), signed_header.header.chain_id.clone()) + .unwrap(); + + // Check vote is valid + let sign_bytes = signed_vote.sign_bytes(); + pubkeys.push(validator.pub_key.to_bytes()); + final_signatures.push(signed_vote.signature().clone().into_bytes()); + messages.push(sign_bytes); + + // if validator + // .verify_signature::(&sign_bytes, signed_vote.signature()) + // .is_err() + // { + // panic!("invalid signature"); + // // return Err(VerificationError::invalid_signature( + // // signed_vote.signature().as_bytes().to_vec(), + // // Box::new(validator), + // // sign_bytes, + // // )) + // } + + // TODO: Break out of the loop when we have enough voting power. + // See https://github.com/informalsystems/tendermint-rs/issues/235 + } + // log::info!("Pubkeys {:?}", pubkeys); + // log::info!("final_signatures {:?}", final_signatures); + // log::info!("messages {:?}", messages); + // Chunk the signatures + let total_signatures = final_signatures.len(); + let chunk_size = 3; + let chunks = total_signatures / chunk_size + 1; + let authority_bytes = authority.pubkey().to_bytes(); + let signature_seeds = &[authority_bytes.as_ref()]; + let (signatures_account_pda, bump) = Pubkey::find_program_address( + signature_seeds, + &self.signature_verifier_program_id, + ); + let mut signature_chunking_txs = Vec::new(); + for chunk in 0..chunks { + let start = chunk * chunk_size; + let end = (start + chunk_size).min(total_signatures); + println!("Start {} end {}", start, end); + + let accounts = vec![ + AccountMeta { + pubkey: authority.pubkey(), + is_signer: true, + is_writable: true, + }, + AccountMeta { + pubkey: signatures_account_pda, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: anchor_lang::solana_program::sysvar::instructions::ID, + is_signer: false, + is_writable: true, + }, + AccountMeta { + pubkey: system_program::ID, + is_signer: false, + is_writable: true, + }, + ]; + let mut data = vec![0, 0]; + data.extend(&bump.to_le_bytes()); + let instruction = Instruction::new_with_bytes( + self.signature_verifier_program_id, + &data, + accounts, + ); + let mut entries = Vec::new(); + let temp_pubkeys = pubkeys[start..end].to_vec(); + let temp_signatures = final_signatures[start..end].to_vec(); + let temp_messages = messages[start..end].to_vec(); + for (pubkey, signature, message) in + izip!(&temp_pubkeys, &temp_signatures, &temp_messages,) + { + let pubkey = pubkey.as_slice().try_into().unwrap(); + let signature = signature.as_slice().try_into().unwrap(); + let message = message.as_slice().try_into().unwrap(); + let entry: Entry = Entry { pubkey, signature, message }; + entries.push(entry); + } + let ix = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(300_000)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(50_000)) + .instruction(new_instruction(entries.as_slice()).unwrap()) + .instruction(instruction) + .instructions() + .unwrap(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let transactions = + Transaction::new_with_payer(ix.as_slice(), Some(&authority.pubkey())); + signature_chunking_txs.push(transactions); + // .send() + // .await + // .or_else(|e| { + // println!("This is error for signature {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }); + // log::info!("This is signature for sending signature {:?}", sig); + } + // let futures = + // instructions.iter().map(|tx| rpc.send_and_confirm_transaction(tx)); + // let signatures = join_all(futures).await; + // for sig in signatures { + // println!(" Signature Chunking Signature {:?}", sig); + // } + let ix = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(2_000_000u32)) + .instruction(ComputeBudgetInstruction::request_heap_frame(256 * 1024)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(50_000)) + .accounts(solana_ibc::accounts::Deliver { + sender: authority.pubkey(), + receiver: Some(self.solana_ibc_program_id), + storage: solana_ibc_storage_key, + trie: trie_key, + chain: chain_key, + system_program: system_program::ID, + mint_authority: Some(self.solana_ibc_program_id), + token_mint: Some(self.solana_ibc_program_id), + escrow_account: Some(self.solana_ibc_program_id), + fee_collector: Some(self.get_fee_collector_key()), + receiver_token_account: Some(self.solana_ibc_program_id), + associated_token_program: Some(self.solana_ibc_program_id), + token_program: Some(self.solana_ibc_program_id), + }) + .accounts(vec![ + AccountMeta { + pubkey: signatures_account_pda, + is_signer: false, + is_writable: true, + }, + AccountMeta { pubkey: chunk_account, is_signer: false, is_writable: true }, + ]) + .args(ix_data_account::Instruction) + .signer(&*authority) + .instructions() + .unwrap(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let transactions = + Transaction::new_with_payer(ix.as_slice(), Some(&authority.pubkey())); + // .send() + // .await + // .or_else(|e| { + // println!("This is error {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }); + let accounts = vec![ + AccountMeta { pubkey: authority.pubkey(), is_signer: true, is_writable: true }, + AccountMeta { + pubkey: signatures_account_pda, + is_signer: false, + is_writable: true, + }, + ]; + let mut data = vec![1, 0]; + data.extend(&bump.to_le_bytes()); + let instruction = Instruction::new_with_bytes( + self.signature_verifier_program_id, + &data, + accounts, + ); + let tx = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(100_000)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(50_000)) + .instruction(instruction) + .payer(authority) + .transaction() + .unwrap(); + // .send() + // .await.or_else(|e| { + // println!("This is error {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }); + // log::info!("This is signature for freeing signature {:?}", sig); + // signature + Ok((signature_chunking_txs, vec![transactions, tx])) + }, + DeliverIxType::Recv { ref token, ref port_id, ref channel_id, ref receiver } => { + log::info!( + "PortId: {:?} and channel {:?} and token {:?}", + port_id, + channel_id, + token + ); + let (escrow_account, token_mint, receiver_account, receiver_address) = + get_accounts( + token.denom.clone(), + self.solana_ibc_program_id, + receiver, + port_id, + channel_id, + &self.rpc_client(), + false, + ) + .await + .map_or( + ( + Some(self.solana_ibc_program_id), + Some(self.solana_ibc_program_id), + Some(self.solana_ibc_program_id), + Some(self.solana_ibc_program_id), + ), + |v| v, + ); + log::info!("This is token mint while sending transfer {:?}", token_mint); + let mint_authority = self.get_mint_auth_key(); + let ix = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(2_000_000u32)) + .instruction(ComputeBudgetInstruction::request_heap_frame(256 * 1024)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(500000)) + .accounts(solana_ibc::ix_data_account::Accounts::new( + solana_ibc::accounts::Deliver { + sender: authority.pubkey(), + receiver: receiver_account, + storage: solana_ibc_storage_key, + trie: trie_key, + chain: chain_key, + system_program: system_program::ID, + mint_authority: Some(mint_authority), + token_mint, + escrow_account, + fee_collector: Some(self.get_fee_collector_key()), + receiver_token_account: receiver_address, + associated_token_program: Some(anchor_spl::associated_token::ID), + token_program: Some(anchor_spl::token::ID), + }, + chunk_account, + )) + .args(ix_data_account::Instruction) + .signer(&*authority) + .instructions() + .unwrap(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let transactions = + Transaction::new_with_payer(ix.as_slice(), Some(&authority.pubkey())); + Ok((vec![], vec![transactions])) + // .send() + // .await + // .or_else(|e| { + // println!("This is error {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }) + }, + DeliverIxType::Timeout { + ref token, + ref port_id, + ref channel_id, + ref sender_account, + } => { + log::info!( + "PortId: {:?} and channel {:?} and token {:?}", + port_id, + channel_id, + token + ); + let (escrow_account, token_mint, sender_account, sender_address) = get_accounts( + token.denom.clone(), + self.solana_ibc_program_id, + &sender_account, + port_id, + channel_id, + &self.rpc_client(), + true, + ) + .await + .map_or( + ( + Some(self.solana_ibc_program_id), + Some(self.solana_ibc_program_id), + Some(self.solana_ibc_program_id), + Some(self.solana_ibc_program_id), + ), + |v| v, + ); + log::info!("This is token mint while sending transfer {:?}", token_mint); + let mint_authority = self.get_mint_auth_key(); + let ix = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(2_000_000u32)) + .instruction(ComputeBudgetInstruction::request_heap_frame(256 * 1024)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(50_000)) + .accounts(solana_ibc::ix_data_account::Accounts::new( + solana_ibc::accounts::Deliver { + sender: authority.pubkey(), + receiver: sender_account, + storage: solana_ibc_storage_key, + trie: trie_key, + chain: chain_key, + system_program: system_program::ID, + mint_authority: Some(mint_authority), + token_mint, + escrow_account, + fee_collector: Some(self.get_fee_collector_key()), + receiver_token_account: sender_address, + associated_token_program: Some(anchor_spl::associated_token::ID), + token_program: Some(anchor_spl::token::ID), + }, + chunk_account, + )) + .args(ix_data_account::Instruction) + .signer(&*authority) + .instructions() + .unwrap(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let transactions = + Transaction::new_with_payer(ix.as_slice(), Some(&authority.pubkey())); + Ok((vec![], vec![transactions])) + // .send() + // .await + // .or_else(|e| { + // println!("This is error {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }) + }, + DeliverIxType::Acknowledgement { sender } => { + let ix = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(2_000_000u32)) + .instruction(ComputeBudgetInstruction::request_heap_frame(256 * 1024)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(50_000)) + .accounts(solana_ibc::ix_data_account::Accounts::new( + solana_ibc::accounts::Deliver { + sender: authority.pubkey(), + receiver: Some(sender), + storage: solana_ibc_storage_key, + trie: trie_key, + chain: chain_key, + system_program: system_program::ID, + mint_authority: Some(self.solana_ibc_program_id), + fee_collector: Some(self.get_fee_collector_key()), + token_mint: Some(self.solana_ibc_program_id), + escrow_account: Some(self.solana_ibc_program_id), + receiver_token_account: Some(self.solana_ibc_program_id), + associated_token_program: Some(self.solana_ibc_program_id), + token_program: Some(self.solana_ibc_program_id), + }, + chunk_account, + )) + // .args(solana_ibc::instruction::Deliver { message: message.clone() }) + .args(ix_data_account::Instruction) + .signer(&*authority) + .instructions() + .unwrap(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let transactions = + Transaction::new_with_payer(ix.as_slice(), Some(&authority.pubkey())); + let mut cloned_tx = transactions.clone(); + cloned_tx.sign(&[&*authority], blockhash); + // let serialized_tx = bincode::serialize(&cloned_tx).unwrap(); + // // encode in base 58 + // let encoded_tx = bs58::encode(serialized_tx).into_string(); + // log::info!("Encoded tx {:?}", encoded_tx); + // while i < 10 { + // let result = rpc.simulate_transaction(&transactions).await; + // log::info!("result {:?}", result); + // sleep(Duration::from_secs(2)); + // } + Ok((vec![], vec![transactions])) + // .send() + // .await + // .or_else(|e| { + // println!("This is error {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }) + }, + DeliverIxType::Normal => { + let jito_address = + Pubkey::from_str("96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5").unwrap(); + let ix = program + .request() + // .instruction(anchor_lang::solana_program::system_instruction::transfer( + // &authority.pubkey(), + // &jito_address, + // 400000, + // )) + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(2_000_000u32)) + .instruction(ComputeBudgetInstruction::request_heap_frame(128 * 1024)) + // .instruction(ComputeBudgetInstruction::set_compute_unit_price(50_000)) + .accounts(solana_ibc::ix_data_account::Accounts::new( + solana_ibc::accounts::Deliver { + sender: authority.pubkey(), + receiver: Some(self.solana_ibc_program_id), + storage: solana_ibc_storage_key, + trie: trie_key, + chain: chain_key, + system_program: system_program::ID, + mint_authority: Some(self.solana_ibc_program_id), + fee_collector: Some(self.get_fee_collector_key()), + token_mint: Some(self.solana_ibc_program_id), + escrow_account: Some(self.solana_ibc_program_id), + receiver_token_account: Some(self.solana_ibc_program_id), + associated_token_program: Some(self.solana_ibc_program_id), + token_program: Some(self.solana_ibc_program_id), + }, + chunk_account, + )) + .args(ix_data_account::Instruction) + .payer(authority.clone()) + .signer(&*authority) + .instructions() + .unwrap(); + + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let transactions = + Transaction::new_with_payer(ix.as_slice(), Some(&authority.pubkey())); + Ok((vec![], vec![transactions])) + // .send_with_spinner_and_config(RpcSendTransactionConfig { + // skip_preflight: true, + // ..Default::default() + // }) + // .await + // .or_else(|e| { + // println!("This is error {:?}", e); + // status = false; + // ibc::prelude::Err("Error".to_owned()) + // }), + }, + } + + // if status { + // let blockhash = rpc.get_latest_blockhash().await.unwrap(); + // // Wait for finalizing the transaction + // let _ = rpc + // .confirm_transaction_with_spinner( + // &sig.clone().unwrap(), + // &blockhash, + // CommitmentConfig::finalized(), + // ) + // .await + // .unwrap(); + // signature = sig.unwrap().to_string(); + // break + // } + // sleep(Duration::from_millis(500)); + // tries += 1; + // } + // if tries == max_tries { + // log::info!("Max retries reached for normal tx in solana"); + // } + // Ok(signature) + } + + pub async fn send_transfer_inner( + &self, + msg: MsgTransfer, + ) -> Result<::TransactionId, Error> { + let keypair = self.keybase.keypair(); + println!("submitting tx now, {}", keypair.pubkey()); + let authority = Arc::new(keypair); + let program = self.program(); + + // Build, sign, and send program instruction + let solana_ibc_storage_key = self.get_ibc_storage_key(); + let trie_key = self.get_trie_key(); + let chain_key = self.get_chain_key(); + + let mint_authority = self.get_mint_auth_key(); + + let channel_id = + ibc_core_host_types::identifiers::ChannelId::new(msg.source_channel.sequence()); + let port_id = + ibc_core_host_types::identifiers::PortId::from_str(msg.source_port.as_str()).unwrap(); + // let trace_path = TracePrefix::new(port_id.clone(), channel_id.clone()); + let prefixed_denom = ibc_app_transfer_types::PrefixedDenom { + // TODO(dhruv): implement conversion + trace_path: ibc_app_transfer_types::TracePath::default(), + base_denom: ibc_app_transfer_types::BaseDenom::from_str( + msg.token.denom.base_denom.as_str(), + ) + .unwrap(), + }; + let token = ibc_app_transfer_types::PrefixedCoin { + denom: prefixed_denom, + amount: ibc_app_transfer_types::Amount::from(msg.token.amount.as_u256().0), + }; + let hashed_denom = CryptoHash::digest(&token.denom.base_denom.as_str().as_bytes()); + let (escrow_account, token_mint) = + if is_sender_chain_source(port_id.clone(), channel_id.clone(), &token.denom) { + let escrow_seeds = ["escrow".as_bytes(), hashed_denom.as_ref()]; + let escrow_account = + Pubkey::find_program_address(&escrow_seeds, &self.solana_ibc_program_id).0; + // let prefix = TracePrefix::new(port_id.clone(), channel_id.clone()); + let base_denom = token.denom.base_denom.clone(); + // trace_path.remove_prefix(&prefix); + log::info!( + "This is base denom {:?} and trace path {:?}", + base_denom, + token.denom.trace_path + ); + let token_mint = Pubkey::from_str(&base_denom.to_string()).unwrap(); + (Some(escrow_account), token_mint) + } else { + let token_mint_seeds = ["mint".as_bytes(), hashed_denom.as_ref()]; + let token_mint = + Pubkey::find_program_address(&token_mint_seeds, &self.solana_ibc_program_id).0; + (None, token_mint) + }; + + let sender_token_address = get_associated_token_address( + &Pubkey::from_str(msg.sender.as_ref()).unwrap(), + &token_mint, + ); + let packet_data = ibc_app_transfer_types::packet::PacketData { + token, + sender: ibc_new_primitives::Signer::from(msg.sender.as_ref().to_string()), + receiver: ibc_new_primitives::Signer::from(msg.receiver.as_ref().to_string()), + memo: ibc_app_transfer_types::Memo::from(msg.memo), + }; + + let new_msg_transfer = ibc_app_transfer_types::msgs::transfer::MsgTransfer { + port_id_on_a: port_id.clone(), + chan_id_on_a: channel_id.clone(), + packet_data, + timeout_height_on_b: ibc_core_channel_types::timeout::TimeoutHeight::At( + ibc_core_client_types::Height::new( + msg.timeout_height.revision_number, + msg.timeout_height.revision_height, + ) + .unwrap(), + ), + timeout_timestamp_on_b: ibc_new_primitives::Timestamp::from_nanoseconds( + msg.timeout_timestamp.nanoseconds(), + ) + .unwrap(), + }; + + let sig = program + .request() + .instruction(ComputeBudgetInstruction::set_compute_unit_limit(2_000_000u32)) + .accounts(solana_ibc::accounts::SendTransfer { + sender: authority.pubkey(), + receiver: Some(authority.pubkey()), + storage: solana_ibc_storage_key, + trie: trie_key, + chain: chain_key, + system_program: system_program::ID, + mint_authority: Some(mint_authority), + token_mint: Some(token_mint), + escrow_account, + fee_collector: Some(self.get_fee_collector_key()), + receiver_token_account: Some(sender_token_address), + token_program: Some(anchor_spl::token::ID), + }) + .args(solana_ibc::instruction::SendTransfer { + hashed_full_denom: hashed_denom, + msg: new_msg_transfer, + }) + // .payer(Arc::new(keypair)) + .signer(&*authority) + .send_with_spinner_and_config(RpcSendTransactionConfig { + skip_preflight: true, + ..Default::default() + }) + .await + .unwrap(); + let rpc = program.async_rpc(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + // Wait for finalizing the transaction + let _ = rpc + .confirm_transaction_with_spinner(&sig, &blockhash, CommitmentConfig::finalized()) + .await + .unwrap(); + let signature = sig.to_string(); + Ok(signature) + } +} + +pub async fn get_accounts( + denom: PrefixedDenom, + program_id: Pubkey, + receiver: &String, + port_id: &ibc_core_host_types::identifiers::PortId, + channel_id: &ibc_core_host_types::identifiers::ChannelId, + rpc: &AsyncRpcClient, + refund: bool, +) -> Result<(Option, Option, Option, Option), ParsePubkeyError> { + if Pubkey::from_str(&denom.base_denom.to_string()).is_ok() { + log::info!("Receiver chain source"); + let hashed_denom = CryptoHash::digest(denom.base_denom.as_str().as_bytes()); + let escrow_seeds = ["escrow".as_bytes(), hashed_denom.as_ref()]; + let escrow_account = Pubkey::find_program_address(&escrow_seeds, &program_id).0; + let token_mint = Pubkey::from_str(&denom.base_denom.to_string())?; + let receiver_account = Pubkey::from_str(&receiver)?; + let receiver_address = get_associated_token_address(&receiver_account, &token_mint); + Ok((Some(escrow_account), Some(token_mint), Some(receiver_account), Some(receiver_address))) + } else { + log::info!("Not receiver chain source"); + let mut full_token = denom.clone(); + if !refund { + full_token.add_trace_prefix(TracePrefix::new(port_id.clone(), channel_id.clone())); + } + let hashed_denom = CryptoHash::digest(full_token.to_string().as_bytes()); + let token_mint_seeds = ["mint".as_bytes(), hashed_denom.as_ref()]; + let token_mint = Pubkey::find_program_address(&token_mint_seeds, &program_id).0; + let receiver_account = Pubkey::from_str(&receiver)?; + let receiver_address = get_associated_token_address(&receiver_account, &token_mint); + let token_mint_info = rpc.get_token_supply(&token_mint).await; + if token_mint_info.is_err() { + return Err(ParsePubkeyError::Invalid); + } + Ok((Some(program_id), Some(token_mint), Some(receiver_account), Some(receiver_address))) + } +} + +// #[test] +// fn test_fetch() { +// let tx_id = +// "33s9BBJyp5jy9dnuwTa4uEiNvzygCrroVr1z8ZNRSG25LDcqAbdKMHXC9emx1Q1ktfgKUbKqFMiqfKioWFx8JesD" +// .to_string(); +// let authority = Rc::new( +// Keypair::from_bytes(&vec![ +// 48, 123, 8, 80, 248, 0, 217, 142, 124, 193, 95, 24, 168, 139, 214, 136, 147, 210, 168, +// 135, 26, 36, 162, 89, 150, 185, 99, 191, 247, 135, 78, 111, 12, 8, 4, 81, 129, 165, +// 153, 230, 192, 225, 51, 119, 216, 14, 69, 225, 73, 7, 204, 144, 39, 213, 91, 255, 136, +// 38, 95, 131, 197, 4, 101, 186, +// ]) +// .unwrap(), +// ); +// let client = AnchorClient::new_with_options( +// Cluster::Devnet, +// authority.clone(), +// CommitmentConfig::processed(), +// ); +// let program = client +// .program(Pubkey::from_str("9FeHRJLHJSEw4dYZrABHWTRKruFjxDmkLtPmhM5WFYL7").unwrap()) +// .unwrap(); +// let signature = Signature::from_str(&tx_id).unwrap(); +// let sol_rpc_client = program.rpc(); +// let tx = sol_rpc_client.get_transaction(&signature, UiTransactionEncoding::Json).unwrap(); +// println!("This is tx {:?}", tx); +// } diff --git a/hyperspace/solana/src/client_state.rs b/hyperspace/solana/src/client_state.rs new file mode 100644 index 000000000..fbadcaa9b --- /dev/null +++ b/hyperspace/solana/src/client_state.rs @@ -0,0 +1,172 @@ +use std::str::FromStr; + +use ibc::{ + core::{ + ics02_client::trust_threshold::TrustThreshold, ics23_commitment::specs::ProofSpecs, + ics24_host::identifier::ChainId, + }, + mock::header::MockHeader, + Height, +}; +use ibc_proto_new::ibc::lightclients::tendermint::v1::{ClientState, Fraction}; +use pallet_ibc::light_clients::AnyClientState; +use tendermint_proto::Protobuf; + +pub fn convert_new_client_state_to_old( + client_state: solana_ibc::client_state::AnyClientState, +) -> AnyClientState { + match client_state { + solana_ibc::client_state::AnyClientState::Tendermint(client) => { + let inner_client = client.inner(); + log::info!("This is latest height on solana {:?}", inner_client.latest_height); + AnyClientState::Tendermint(ics07_tendermint::client_state::ClientState { + chain_id: ChainId::from_str(inner_client.chain_id.as_str()).unwrap(), + trust_level: TrustThreshold::new( + inner_client.trust_level.numerator(), + inner_client.trust_level.denominator(), + ) + .unwrap(), + trusting_period: inner_client.trusting_period, + unbonding_period: inner_client.unbonding_period, + max_clock_drift: inner_client.max_clock_drift, + latest_height: Height::new( + inner_client.latest_height.revision_number(), + inner_client.latest_height.revision_height(), + ), + proof_specs: ProofSpecs::cosmos(), // Not sure about this + upgrade_path: inner_client.upgrade_path.clone(), + frozen_height: inner_client.frozen_height.and_then(|height| { + Some(Height::new(height.revision_number(), height.revision_height())) + }), + _phantom: std::marker::PhantomData, + }) + }, + // solana_ibc::client_state::AnyClientState::Mock(client) => + // AnyClientState::Mock(ibc::mock::client_state::MockClientState { + // header: MockHeader { + // height: Height::new( + // client.header.height.revision_number(), + // client.header.height.revision_height(), + // ), + // timestamp: ibc::timestamp::Timestamp::from_nanoseconds( + // client.header.timestamp.nanoseconds(), + // ) + // .unwrap(), + // }, + // frozen_height: client.frozen_height.and_then(|height| { + // Some(Height::new(height.revision_number(), height.revision_height())) + // }), + // }), + solana_ibc::client_state::AnyClientState::Wasm(_) => unimplemented!(), + } +} + +pub fn convert_old_client_state_to_new( + client_state: AnyClientState, +) -> solana_ibc::client_state::AnyClientState { + match client_state { + #[allow(deprecated)] + AnyClientState::Tendermint(cs) => solana_ibc::client_state::AnyClientState::Tendermint( + ClientState { + chain_id: cs.chain_id.to_string(), + trust_level: Some(Fraction { + numerator: cs.trust_level.numerator(), + denominator: cs.trust_level.denominator(), + }), + trusting_period: Some(cs.trusting_period.into()), + unbonding_period: Some(cs.unbonding_period.into()), + max_clock_drift: Some(cs.max_clock_drift.into()), + frozen_height: cs.frozen_height.map_or( + Some(ibc_proto_new::ibc::core::client::v1::Height { + revision_height: 0, + revision_number: 0, + }), + |height| { + Some(ibc_proto_new::ibc::core::client::v1::Height { + revision_number: height.revision_number, + revision_height: height.revision_height, + }) + }, + ), + latest_height: Some(ibc_proto_new::ibc::core::client::v1::Height { + revision_number: cs.latest_height.revision_number, + revision_height: cs.latest_height.revision_height, + }), + proof_specs: ibc_core_commitment_types::specs::ProofSpecs::cosmos().into(), + upgrade_path: cs.upgrade_path, + allow_update_after_expiry: false, + allow_update_after_misbehaviour: false, + } + .try_into() + .unwrap(), + ), + // AnyClientState::Mock(cs) => + // solana_ibc::client_state::AnyClientState::Mock(MockClientState { + // header: ibc_testkit::testapp::ibc::clients::mock::header::MockHeader { + // height: ibc_core_client_types::Height::new( + // cs.header.height().revision_number, + // cs.header.height().revision_height, + // ) + // .unwrap(), + // timestamp: ibc_new_primitives::Timestamp::from_nanoseconds( + // cs.header.timestamp.nanoseconds(), + // ) + // .unwrap(), + // }, + // frozen_height: cs.frozen_height.and_then(|height| { + // Some( + // ibc_core_client_types::Height::new( + // height.revision_number, + // height.revision_height, + // ) + // .unwrap(), + // ) + // }), + // }), + #[allow(deprecated)] + AnyClientState::Wasm(cs) => { + let cs = AnyClientState::decode_vec(&cs.data).unwrap(); + println!("This is tendermint\n {:?}", cs); + match cs { + AnyClientState::Tendermint(e) => { + log::info!( + "This is default {:?}", + ibc_core_commitment_types::specs::ProofSpecs::cosmos() + ); + log::info!("This is from client state {:?}", e.proof_specs); + solana_ibc::client_state::AnyClientState::Tendermint( + ClientState { + chain_id: e.chain_id.to_string(), + trust_level: Some(Fraction { + numerator: e.trust_level.numerator(), + denominator: e.trust_level.denominator(), + }), + trusting_period: Some(e.trusting_period.into()), + unbonding_period: Some(e.unbonding_period.into()), + max_clock_drift: Some(e.max_clock_drift.into()), + frozen_height: e.frozen_height.and_then(|height| { + Some(ibc_proto_new::ibc::core::client::v1::Height { + revision_number: height.revision_number, + revision_height: height.revision_height, + }) + }), + latest_height: Some(ibc_proto_new::ibc::core::client::v1::Height { + revision_number: e.latest_height.revision_number, + revision_height: e.latest_height.revision_height, + }), + proof_specs: ibc_core_commitment_types::specs::ProofSpecs::cosmos() + .into(), + upgrade_path: e.upgrade_path, + allow_update_after_expiry: false, + allow_update_after_misbehaviour: false, + } + .try_into() + .unwrap(), + ) + }, + _ => panic!("Invalid state {:?}", cs), + } + }, + _ => panic!("Client state not supported"), + } +} diff --git a/hyperspace/solana/src/consensus_state.rs b/hyperspace/solana/src/consensus_state.rs new file mode 100644 index 000000000..9f986dbfd --- /dev/null +++ b/hyperspace/solana/src/consensus_state.rs @@ -0,0 +1,89 @@ +use ibc::core::ics23_commitment::commitment::CommitmentRoot; +use ibc_proto_new::{ + google::protobuf::Timestamp, ibc::lightclients::tendermint::v1::ConsensusState, +}; +use pallet_ibc::light_clients::AnyConsensusState; +use tendermint::Hash; + +pub fn convert_new_consensus_state_to_old( + consensus_state: solana_ibc::consensus_state::AnyConsensusState, +) -> AnyConsensusState { + match consensus_state { + solana_ibc::consensus_state::AnyConsensusState::Tendermint(cs) => { + let timestamp_in_secs = cs.timestamp().unix_timestamp(); + let remaining_timestamp_in_nano = + (cs.timestamp().unix_timestamp_nanos() % 1_000_000_000) as u32; + AnyConsensusState::Tendermint(ics07_tendermint::consensus_state::ConsensusState { + timestamp: tendermint::time::Time::from_unix_timestamp( + timestamp_in_secs, + remaining_timestamp_in_nano, + ) + .unwrap(), + root: CommitmentRoot { bytes: cs.inner().root.as_bytes().to_vec() }, + next_validators_hash: Hash::try_from(cs.next_validators_hash().as_bytes().to_vec()) + .unwrap(), + }) + }, + // solana_ibc::consensus_state::AnyConsensusState::Mock(cs) => + // AnyConsensusState::Mock(ibc::mock::client_state::MockConsensusState { + // header: MockHeader { + // height: Height::new( + // cs.header.height.revision_number(), + // cs.header.height.revision_height(), + // ), + // timestamp: ibc::timestamp::Timestamp::from_nanoseconds( + // cs.header.timestamp.nanoseconds(), + // ) + // .unwrap(), + // }, + // root: CommitmentRoot { bytes: cs.root.into_vec() }, + // }), + solana_ibc::consensus_state::AnyConsensusState::Wasm(_) => + panic!("Guest consensus not supported"), + } +} + +pub fn convert_old_consensus_state_to_new( + consensus_state: AnyConsensusState, +) -> solana_ibc::consensus_state::AnyConsensusState { + match consensus_state { + AnyConsensusState::Tendermint(cs) => { + let timestamp_in_secs = cs.timestamp.unix_timestamp(); + let remaining_timestamp_in_nano = + (cs.timestamp.unix_timestamp_nanos() % 1_000_000_000) as i32; + solana_ibc::consensus_state::AnyConsensusState::Tendermint( + ConsensusState { + timestamp: Some(Timestamp { + seconds: timestamp_in_secs, + nanos: remaining_timestamp_in_nano, + }), + root: Some(ibc_proto_new::ibc::core::commitment::v1::MerkleRoot { + hash: cs.root.bytes, + }), + next_validators_hash: cs.next_validators_hash.as_bytes().to_vec(), + } + .try_into() + .unwrap(), + ) + }, + // AnyConsensusState::Mock(cs) => solana_ibc::consensus_state::AnyConsensusState::Mock( + // ibc_testkit::testapp::ibc::clients::mock::consensus_state::MockConsensusState { + // header: ibc_testkit::testapp::ibc::clients::mock::header::MockHeader { + // height: ibc_core_client_types::Height::new( + // cs.header.height().revision_number, + // cs.header.height().revision_height, + // ) + // .unwrap(), + // timestamp: ibc_new_primitives::Timestamp::from_nanoseconds( + // cs.header.timestamp.nanoseconds(), + // ) + // .unwrap(), + // }, + // root: ibc_core_commitment_types::commitment::CommitmentRoot::from_bytes( + // cs.root.as_bytes(), + // ), + // }, + // ), + _ => panic!("Client state not supported"), + } +} diff --git a/hyperspace/solana/src/error.rs b/hyperspace/solana/src/error.rs new file mode 100644 index 000000000..770ff56d7 --- /dev/null +++ b/hyperspace/solana/src/error.rs @@ -0,0 +1,34 @@ +use ibc::timestamp::ParseTimestampError; +use prost::DecodeError; + +/// Error definitions for the cosmos client in accordance with the parachain's Error type. +#[derive(thiserror::Error, Debug)] +pub enum Error { + /// An error from the rpc interface + #[error("Rpc client error: {0}")] + RpcError(String), + /// Custom error + #[error("{0}")] + Custom(String), + /// Decode error + #[error("Decode error: {0}")] + DecodeError(#[from] DecodeError), + /// Encode error + #[error("Encode error: {0}")] + EncodeError(#[from] prost::EncodeError), + /// Parse timestamp error + #[error("Parse timestamp error: {0}")] + ParseTimestampError(#[from] ParseTimestampError), + /// Transfer error + #[error("IBC transfer error: {0}")] + TransferError(#[from] ibc::applications::transfer::error::Error), + /// Tendermint error + #[error("Tendermint error: {0}")] + TendermintError(#[from] tendermint::Error), +} + +impl From for Error { + fn from(error: String) -> Self { + Self::Custom(error) + } +} diff --git a/hyperspace/solana/src/events.rs b/hyperspace/solana/src/events.rs new file mode 100644 index 000000000..a565d3771 --- /dev/null +++ b/hyperspace/solana/src/events.rs @@ -0,0 +1,863 @@ +use anchor_client::{ + solana_client::{ + nonblocking::rpc_client::RpcClient, rpc_client::GetConfirmedSignaturesForAddress2Config, + }, + solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey}, +}; +use guestchain::{BlockHeader, Signature as SignatureTrait}; +use lib::hash::CryptoHash; +use serde::{Deserialize, Serialize}; +use solana_ibc::events::Epoch; +use solana_transaction_status::EncodedConfirmedTransactionWithStatusMeta; +use std::str::FromStr; +use tokio::runtime::Runtime; + +use base64::Engine; +use ibc::{ + core::{ + ics02_client::{ + client_state::ClientType, + events::{ + Attributes as ClientAttributes, ClientMisbehaviour, CreateClient, UpdateClient, + UpgradeClient, + }, + }, + ics03_connection::events::{ + Attributes as ConnAttributes, OpenAck as ConnOpenAck, OpenConfirm as ConnOpenConfirm, + OpenInit as ConnOpenInit, OpenTry as ConnOpenTry, + }, + ics04_channel::{ + events::{ + AcknowledgePacket, CloseConfirm as ChanCloseConfirm, CloseInit as ChanCloseInit, + OpenAck as ChanOpenAck, OpenConfirm as ChanOpenConfirm, OpenInit as ChanOpenInit, + OpenTry as ChanOpenTry, ReceivePacket, SendPacket, TimeoutPacket, + WriteAcknowledgement, + }, + packet::{Packet, Sequence}, + }, + ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}, + ics26_routing::context::ModuleId, + }, + events::{IbcEvent, ModuleEvent, ModuleEventAttribute}, + timestamp::Timestamp, + Height, +}; +use pallet_ibc::light_clients::Signature; + +use crate::utils::skip_fail; + +pub fn convert_new_event_to_old( + event: ibc_core_handler_types::events::IbcEvent, + height: Height, +) -> Option { + match event { + ibc_core_handler_types::events::IbcEvent::CreateClient(e) => { + let eve = CreateClient(ClientAttributes { + height: Height { + revision_number: e.consensus_height().revision_number(), + revision_height: e.consensus_height().revision_height(), + }, + client_id: ClientId::from_str(e.client_id().as_str()).unwrap(), + client_type: ClientType::from_str(e.client_type().as_str()).unwrap(), + consensus_height: Height { + revision_number: e.consensus_height().revision_number(), + revision_height: e.consensus_height().revision_height(), + }, + }); + Some(IbcEvent::CreateClient(eve)) + }, + ibc_core_handler_types::events::IbcEvent::UpdateClient(e) => { + let eve = UpdateClient { + common: ClientAttributes { + height: Height { + revision_number: e.consensus_height().revision_number(), + revision_height: e.consensus_height().revision_height(), + }, + client_id: ClientId::from_str(e.client_id().as_str()).unwrap(), + client_type: ClientType::from_str(e.client_type().as_str()).unwrap(), + consensus_height: Height { + revision_number: e.consensus_height().revision_number(), + revision_height: e.consensus_height().revision_height(), + }, + }, + header: Some(e.header().clone()), + }; + Some(IbcEvent::UpdateClient(eve)) + }, + ibc_core_handler_types::events::IbcEvent::UpgradeClient(e) => { + let eve = UpgradeClient(ClientAttributes { + height: Height { + revision_number: e.consensus_height().revision_number(), + revision_height: e.consensus_height().revision_height(), + }, + client_id: ClientId::from_str(e.client_id().as_str()).unwrap(), + client_type: ClientType::from_str(e.client_type().as_str()).unwrap(), + consensus_height: Height { + revision_number: e.consensus_height().revision_number(), + revision_height: e.consensus_height().revision_height(), + }, + }); + Some(IbcEvent::UpgradeClient(eve)) + }, + ibc_core_handler_types::events::IbcEvent::ClientMisbehaviour(e) => { + let eve = ClientMisbehaviour(ClientAttributes { + height, + client_id: ClientId::from_str(e.client_id().as_str()).unwrap(), + client_type: ClientType::from_str(e.client_type().as_str()).unwrap(), + consensus_height: height, + }); + Some(IbcEvent::ClientMisbehaviour(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenInitConnection(e) => { + let eve = ConnOpenInit(ConnAttributes { + height, + client_id: ClientId::from_str(e.client_id_on_a().as_str()).unwrap(), + counterparty_client_id: ClientId::from_str(e.client_id_on_b().as_str()).unwrap(), + counterparty_connection_id: e + .conn_id_on_b() + .and_then(|conn| Some(ConnectionId::from_str(conn.as_str()).unwrap())), + connection_id: Some(ConnectionId::from_str(e.conn_id_on_a().as_str()).unwrap()), + }); + Some(IbcEvent::OpenInitConnection(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenTryConnection(e) => { + let eve = ConnOpenTry(ConnAttributes { + height, + client_id: ClientId::from_str(e.client_id_on_b().as_str()).unwrap(), + counterparty_client_id: ClientId::from_str(e.client_id_on_b().as_str()).unwrap(), + counterparty_connection_id: e.conn_id_on_a().and_then(|conn_id| { + Some(ConnectionId::from_str(conn_id.clone().as_str()).unwrap()) + }), + connection_id: Some( + ConnectionId::from_str(e.conn_id_on_b().clone().as_str()).unwrap(), + ), + }); + Some(IbcEvent::OpenTryConnection(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenAckConnection(e) => { + let eve = ConnOpenAck(ConnAttributes { + height, + client_id: ClientId::from_str(e.client_id_on_a().as_str()).unwrap(), + counterparty_client_id: ClientId::from_str(e.client_id_on_b().as_str()).unwrap(), + counterparty_connection_id: e + .conn_id_on_b() + .and_then(|conn| Some(ConnectionId::from_str(conn.as_str()).unwrap())), + connection_id: Some(ConnectionId::from_str(e.conn_id_on_a().as_str()).unwrap()), + }); + Some(IbcEvent::OpenAckConnection(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenConfirmConnection(e) => { + let eve = ConnOpenConfirm(ConnAttributes { + height, + client_id: ClientId::from_str(e.client_id_on_a().as_str()).unwrap(), + counterparty_client_id: ClientId::from_str(e.client_id_on_b().as_str()).unwrap(), + counterparty_connection_id: Some( + ConnectionId::from_str(e.conn_id_on_b().as_str()).unwrap(), + ), + connection_id: e + .conn_id_on_a() + .and_then(|conn| Some(ConnectionId::from_str(conn.as_str()).unwrap())), + }); + Some(IbcEvent::OpenConfirmConnection(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenInitChannel(e) => { + let eve = ChanOpenInit { + height, + port_id: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + channel_id: Some(ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap()), + connection_id: ConnectionId::from_str(e.conn_id_on_a().as_str()).unwrap(), + counterparty_port_id: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + counterparty_channel_id: None, + }; + Some(IbcEvent::OpenInitChannel(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenTryChannel(e) => { + let eve = ChanOpenTry { + height, + port_id: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + channel_id: Some(ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap()), + connection_id: ConnectionId::from_str(e.conn_id_on_b().as_str()).unwrap(), + counterparty_port_id: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + counterparty_channel_id: None, + }; + Some(IbcEvent::OpenTryChannel(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenAckChannel(e) => { + let eve = ChanOpenAck { + height, + port_id: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + channel_id: Some(ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap()), + connection_id: ConnectionId::from_str(e.conn_id_on_a().as_str()).unwrap(), + counterparty_port_id: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + counterparty_channel_id: None, + }; + Some(IbcEvent::OpenAckChannel(eve)) + }, + ibc_core_handler_types::events::IbcEvent::OpenConfirmChannel(e) => { + let eve = ChanOpenConfirm { + height, + port_id: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + channel_id: Some(ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap()), + connection_id: ConnectionId::from_str(e.conn_id_on_b().as_str()).unwrap(), + counterparty_port_id: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + counterparty_channel_id: None, + }; + Some(IbcEvent::OpenConfirmChannel(eve)) + }, + ibc_core_handler_types::events::IbcEvent::CloseInitChannel(e) => { + let eve = ChanCloseInit { + height, + port_id: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + channel_id: ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap(), + connection_id: ConnectionId::from_str(e.conn_id_on_a().as_str()).unwrap(), + counterparty_port_id: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + counterparty_channel_id: None, + }; + Some(IbcEvent::CloseInitChannel(eve)) + }, + ibc_core_handler_types::events::IbcEvent::CloseConfirmChannel(e) => { + let eve = ChanCloseConfirm { + height, + port_id: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + channel_id: Some(ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap()), + connection_id: ConnectionId::from_str(e.conn_id_on_b().as_str()).unwrap(), + counterparty_port_id: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + counterparty_channel_id: None, + }; + Some(IbcEvent::CloseConfirmChannel(eve)) + }, + ibc_core_handler_types::events::IbcEvent::SendPacket(e) => { + let eve = SendPacket { + height, + packet: Packet { + sequence: Sequence(e.seq_on_a().value()), + source_port: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + source_channel: ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap(), + destination_port: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + destination_channel: ChannelId::from_str(e.chan_id_on_b().as_str()).unwrap(), + data: e.packet_data().to_vec(), + timeout_height: match e.timeout_height_on_b() { + ibc_core_channel_types::timeout::TimeoutHeight::Never => + Height { revision_height: 0, revision_number: 0 }, + ibc_core_channel_types::timeout::TimeoutHeight::At(h) => Height { + revision_height: h.revision_height(), + revision_number: h.revision_number(), + }, + }, + timeout_timestamp: Timestamp::from_nanoseconds( + e.timeout_timestamp_on_b().nanoseconds(), + ) + .unwrap(), + }, + }; + Some(IbcEvent::SendPacket(eve)) + }, + ibc_core_handler_types::events::IbcEvent::ReceivePacket(e) => { + let eve = ReceivePacket { + height, + packet: Packet { + sequence: Sequence(e.seq_on_b().value()), + source_port: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + source_channel: ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap(), + destination_port: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + destination_channel: ChannelId::from_str(e.chan_id_on_b().as_str()).unwrap(), + data: e.packet_data().to_vec(), + timeout_height: match e.timeout_height_on_b() { + ibc_core_channel_types::timeout::TimeoutHeight::Never => + Height { revision_height: 0, revision_number: 0 }, + ibc_core_channel_types::timeout::TimeoutHeight::At(h) => Height { + revision_height: h.revision_height(), + revision_number: h.revision_number(), + }, + }, + timeout_timestamp: Timestamp::from_nanoseconds( + e.timeout_timestamp_on_b().nanoseconds(), + ) + .unwrap(), + }, + }; + Some(IbcEvent::ReceivePacket(eve)) + }, + ibc_core_handler_types::events::IbcEvent::WriteAcknowledgement(e) => { + let eve = WriteAcknowledgement { + height, + packet: Packet { + sequence: Sequence(e.seq_on_a().value()), + source_port: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + source_channel: ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap(), + destination_port: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + destination_channel: ChannelId::from_str(e.chan_id_on_b().as_str()).unwrap(), + data: e.packet_data().to_vec(), + timeout_height: match e.timeout_height_on_b() { + ibc_core_channel_types::timeout::TimeoutHeight::Never => + Height { revision_height: 0, revision_number: 0 }, + ibc_core_channel_types::timeout::TimeoutHeight::At(h) => Height { + revision_height: h.revision_height(), + revision_number: h.revision_number(), + }, + }, + timeout_timestamp: Timestamp::from_nanoseconds( + e.timeout_timestamp_on_b().nanoseconds(), + ) + .unwrap(), + }, + ack: e.acknowledgement().as_bytes().to_vec(), + }; + Some(IbcEvent::WriteAcknowledgement(eve)) + }, + ibc_core_handler_types::events::IbcEvent::AcknowledgePacket(e) => { + let eve = AcknowledgePacket { + height, + packet: Packet { + sequence: Sequence(e.seq_on_a().value()), + source_port: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + source_channel: ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap(), + destination_port: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + destination_channel: ChannelId::from_str(e.chan_id_on_b().as_str()).unwrap(), + data: Vec::new(), + timeout_height: match e.timeout_height_on_b() { + ibc_core_channel_types::timeout::TimeoutHeight::Never => + Height { revision_height: 0, revision_number: 0 }, + ibc_core_channel_types::timeout::TimeoutHeight::At(h) => Height { + revision_height: h.revision_height(), + revision_number: h.revision_number(), + }, + }, + timeout_timestamp: Timestamp::from_nanoseconds( + e.timeout_timestamp_on_b().nanoseconds(), + ) + .unwrap(), + }, + }; + Some(IbcEvent::AcknowledgePacket(eve)) + }, + ibc_core_handler_types::events::IbcEvent::TimeoutPacket(e) => { + let eve = TimeoutPacket { + height, + packet: Packet { + sequence: Sequence(e.seq_on_a().value()), + source_port: PortId::from_str(e.port_id_on_a().as_str()).unwrap(), + source_channel: ChannelId::from_str(e.chan_id_on_a().as_str()).unwrap(), + destination_port: PortId::from_str(e.port_id_on_b().as_str()).unwrap(), + destination_channel: ChannelId::from_str(e.chan_id_on_b().as_str()).unwrap(), + data: Vec::new(), // Not sure about this + timeout_height: match e.timeout_height_on_b() { + ibc_core_channel_types::timeout::TimeoutHeight::Never => + Height { revision_height: 0, revision_number: 0 }, + ibc_core_channel_types::timeout::TimeoutHeight::At(h) => Height { + revision_height: h.revision_height(), + revision_number: h.revision_number(), + }, + }, + timeout_timestamp: Timestamp::from_nanoseconds( + e.timeout_timestamp_on_b().nanoseconds(), + ) + .unwrap(), + }, + }; + Some(IbcEvent::TimeoutPacket(eve)) + }, + ibc_core_handler_types::events::IbcEvent::ChannelClosed(_) => None, + ibc_core_handler_types::events::IbcEvent::Module(e) => { + let attributes: Vec = e + .attributes + .iter() + .map(|attr| ModuleEventAttribute { + key: attr.clone().key, + value: attr.clone().value, + }) + .collect(); + let eve = ModuleEvent { + kind: e.kind, + module_name: ModuleId::from_str("transfer").unwrap(), + attributes, + }; + Some(IbcEvent::AppModule(eve)) + }, + ibc_core_handler_types::events::IbcEvent::Message(_) => None, + } +} + +pub fn get_ibc_events_from_logs( + logs: Vec, +) -> (Vec, u64) { + let (events, proof_height) = get_events_from_logs(logs); + let events: Vec = events + .iter() + .filter_map(|event| match event { + solana_ibc::events::Event::IbcEvent(e) => Some(e.clone()), + _ => None, + }) + .collect(); + (events, proof_height) +} + +pub async fn get_client_state_at_height( + rpc: RpcClient, + program_id: Pubkey, + upto_height: u64, +) -> Option { + log::info!("Getting client states at height {:?}", upto_height); + let mut before_hash = None; + let mut current_height = upto_height; + while current_height >= upto_height { + let (transactions, last_searched_hash) = + get_previous_transactions(&rpc, program_id, before_hash, SearchIn::IBC).await; + if transactions.is_empty() { + break; + } + before_hash = Some( + anchor_client::solana_sdk::signature::Signature::from_str(&last_searched_hash).unwrap(), + ); + for tx in transactions { + let logs = match tx.result.transaction.meta.clone().unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(e) => e, + _ => Vec::new(), + }; + let (events, height) = get_events_from_logs(logs); + let client_state_events: Vec = events + .iter() + .filter_map(|event| match event { + solana_ibc::events::Event::ClientStateUpdate(e) => Some(e.clone()), + _ => None, + }) + .collect(); + current_height = height; + if height == 0 || client_state_events.is_empty() { + continue; + } + log::info!("Found height {:?}", height); + if height < upto_height { + break; + } + // There can be only one client state event in a tx + let current_client_state = &client_state_events[0]; + let any_client_state: solana_ibc::client_state::AnyClientState = + borsh::BorshDeserialize::try_from_slice(current_client_state.state.as_ref()) + .unwrap(); + log::info!("This is any client state {:?}", any_client_state); + return Some(any_client_state); + } + } + None +} + +pub fn get_events_from_logs(logs: Vec) -> (Vec>, u64) { + let serialized_events: Vec<&str> = logs + .iter() + .filter_map(|log| { + if log.starts_with("Program data: ") { + Some(log.strip_prefix("Program data: ").unwrap()) + } else { + None + } + }) + .collect(); + let height_str = logs + .iter() + .find_map(|log| { + if log.starts_with("Program log: Current Block height ") { + Some(log.strip_prefix("Program log: Current Block height ").unwrap()) + } else { + None + } + }) + .map_or("0", |height| height); + let height = height_str.parse::().unwrap(); + let events: Vec = serialized_events + .iter() + .map(|event| { + let decoded_event = base64::prelude::BASE64_STANDARD.decode(event).unwrap(); + let decoded_event: solana_ibc::events::Event = + borsh::BorshDeserialize::try_from_slice(&decoded_event).unwrap(); + decoded_event + }) + .collect(); + (events, height) +} + +pub async fn _get_signatures_for_blockhash( + rpc: RpcClient, + program_id: Pubkey, + blockhash: CryptoHash, +) -> Result<(Vec<(Pubkey, Signature)>, BlockHeader), String> { + let (transactions, _) = + get_previous_transactions(&rpc, program_id, None, SearchIn::GuestChain).await; + + let mut signatures = Vec::new(); + // let mut index = 0; + for tx in transactions { + let logs = match tx.result.transaction.meta.clone().unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(e) => e, + _ => Vec::new(), + }; + let (events, _proof_height) = get_events_from_logs(logs); + // Find block signed events with blockhash + let block_header: Vec> = events + .iter() + .map(|event| match event { + solana_ibc::events::Event::NewBlock(e) => { + println!("This is new block event {:?}", e.block_header.0.block_height); + let new_blockhash = e.block_header.0.calc_hash(); + if blockhash == new_blockhash { + println!("New block event where it is true"); + return Some(e.block_header.0.clone()); + } + None + }, + solana_ibc::events::Event::BlockSigned(e) => { + println!("This is block signed event {:?}", e.block_height); + if e.block_hash == blockhash { + println!("This is block signed in side blockhash"); + signatures.push(( + Pubkey::new_from_array(e.pubkey.clone().into()), + Signature::from_bytes(&e.signature.to_vec()).unwrap(), + )) + }; + None + }, + _ => None, + }) + .collect(); + if let Some(header) = block_header.iter().find(|b| b.is_some()) { + return Ok((signatures, header.clone().unwrap())); + } + } + Err("Couldnt find blocks".to_string()) +} + +pub async fn get_header_from_height( + rpc: RpcClient, + program_id: Pubkey, + height: u64, +) -> Option { + log::info!("Getting header for height {}", height); + let mut before_hash = None; + let mut block_header = None; + while block_header.is_none() { + let (transactions, last_searched_hash) = + get_previous_transactions(&rpc, program_id, before_hash, SearchIn::GuestChain).await; + if transactions.is_empty() { + break; + } + before_hash = Some( + anchor_client::solana_sdk::signature::Signature::from_str(&last_searched_hash).unwrap(), + ); + log::info!("THis is before hash {:?} {:?}", before_hash, last_searched_hash); + for tx in transactions { + let logs = match tx.result.transaction.meta.clone().unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(e) => e, + _ => Vec::new(), + }; + let (events, _proof_height) = get_events_from_logs(logs); + // Find block signed events with blockhash + block_header = events.iter().find_map(|event| match event { + solana_ibc::events::Event::NewBlock(e) => { + println!( + "This is new block event when fetching for height {:?}", + e.block_header.0.block_height + ); + let block_height = u64::from(e.block_header.0.block_height); + if block_height == height { + println!("New block event where it is true for height {:?}", height); + return Some(e.block_header.0.clone()); + } + None + }, + _ => None, + }); + if block_header.is_some() { + return block_header; + } + } + } + block_header +} + +pub async fn get_signatures_upto_height( + rpc: RpcClient, + program_id: Pubkey, + upto_height: u64, +) -> ( + Vec<( + Vec<(Pubkey, Signature)>, + BlockHeader, + Option>, + )>, + Vec, +) { + let mut current_height = upto_height; + let mut before_hash = None; + let mut all_signatures = Vec::new(); + let mut all_block_headers = Vec::new(); + let mut all_ibc_events = Vec::new(); + // let mut finalized_heights = Vec::new(); + log::info!("This is upto height {:?}", upto_height); + while current_height >= upto_height { + let (transactions, last_searched_hash) = + get_previous_transactions(&rpc, program_id, before_hash, SearchIn::GuestChain).await; + if transactions.is_empty() { + break; + } + before_hash = Some( + anchor_client::solana_sdk::signature::Signature::from_str(&last_searched_hash).unwrap(), + ); + for tx in transactions { + let transaction_err = tx.result.transaction.meta.clone().unwrap().err; + if transaction_err.is_some() { + // match tx.result.transaction.transaction { + // solana_transaction_status::EncodedTransaction::Json(e) => { + // println!("Error in transaction {:?}", e.signatures); + // }, + // _ => panic!("WTF") + // } + continue; + } + let logs = match tx.result.transaction.meta.clone().unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(e) => e, + _ => Vec::new(), + }; + let (events, _proof_height) = get_events_from_logs(logs.clone()); + let (ibc_events, _) = get_ibc_events_from_logs(logs); + all_ibc_events.extend(ibc_events); + for event in events { + match event { + solana_ibc::events::Event::NewBlock(e) => { + println!( + "This is new block event when fetching for height {:?}", + e.block_header.0.block_height + ); + let block_height = u64::from(e.block_header.0.block_height); + current_height = block_height; + if block_height >= upto_height { + all_block_headers.push((e.block_header.0.clone(), e.epoch)); + } else { + log::info!("breaking out of upto height"); + } + }, + solana_ibc::events::Event::BlockSigned(e) => { + all_signatures.push(e); + }, + // solana_ibc::events::Event::BlockFinalised(e) => { + // let block_height = u64::from(e.block_height); + // finalized_heights.push(block_height); + // }, + _ => (), + } + } + if current_height < upto_height { + break; + } + } + } + ( + all_block_headers + .iter() + .filter_map(|(b, epoch)| { + let signatures_for_header: Vec<_> = all_signatures + .iter() + .filter_map(|s| { + if s.block_height == b.block_height { + Some(( + Pubkey::new_from_array(s.pubkey.clone().into()), + Signature::from_bytes(&s.signature.to_vec()).unwrap(), + )) + } else { + None + } + }) + .collect(); + if signatures_for_header.is_empty() { + return None; + } + let epoch = epoch.as_ref().and_then(|e| Some(e.0.clone())); + Some((signatures_for_header, b.clone(), epoch)) + }) + .collect(), + all_ibc_events, + ) +} + +pub async fn get_previous_transactions( + rpc: &RpcClient, + program_id: Pubkey, + before_hash: Option, + search_in: SearchIn, +) -> (Vec, String) { + let search_address = match search_in { + SearchIn::IBC => { + let storage_seeds = &[solana_ibc::SOLANA_IBC_STORAGE_SEED]; + Pubkey::find_program_address(storage_seeds, &program_id).0 + }, + SearchIn::GuestChain => program_id, + }; + let transaction_signatures = rpc + .get_signatures_for_address_with_config( + &search_address, // Since ibc storage is only used for ibc and not for guest chain + GetConfirmedSignaturesForAddress2Config { + limit: Some(200), + before: before_hash, + commitment: Some(CommitmentConfig::confirmed()), + ..Default::default() + }, + ) + .await + .unwrap(); + if transaction_signatures.is_empty() { + return (vec![], before_hash.map_or("".to_string(), |sig| sig.to_string())); + } + let last_searched_hash = transaction_signatures + .last() + .map_or("".to_string(), |sig| sig.signature.clone()); + let mut body = vec![]; + for sig in transaction_signatures { + let signature = sig.signature.clone(); + let payload = Payload { + jsonrpc: "2.0".to_string(), + id: 1 as u64, + method: "getTransaction".to_string(), + params: ( + signature, + Param { commitment: "confirmed".to_string(), maxSupportedTransactionVersion: 0 }, + ), + }; + body.push(payload); + } + let url = rpc.url(); + tokio::task::spawn_blocking(move || { + for _ in 0..5 { + let response = reqwest::blocking::Client::new().post(url.clone()).json(&body).send(); + let response = skip_fail!(response); + let response: std::result::Result, reqwest::Error> = response.json(); + let transactions = skip_fail!(response); + return (transactions, last_searched_hash); + } + log::error!("Couldnt get transactions after 5 retries"); + (vec![], "".to_string()) + }) + .await + .unwrap() +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Payload { + jsonrpc: String, + id: u64, + method: String, + params: (String, Param), +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Param { + commitment: String, + maxSupportedTransactionVersion: u16, +} + +pub enum SearchIn { + IBC, + GuestChain, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Response { + pub jsonrpc: String, + pub id: u64, + pub result: EncodedConfirmedTransactionWithStatusMeta, +} + +#[test] +pub fn testing_signatures() { + println!("I am testing signatures"); + let rpc = RpcClient::new( + "https://mainnet.helius-rpc.com/?api-key=65520d87-04b2-43a5-b5d5-35d5db0601b3".to_string(), + ); + let program_id = Pubkey::from_str("2HLLVco5HvwWriNbUhmVwA2pCetRkpgrqwnjcsZdyTKT").unwrap(); + let upto_height = 116806; + println!("I am testing signatures"); + let signatures = + Runtime::new() + .unwrap() + .block_on(get_signatures_upto_height(rpc, program_id, upto_height)); + signatures.0.iter().for_each(|sig| { + println!("Height {}", sig.1.block_height); + }) +} + +#[tokio::test] +pub async fn testing_events_final() { + let rpc = RpcClient::new("http://127.0.0.1:8899".to_string()); + let mut last_hash = None; + loop { + let (events, prev) = get_previous_transactions( + &rpc, + Pubkey::from_str("9FeHRJLHJSEw4dYZrABHWTRKruFjxDmkLtPmhM5WFYL7").unwrap(), + last_hash, + SearchIn::IBC, + ) + .await; + if events.is_empty() { + println!("No events found"); + break; + } + println!("Received events {}", events.len()); + last_hash = Some(anchor_client::solana_sdk::signature::Signature::from_str(&prev).unwrap()); + } +} + +#[test] +pub fn testing_events() { + let events = vec![ + "Program data: ABUC".to_string(), + "Program data: AA+kAAAAeyJhbW91bnQiOiIxNjAwMDA4Mzk5NDAxNjg3NjgwIiwiZGVub20iOiJwcGljYSIsInJlY2VpdmVyIjoib3h5ekVzVWo5Q1Y2SHNxUENVWnFWd3JGSkp2cGQ5aUNCclBkelRCV0xCYiIsInNlbmRlciI6ImNlbnRhdXJpMWYwcm1kZnVmM2s4c3FubXJmYTBwbHQzeGdtM2xmeDR2cXU0dHA2In0BAQAAAAAAAAAGCAAAAAAAAAAaVjgvdcMXAQAAAAAAAAAIAAAAdHJhbnNmZXIKAAAAY2hhbm5lbC0xNQgAAAB0cmFuc2ZlcgkAAABjaGFubmVsLTABDAAAAGNvbm5lY3Rpb24tMA==".to_string(), + "Program data: ABUC".to_string(), + "Program data: ABCkAAAAeyJhbW91bnQiOiIxNjAwMDA4Mzk5NDAxNjg3NjgwIiwiZGVub20iOiJwcGljYSIsInJlY2VpdmVyIjoib3h5ekVzVWo5Q1Y2SHNxUENVWnFWd3JGSkp2cGQ5aUNCclBkelRCV0xCYiIsInNlbmRlciI6ImNlbnRhdXJpMWYwcm1kZnVmM2s4c3FubXJmYTBwbHQzeGdtM2xmeDR2cXU0dHA2In0BAQAAAAAAAAAGCAAAAAAAAAAaVjgvdcMXAQAAAAAAAAAIAAAAdHJhbnNmZXIKAAAAY2hhbm5lbC0xNQgAAAB0cmFuc2ZlcgkAAABjaGFubmVsLTARAAAAeyJyZXN1bHQiOiJBUT09In0MAAAAY29ubmVjdGlvbi0w".to_string(), + "Program data: ABQSAAAAZGVub21pbmF0aW9uX3RyYWNlAQAAAAUAAABkZW5vbRgAAAB0cmFuc2Zlci9jaGFubmVsLTAvcHBpY2E=".to_string(), + "Program data: ABQVAAAAZnVuZ2libGVfdG9rZW5fcGFja2V0BwAAAAYAAABtb2R1bGUIAAAAdHJhbnNmZXIGAAAAc2VuZGVyLwAAAGNlbnRhdXJpMWYwcm1kZnVmM2s4c3FubXJmYTBwbHQzeGdtM2xmeDR2cXU0dHA2CAAAAHJlY2VpdmVyKwAAAG94eXpFc1VqOUNWNkhzcVBDVVpxVndyRkpKdnBkOWlDQnJQZHpUQldMQmIFAAAAZGVub20FAAAAcHBpY2EGAAAAYW1vdW50EwAAADE2MDAwMDgzOTk0MDE2ODc2ODAEAAAAbWVtbwAAAAAHAAAAc3VjY2VzcwQAAAB0cnVl".to_string(), + ]; + let (eves, height) = get_events_from_logs(events); + eves.iter().for_each(|event| println!("{:?}", event)); + let seqs = vec![1]; + let port_id = PortId::transfer(); + let channel_id = ChannelId::new(15); + let recv_packet_events: Vec<_> = eves + .iter() + .filter_map(|tx| match tx { + solana_ibc::events::Event::IbcEvent(e) => match e { + ibc_core_handler_types::events::IbcEvent::WriteAcknowledgement(packet) => + if packet.chan_id_on_a().as_str() == &channel_id.to_string() && + packet.port_id_on_a().as_str() == port_id.as_str() && + seqs.iter().find(|&&seq| packet.seq_on_a().value() == seq).is_some() + { + println!("We found packet"); + Some(packet) + } else { + None + }, + _ => None, + }, + _ => None, + }) + .collect(); + // let client_state_logs: Vec<&str> = events + // .iter() + // .filter_map(|log| { + // if log.starts_with("Program logged: This is updated client state ") { + // Some(log.strip_prefix("Program logged: This is updated client state ").unwrap()) + // } else { + // None + // } + // }) + // .collect(); + // // There can be only one client state event in a tx + // let client_state_log = client_state_logs[0]; + // // Remove the square brackets and whitespace, then split the string into an iterator of &str, + // // each representing a byte. Then parse each &str to a u8 and collect into a Vec + // let bytes: Vec = client_state_log + // .trim_matches(|c: char| c == '[' || c == ']') // Trim the square brackets + // .split(", ") // Split the string into individual numbers + // .map(|s| s.parse::().unwrap()) // Convert each number from &str to u8 + // .collect(); // Collect into a Vec + // let any_client_state: solana_ibc::client_state::AnyClientState = + // borsh::BorshDeserialize::try_from_slice(bytes.as_slice()).unwrap(); + // println!("This is any client state {:?}", any_client_state); +} diff --git a/hyperspace/solana/src/lib.rs b/hyperspace/solana/src/lib.rs new file mode 100644 index 000000000..9d4fa3941 --- /dev/null +++ b/hyperspace/solana/src/lib.rs @@ -0,0 +1,2540 @@ +// #![feature(more_qualified_paths)] +extern crate alloc; + +use anchor_client::{ + solana_client::{rpc_client::RpcClient, rpc_config::RpcSendTransactionConfig}, + solana_sdk::{ + compute_budget::ComputeBudgetInstruction, + instruction::Instruction, + system_instruction::transfer, + transaction::{Transaction, VersionedTransaction}, + }, +}; +use anchor_spl::associated_token::get_associated_token_address; +use client::FinalityEvent; +use client_state::convert_new_client_state_to_old; +use consensus_state::convert_new_consensus_state_to_old; +use core::{pin::Pin, str::FromStr, time::Duration}; +use futures::future::join_all; +use guestchain::{BlockHeader, Epoch, PubKey, Validator}; +use ibc_core_channel_types::msgs::PacketMsg; +use ibc_core_client_types::msgs::ClientMsg; +use ibc_core_handler_types::msgs::MsgEnvelope; +use ics07_tendermint::{ + client_message::ClientMessage, client_state::ClientState as TmClientState, + consensus_state::ConsensusState as TmConsensusState, +}; +use msgs::convert_old_msgs_to_new; +use serde::{Deserialize, Serialize}; +use solana_transaction_status::UiTransactionEncoding; +use std::{num::NonZeroU128, ops::Deref, thread::sleep, time::Instant}; +use tendermint::{Hash, Time}; +use tendermint_proto::Protobuf; +use tokio::{ + sync::mpsc::unbounded_channel, + task::{spawn_blocking, JoinSet}, +}; + +use anchor_client::{ + solana_client::{ + pubsub_client::PubsubClient, + rpc_client::GetConfirmedSignaturesForAddress2Config, + rpc_config::{ + RpcBlockSubscribeConfig, RpcBlockSubscribeFilter, RpcTransactionLogsConfig, + RpcTransactionLogsFilter, + }, + }, + solana_sdk::{ + commitment_config::CommitmentConfig, signature::Signature, signer::Signer as AnchorSigner, + }, +}; +use anchor_lang::prelude::*; +use error::Error; +use ibc::{ + applications::transfer::{Amount, BaseDenom, PrefixedCoin, PrefixedDenom, TracePath}, + core::{ + ics02_client::{ + events::{NewBlock, UpdateClient}, + msgs::update_client::MsgUpdateAnyClient, + trust_threshold::TrustThreshold, + }, + ics23_commitment::specs::ProofSpecs, + ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId}, + ics26_routing::msgs::Ics26Envelope, + }, + events::IbcEvent, + timestamp::Timestamp, + tx_msg::Msg, + Height, +}; +use ibc_proto::{ + google::protobuf::Any, + ibc::core::{ + channel::v1::{ + Channel, Counterparty as ChanCounterparty, IdentifiedChannel, QueryChannelResponse, + QueryNextSequenceReceiveResponse, QueryPacketAcknowledgementResponse, + QueryPacketCommitmentResponse, QueryPacketReceiptResponse, + }, + client::v1::{QueryClientStateResponse, QueryConsensusStateResponse}, + connection::v1::{ + ConnectionEnd, Counterparty as ConnCounterparty, IdentifiedConnection, + QueryConnectionResponse, Version, + }, + }, +}; +use jito_protos::{ + convert::versioned_tx_from_packet, + searcher::{ + mempool_subscription, searcher_service_client::SearcherServiceClient, + ConnectedLeadersRegionedRequest, GetTipAccountsRequest, MempoolSubscription, + NextScheduledLeaderRequest, PendingTxNotification, ProgramSubscriptionV0, + SubscribeBundleResultsRequest, WriteLockedAccountSubscriptionV0, + }, +}; +use lib::hash::CryptoHash; +use pallet_ibc::light_clients::{AnyClientMessage, AnyClientState, AnyConsensusState}; +use primitives::{ + mock::LocalClientTypes, Chain, CommonClientState, IbcProvider, KeyProvider, LightClientSync, + MisbehaviourHandler, UndeliveredType, UpdateType, +}; +use solana_ibc::events::Event; +use std::{result::Result, sync::Arc}; +use tokio_stream::Stream; + +use solana_ibc::storage::{SequenceKind, Serialised}; + +use trie_ids::{ClientIdx, ConnectionIdx, PortChannelPK, Tag, TrieKey}; + +use crate::{ + client::TransactionSender, + events::{get_events_from_logs, SearchIn}, +}; +pub use crate::{ + client::{DeliverIxType, SolanaClient, SolanaClientConfig}, + events::convert_new_event_to_old, +}; + +pub mod client; +mod client_state; +mod consensus_state; +mod error; +mod events; +// mod jito; +mod msgs; +#[cfg(feature = "testing")] +mod test_provider; +mod utils; + +const SOLANA_IBC_STORAGE_SEED: &[u8] = b"private"; +const TRIE_SEED: &[u8] = b"trie"; +const CHAIN_SEED: &[u8] = b"chain"; +pub const NUMBER_OF_BLOCKS_TO_PROCESS_PER_ITER: u64 = 250; +pub const WRITE_ACCOUNT_SEED: &[u8] = b"write"; +pub const SIGNATURE_ACCOUNT_SEED: &[u8] = b"signature"; + +pub const BLOCK_ENGINE_URL: &str = "https://mainnet.block-engine.jito.wtf"; + +pub const MIN_TIME_UNTIL_UPDATE: u64 = 30 * 60; // 30 mins + +pub struct InnerAny { + pub type_url: String, + pub value: Vec, +} + +#[async_trait::async_trait] +impl IbcProvider for SolanaClient { + type FinalityEvent = FinalityEvent; + + type TransactionId = String; + + type AssetId = String; + + type Error = Error; + + async fn query_latest_ibc_events( + &mut self, + finality_event: Self::FinalityEvent, + counterparty: &T, + ) -> Result, primitives::UpdateType)>, anyhow::Error> + where + T: Chain, + { + log::info!("Came into solana lts events"); + let (finality_blockhash, finality_height) = match finality_event { + FinalityEvent::Guest { blockhash, block_height } => (blockhash, block_height), + }; + log::info!("This is solaan height {:?}", finality_height); + let client_id = self.client_id(); + let latest_cp_height = counterparty.latest_height_and_timestamp().await?.0; + log::info!("this is the latest cp height {:?}", latest_cp_height); + let latest_cp_client_state = + counterparty.query_client_state(latest_cp_height, client_id.clone()).await?; + let client_state_response = latest_cp_client_state + .client_state + .ok_or_else(|| Error::Custom("counterparty returned empty client state".to_string()))?; + log::info!("This is the type url in solana {:?}", client_state_response.type_url); + let AnyClientState::Guest(client_state) = + AnyClientState::decode_recursive(client_state_response.clone(), |c| { + matches!(c, AnyClientState::Guest(_)) + }) + .or_else(|| { + log::info!("This is wasm {:?}", client_state_response); + let wasm_client_state = + AnyClientState::decode_recursive(client_state_response, |c| { + matches!(c, AnyClientState::Wasm(_)) + }) + .unwrap(); + Some(wasm_client_state.unpack_recursive().clone()) + }) + .unwrap() + else { + unreachable!() + }; + log::info!("This is client state {:?}", client_state); + let latest_cp_client_height = u64::from(client_state.0.latest_height); + println!("This is counterparty client height {:?}", latest_cp_client_height); + let (all_signatures, new_block_events) = events::get_signatures_upto_height( + self.rpc_client(), + self.solana_ibc_program_id, + latest_cp_client_height + 1, + ) + .await; + + let earliest_block_header = all_signatures.last(); + + log::info!("This is all events {:?}", new_block_events); + let block_events: Vec = new_block_events + .iter() + .filter_map(|event| { + convert_new_event_to_old(event.clone(), Height::new(1, u64::from(finality_height))) + }) + .collect(); + + let chain_account = self.get_chain_storage().await; + let mut updates = Vec::new(); + let mut rev_all_signatures = all_signatures.clone(); + // Reversing so that updates are sent in ascending order of their height. + rev_all_signatures.reverse(); + for (signatures, block_header, epoch) in rev_all_signatures { + if (block_header.next_epoch_commitment.is_none() + && u64::from(block_header.block_height) != finality_height) + || epoch.is_none() + { + continue; + } + + let block_hash = block_header.calc_hash(); + let block_height: u64 = block_header.block_height.into(); + let validators = epoch.unwrap().validators().to_vec(); + let all_validators: Vec> = validators + .iter() + .map(|validator| { + let new_validator: Validator = + Validator::new( + PubKey::from_bytes(&validator.pubkey.to_vec()).unwrap(), + validator.stake, + ); + new_validator + }) + .collect(); + let final_signatures: Vec<_> = signatures + .iter() + .enumerate() + .map(|(index, (validator, signature))| { + let validator_idx = all_validators + .iter() + .position(|v| { + v.pubkey + == PubKey::from_bytes(&validator.to_bytes().as_slice()).unwrap() + }) + .unwrap(); + (validator_idx as u16, signature.clone()) + }) + .collect(); + let current_epoch = Epoch::new_with(all_validators, |total| { + let quorum = NonZeroU128::new(total.get() / 2 + 1).unwrap(); + // min_quorum_stake may be greater than total_stake so we’re not + // using .clamp to make sure we never return value higher than + // total_stake. + println!("THis is total {:?} and quorum {:?}", total, quorum); + quorum.max(NonZeroU128::new(1000).unwrap()).min(total) + }) + .unwrap(); + let guest_header = cf_guest_og::Header { + genesis_hash: chain_account.genesis().unwrap().clone(), + block_hash, + block_header: block_header.clone(), + epoch_commitment: current_epoch.calc_commitment(), + epoch: current_epoch, + signatures: final_signatures, + }; + log::info!( + "Height: {:?} signature {:?} and finality height {:?}", + block_height, + signatures, + finality_height + ); + let msg = MsgUpdateAnyClient:: { + client_id: self.client_id(), + client_message: AnyClientMessage::Guest(cf_guest::ClientMessage::from( + guest_header, + )), + signer: counterparty.account_id(), + }; + let value = msg.clone().encode_vec(); + log::info!("This is wihle update {:?}", value); + + let update = if u64::from(block_header.block_height) == finality_height { + let time_since_last_update = + if let Some(earliest_block_header) = earliest_block_header { + u64::from(block_header.timestamp_ns) + - u64::from(earliest_block_header.1.timestamp_ns) + } else { + 0 + }; + log::info!( + "TIme since last update on solana {}", + time_since_last_update / 1_000_000_000 + ); + if time_since_last_update > MIN_TIME_UNTIL_UPDATE * 1_000_000_000 { + log::info!("--------------------------PURPOSE UPDATE------------------------"); + } else { + log::info!("-----------------------NO UPDATE---------------------------"); + } + ( + Any { type_url: msg.type_url(), value }, + Height::new(1, finality_height), + block_events.clone(), + if !block_events.is_empty() + || time_since_last_update > MIN_TIME_UNTIL_UPDATE * 1_000_000_000 + { + UpdateType::Mandatory + } else { + UpdateType::Optional + }, + ) + } else { + log::info!("Mandatory update due to change in epoch"); + ( + Any { type_url: msg.type_url(), value }, + Height::new(1, block_height), + Vec::new(), + UpdateType::Mandatory, + ) + }; + updates.push(update); + } + Ok(updates) + } + + async fn ibc_events(&self) -> Pin + Send + 'static>> { + let (tx, rx) = unbounded_channel(); + let ws_url = self.ws_url.clone(); + let program_id = self.solana_ibc_program_id; + tokio::task::spawn_blocking(move || { + let (_logs_subscription, receiver) = PubsubClient::logs_subscribe( + &ws_url, + RpcTransactionLogsFilter::Mentions(vec![program_id.to_string()]), + RpcTransactionLogsConfig { commitment: Some(CommitmentConfig::finalized()) }, + ) + .unwrap(); + + loop { + match receiver.recv() { + Ok(logs) => { + let (events, proof_height) = + events::get_ibc_events_from_logs(logs.value.logs); + // log::info!("These are events {:?} ", events); + // log::info!("Total {:?} events", events.len()); + let mut broke = false; + events.iter().for_each(|event| { + log::info!("Came into ibc events"); + let height = Height::new(1, proof_height); + let converted_event = + events::convert_new_event_to_old(event.clone(), height); + if let Some(event) = converted_event { + log::info!("Sending message"); + tx.send(event.clone()).unwrap_or_else(|_| { + log::info!("Broke"); + broke = true; + }); + } + }); + if broke { + break; + } + }, + Err(err) => { + panic!("{}", format!("Disconnected: {err}")); + }, + } + } + }); + let streams = tokio_stream::wrappers::UnboundedReceiverStream::new(rx); + Box::pin(streams) + } + + async fn query_client_consensus( + &self, + at: Height, + client_id: ClientId, + consensus_height: Height, + ) -> Result { + use ibc_proto_new::Protobuf; + let (trie, at_height) = self.get_trie(at.revision_height + 1, true).await; + let storage = self.get_ibc_storage().await; + let revision_height = consensus_height.revision_height; + let revision_number = consensus_height.revision_number; + let new_client_id = + ibc_core_host_types::identifiers::ClientId::from_str(client_id.as_str()).unwrap(); + log::info!("query_client_consensus before trie key"); + let consensus_state_trie_key = TrieKey::for_consensus_state( + ClientIdx::try_from(new_client_id).unwrap(), + ibc_core_client_types::Height::new( + consensus_height.revision_number, + consensus_height.revision_height, + ) + .unwrap(), + ); + log::info!("query_client_consensus before prove trie"); + let (val, consensus_state_proof) = trie + .prove(&consensus_state_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + log::info!("query_client_consensus before search clients"); + let client_store = storage + .clients + .iter() + .find(|&client| client.client_id.as_str() == client_id.as_str()) + .ok_or( + "Client not found with the given client id while querying client consensus" + .to_owned(), + )?; + log::info!("query_client_consensus before get cs states"); + let serialized_consensus_state = client_store + .consensus_states + .get(&ibc_core_client_types::Height::new(revision_number, revision_height).unwrap()) + .ok_or(Error::Custom("No value at given key".to_owned()))?; + log::info!("query_client_consensus before convert cs states"); + let consensus_state = serialized_consensus_state + .state() + .map_err(|_| { + Error::Custom( + "Could not +deserialize consensus state" + .to_owned(), + ) + }) + .unwrap(); + log::info!("query_client_consensus before encode"); + let cs_state = convert_new_consensus_state_to_old(consensus_state.clone()); + let inner_any = consensus_state.clone().encode_vec(); + log::info!("this is consensus state {:?}", consensus_state); + log::info!("This is inner any consensus state {:?}", inner_any); + let chain_account = self.get_chain_storage().await; + let block_header = if !self.common_state.handshake_completed { + log::info!("Fetching previous block header"); + events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)) + } else { + log::info!("Fetching latest header"); + chain_account.head().unwrap().clone() + }; + // let block_header = chain_account.head().unwrap().clone(); + log::info!( + "proof {:?} state root {:?}, trie key {:?} and value {:?}", + consensus_state_proof, + block_header.state_root, + consensus_state_trie_key, + val + ); + let result = consensus_state_proof.verify( + &block_header.state_root, + &consensus_state_trie_key, + val.as_ref(), + ); + log::info!("Result {}", result); + Ok(QueryConsensusStateResponse { + consensus_state: Some(cs_state.into()), + proof: borsh::to_vec(&(block_header, &consensus_state_proof)).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_client_state( + &self, + at: Height, + client_id: ClientId, + ) -> Result { + log::info!("Quering solana client state at height {:?} {:?}", at, client_id); + let (trie, at_height) = self.get_trie(at.revision_height + 1, true).await; + let storage = self.get_ibc_storage().await; + let new_client_id = + ibc_core_host_types::identifiers::ClientId::from_str(client_id.as_str()).unwrap(); + let client_state_trie_key = + TrieKey::for_client_state(ClientIdx::try_from(new_client_id).unwrap()); + let (val, client_state_proof) = trie + .prove(&client_state_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + let client_state = events::get_client_state_at_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height + 1, + ) + .await + .unwrap_or_else(|| { + log::info!("Fetching latest client state"); + let client_store = storage + .clients + .iter() + .find(|&client| client.client_id.as_str() == client_id.as_str()) + .expect("Client not found with the given client id while querying client state"); + let serialized_client_state = &client_store.client_state; + serialized_client_state + .get() + .map_err(|_| { + Error::Custom( + "Could not +deserialize client state" + .to_owned(), + ) + }) + .unwrap() + }); + // let inner_any = client_state.clone().encode_vec(); + log::info!("this is client state {:?}", client_state); + // log::info!("This is inner any client state {:?}", inner_any); + let any_client_state = convert_new_client_state_to_old(client_state); + let chain_account = self.get_chain_storage().await; + let block_header = if !self.common_state.handshake_completed { + log::info!("Fetching previous block header"); + events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)) + } else { + log::info!("Fetching latest header"); + chain_account.head().unwrap().clone() + }; + // let block_header = chain_account.head().unwrap().clone(); + log::info!( + "proof {:?} state root {:?}, trie key {:?} and value {:?}", + client_state_proof, + block_header.state_root, + client_state_trie_key, + val + ); + let result = client_state_proof.verify( + &block_header.state_root, + &client_state_trie_key, + val.as_ref(), + ); + log::info!("Result {}", result); + Ok(QueryClientStateResponse { + client_state: Some(any_client_state.into()), + proof: borsh::to_vec(&(block_header, &client_state_proof)).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_connection_end( + &self, + at: Height, + connection_id: ConnectionId, + ) -> Result { + use ibc_proto_new::Protobuf; + let (trie, at_height) = self.get_trie(at.revision_height + 1, true).await; + let storage = self.get_ibc_storage().await; + let connection_idx = ConnectionIdx::try_from( + ibc_core_host_types::identifiers::ConnectionId::from_str(connection_id.as_str()) + .unwrap(), + ) + .unwrap(); + log::info!( + "This is connection ID {:?} and index {:?} while querying connection end", + connection_id, + connection_idx + ); + let connection_end_trie_key = TrieKey::for_connection(connection_idx); + log::info!("This is connection end trie key {:?}", connection_end_trie_key); + let (val, connection_end_proof) = trie + .prove(&connection_end_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + log::info!("This is serialized connection {:?}", storage.connections); + let serialized_connection_end = + storage.connections.get(usize::from(connection_idx)).ok_or( + "Connection not found with the given + client id" + .to_owned(), + )?; + let inner_connection_end = Serialised::get(serialized_connection_end) + .map_err(|_| { + Error::Custom( + "Could not + deserialize connection end" + .to_owned(), + ) + }) + .unwrap(); + log::info!("This is new connection end {:?}", inner_connection_end); + log::info!("Borsh serialized connection end {:?}", borsh::to_vec(&inner_connection_end)); + log::info!("This is in any {:?}", inner_connection_end.clone().encode_vec()); + log::info!("This is the hashed value {:?}", val); + let inner_any = inner_connection_end.clone().encode_vec(); + let inner_counterparty = inner_connection_end.counterparty(); + let connection_end = ConnectionEnd { + client_id: inner_connection_end.client_id().to_string(), + versions: inner_connection_end + .versions() + .to_vec() + .iter() + .map(|version| { + let raw_version = + ibc_proto_new::ibc::core::connection::v1::Version::from(version.clone()); + Version { identifier: raw_version.identifier, features: raw_version.features } + }) + .collect(), + state: inner_connection_end.state.into(), + counterparty: Some(ConnCounterparty { + client_id: inner_counterparty.client_id().to_string(), + connection_id: inner_counterparty + .connection_id + .as_ref() + .map_or_else(|| "".to_string(), |v| v.as_str().to_string()), + prefix: Some(ibc_proto::ibc::core::commitment::v1::MerklePrefix { + key_prefix: inner_counterparty.prefix().clone().into_vec(), + }), + }), + delay_period: inner_connection_end.delay_period().as_nanos() as u64, + }; + log::info!("This is after connection end {:?}", connection_end); + let chain_account = self.get_chain_storage().await; + let block_header = if !self.common_state.handshake_completed { + log::info!("Fetching previous block header"); + events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)) + } else { + log::info!("Fetching latest header"); + chain_account.head().unwrap().clone() + }; + // let block_header = chain_account.head().unwrap().clone(); + log::info!( + "proof {:?} state root {:?}, trie key {:?} and value {:?}", + connection_end_proof, + block_header.state_root, + connection_end_trie_key, + val + ); + log::info!("Block header {:?}", block_header); + let result = connection_end_proof.verify( + &block_header.state_root, + &connection_end_trie_key, + val.as_ref(), + ); + log::info!("Result {}", result); + log::info!("connection end {:?}", connection_end); + let mut proof = borsh::to_vec(&(block_header.clone(), &connection_end_proof)).unwrap(); + log::info!("This is proof {:?}", proof); + let (header, proof): (BlockHeader, sealable_trie::proof::Proof) = + borsh::BorshDeserialize::deserialize_reader(&mut &proof[..]).unwrap(); + log::info!("This is deserialized proof {:?}", proof); + Ok(QueryConnectionResponse { + connection: Some(connection_end), + proof: borsh::to_vec(&(block_header, &connection_end_proof)).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_channel_end( + &self, + at: Height, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + ) -> Result { + let (trie, at_height) = self.get_trie(at.revision_height, true).await; + let storage = self.get_ibc_storage().await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let channel_end_path = + PortChannelPK::try_from(new_port_id.clone(), new_channel_id.clone()).unwrap(); + let channel_end_trie_key = TrieKey::for_channel_end(&channel_end_path); + let (_, channel_end_proof) = trie + .prove(&channel_end_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + let inner_channel_end = storage + .port_channel + .deref() + .get(&channel_end_path) + .ok_or(Error::Custom("No value at given key".to_owned()))? + .channel_end() + .unwrap() + .ok_or(Error::Custom("Channel end not found".to_owned()))?; + let inner_counterparty = inner_channel_end.counterparty(); + let state = match inner_channel_end.state { + ibc_core_channel_types::channel::State::Uninitialized => 0, + ibc_core_channel_types::channel::State::Init => 1, + ibc_core_channel_types::channel::State::TryOpen => 2, + ibc_core_channel_types::channel::State::Open => 3, + ibc_core_channel_types::channel::State::Closed => 4, + }; + let ordering = match inner_channel_end.ordering { + ibc_core_channel_types::channel::Order::None => 0, + ibc_core_channel_types::channel::Order::Unordered => 1, + ibc_core_channel_types::channel::Order::Ordered => 2, + }; + let channel_end = Channel { + state, + ordering, + counterparty: Some(ChanCounterparty { + port_id: inner_counterparty.port_id.to_string(), + channel_id: if inner_counterparty.channel_id.is_none() { + "".to_owned() + } else { + inner_counterparty.channel_id.clone().unwrap().to_string() + }, + }), + connection_hops: inner_channel_end + .connection_hops + .iter() + .map(|connection_id| connection_id.to_string()) + .collect(), + version: inner_channel_end.version.to_string(), + }; + let block_header = if !self.common_state.handshake_completed { + log::info!("Fetching previous block header"); + events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)) + } else { + log::info!("Fetching latest block header"); + let chain_account = self.get_chain_storage().await; + chain_account.head().unwrap().clone() + }; + Ok(QueryChannelResponse { + channel: Some(channel_end), + proof: borsh::to_vec(&(block_header, &channel_end_proof)).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_proof(&self, at: Height, keys: Vec>) -> Result, Self::Error> { + log::info!("Querying proof at {:?}", at.revision_height); + log::info!("This is the bytes for keys {:?} ", keys); + let key_str = String::from_utf8(keys[0].clone()) + .map_err(|_| Error::Custom("Invalid key".to_owned()))?; + log::info!("This is the keys in string{:?}", key_str); + let split_keys = key_str.split("/").collect::>(); + let trie_key = match split_keys[0] { + "nextSequenceRecv" => { + let port_str = split_keys[2]; + let channel_str = split_keys[4]; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_str).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::from_str(channel_str).unwrap(); + let next_seq_recv_path = + PortChannelPK::try_from(new_port_id.clone(), new_channel_id.clone()).unwrap(); + TrieKey::for_next_sequence(&next_seq_recv_path) + }, + "receipts" => { + let port_str = split_keys[2]; + let channel_str = split_keys[4]; + let sequence_str = split_keys[6]; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_str).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::from_str(channel_str).unwrap(); + let new_seq = + ibc_core_host_types::identifiers::Sequence::from_str(sequence_str).unwrap(); + let packet_receipt_path = ibc_core_host_types::path::ReceiptPath { + port_id: new_port_id, + channel_id: new_channel_id, + sequence: new_seq, + }; + TrieKey::try_from(&packet_receipt_path).unwrap() + }, + "commitments" => { + log::info!("Entered commitments"); + let port_str = split_keys[2]; + let channel_str = split_keys[4]; + let sequence_str = split_keys[6]; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_str).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::from_str(channel_str).unwrap(); + let new_seq = + ibc_core_host_types::identifiers::Sequence::from_str(sequence_str).unwrap(); + let packet_commitment_path = ibc_core_host_types::path::CommitmentPath { + port_id: new_port_id, + channel_id: new_channel_id, + sequence: new_seq, + }; + TrieKey::try_from(&packet_commitment_path).unwrap() + }, + "acks" => { + let port_str = split_keys[2]; + let channel_str = split_keys[4]; + let sequence_str = split_keys[6]; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_str).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::from_str(channel_str).unwrap(); + let new_seq = + ibc_core_host_types::identifiers::Sequence::from_str(sequence_str).unwrap(); + let packet_ack_path = ibc_core_host_types::path::AckPath { + port_id: new_port_id, + channel_id: new_channel_id, + sequence: new_seq, + }; + TrieKey::try_from(&packet_ack_path).unwrap() + }, + "channelEnds" => { + let port_str = split_keys[2]; + let channel_str = split_keys[4]; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_str).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::from_str(channel_str).unwrap(); + let channel_end_path = + PortChannelPK::try_from(new_port_id.clone(), new_channel_id.clone()).unwrap(); + TrieKey::for_channel_end(&channel_end_path) + }, + _ => { + log::error!("invalid key in proof query proof"); + return Err(Error::Custom("Invalid key".to_owned())); + }, + }; + let (trie, at_height) = self.get_trie(at.revision_height, true).await; + let (val, proof) = trie + .prove(&trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + log::info!("This is proof {:?}", proof); + let chain_account = self.get_chain_storage().await; + let block_header_at_height = if at_height { + log::info!("Fetching block header at height"); + events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)) + } else { + log::info!("Block header not found at height, so fetching latest height"); + chain_account.head().unwrap().clone() + }; + let result = proof.verify(&block_header_at_height.state_root, &trie_key, val.as_ref()); + log::info!("latest Block header height {}", block_header_at_height.block_height); + log::info!("state root {:?}", &block_header_at_height.state_root); + log::info!("trie root {:?}", &trie.hash()); + log::info!("trie key {:?}", trie_key); + log::info!("Value {:?}", val.as_ref()); + log::info!("This is value in proof verify {:?}", val); + log::info!("This is result of time out packet proof verify lts {:?}", result); + Ok(borsh::to_vec(&(block_header_at_height.clone(), &proof)).unwrap()) + } + + async fn query_packet_commitment( + &self, + at: Height, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + seq: u64, + ) -> Result { + let (trie, at_height) = self.get_trie(at.revision_height, true).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let new_seq = ibc_core_host_types::identifiers::Sequence::from(seq); + let packet_commitment_path = ibc_core_host_types::path::CommitmentPath { + port_id: new_port_id, + channel_id: new_channel_id, + sequence: new_seq, + }; + let packet_commitment_trie_key = TrieKey::try_from(&packet_commitment_path).unwrap(); + let (packet_commitment, packet_commitment_proof) = trie + .prove(&packet_commitment_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + let commitment = + packet_commitment.ok_or(Error::Custom("No value at given key".to_owned()))?; + let block_header = events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)); + log::info!("This is packet commitment {:?}", commitment.0.to_vec()); + Ok(QueryPacketCommitmentResponse { + commitment: commitment.0.to_vec(), + proof: borsh::to_vec(&(block_header, &packet_commitment_proof)).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_packet_acknowledgement( + &self, + at: Height, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + seq: u64, + ) -> Result { + let (trie, at_height) = self.get_trie(at.revision_height, true).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let new_seq = ibc_core_host_types::identifiers::Sequence::from(seq); + let packet_ack_path = ibc_core_host_types::path::AckPath { + port_id: new_port_id, + channel_id: new_channel_id, + sequence: new_seq, + }; + let packet_ack_trie_key = TrieKey::try_from(&packet_ack_path).unwrap(); + let (packet_ack, packet_ack_proof) = trie + .prove(&packet_ack_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + let ack = packet_ack.ok_or(Error::Custom("No value at given key".to_owned()))?; + let (packet_ack, packet_ack_proof) = trie + .prove(&packet_ack_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + let ack = packet_ack.ok_or(Error::Custom("No value at given key".to_owned()))?; + let block_header = events::get_header_from_height( + self.rpc_client(), + self.solana_ibc_program_id, + at.revision_height, + ) + .await + .expect(&format!("No block header found for height {:?}", at.revision_height)); + log::info!("This is packet ack {:?}", ack.0.to_vec()); + Ok(QueryPacketAcknowledgementResponse { + acknowledgement: ack.0.to_vec(), + proof: borsh::to_vec(&(block_header, packet_ack_proof)).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_next_sequence_recv( + &self, + at: Height, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + ) -> Result { + let (trie, at_height) = self.get_trie(at.revision_height, true).await; + let storage = self.get_ibc_storage().await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let next_sequence_recv_path = PortChannelPK::try_from(new_port_id, new_channel_id).unwrap(); + let next_sequence_recv_trie_key = TrieKey::for_next_sequence(&next_sequence_recv_path); + let (_, next_sequence_recv_proof) = trie + .prove(&next_sequence_recv_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + let next_seq = &storage + .port_channel + .deref() + .get(&next_sequence_recv_path) + .ok_or(Error::Custom("No value at given key".to_owned()))? + .next_sequence; + let next_seq_recv = next_seq + .get(SequenceKind::Recv) + .ok_or(Error::Custom("No value set for the next sequence receive".to_owned()))?; + Ok(QueryNextSequenceReceiveResponse { + next_sequence_receive: next_seq_recv.into(), + proof: borsh::to_vec(&next_sequence_recv_proof).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn query_packet_receipt( + &self, + at: Height, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + seq: u64, + ) -> Result { + let (trie, at_height) = self.get_trie(at.revision_height, true).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let new_seq = ibc_core_host_types::identifiers::Sequence::from(seq); + let packet_recv_path = ibc_core_host_types::path::ReceiptPath { + port_id: new_port_id, + channel_id: new_channel_id, + sequence: new_seq, + }; + let packet_recv_trie_key = TrieKey::try_from(&packet_recv_path).unwrap(); + let (packet_recv, packet_recv_proof) = trie + .prove(&packet_recv_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + Ok(QueryPacketReceiptResponse { + received: packet_recv.is_some(), + proof: borsh::to_vec(&packet_recv_proof).unwrap(), + proof_height: Some(at.into()), + }) + } + + async fn latest_height_and_timestamp( + &self, + ) -> Result<(Height, ibc::timestamp::Timestamp), Self::Error> { + let chain = self.get_chain_storage().await; + let block_header = chain.head().unwrap(); + let height = block_header.block_height.into(); + let timestamp_ns: u64 = block_header.timestamp_ns.into(); + log::info!("THis is the timestamp and height of solana {:?} {:?}", timestamp_ns, height); + Ok((Height::new(1, height), Timestamp::from_nanoseconds(timestamp_ns).unwrap())) + } + + async fn query_packet_commitments( + &self, + at: Height, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + ) -> Result, Self::Error> { + let (trie, at_height) = self.get_trie(at.revision_height, false).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let trie_comp = PortChannelPK::try_from(new_port_id, new_channel_id).unwrap(); + let key = TrieKey::new(Tag::Commitment, trie_comp); + let sequences: Vec = trie + .get_subtrie(&key) + .unwrap() + .iter() + .map(|c| { + u64::from_be_bytes( + Vec::::try_from(c.sub_key.clone()).unwrap().as_slice().try_into().unwrap(), + ) + }) + .collect(); + Ok(sequences) + } + + async fn query_packet_acknowledgements( + &self, + at: Height, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + ) -> Result, Self::Error> { + let (trie, at_height) = self.get_trie(at.revision_height, false).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let trie_comp = PortChannelPK::try_from(new_port_id, new_channel_id).unwrap(); + let key = TrieKey::new(Tag::Ack, trie_comp); + let sequences: Vec = trie + .get_subtrie(&key) + .unwrap() + .iter() + .map(|c| { + u64::from_be_bytes( + Vec::::try_from(c.sub_key.clone()).unwrap().as_slice().try_into().unwrap(), + ) + }) + .collect(); + Ok(sequences) + } + + async fn query_unreceived_packets( + &self, + at: Height, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + seqs: Vec, + ) -> Result, Self::Error> { + log::info!("----------Unreceived packets seqs on solana {:?} ", seqs); + let (trie, at_height) = self.get_trie(at.revision_height, false).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let trie_comp = PortChannelPK::try_from(new_port_id, new_channel_id).unwrap(); + let key = TrieKey::new(Tag::Receipt, trie_comp); + let packet_receipt_sequences: Vec = trie + .get_subtrie(&key) + .unwrap() + .iter() + .map(|c| { + u64::from_be_bytes( + Vec::::try_from(c.sub_key.clone()).unwrap().as_slice().try_into().unwrap(), + ) + }) + .collect(); + Ok(seqs + .iter() + .flat_map(|&seq| { + match packet_receipt_sequences.iter().find(|&&receipt_seq| receipt_seq == seq) { + Some(_) => None, + None => Some(seq), + } + }) + .collect()) + } + + async fn query_unreceived_acknowledgements( + &self, + at: Height, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + seqs: Vec, + ) -> Result, Self::Error> { + let (trie, at_height) = self.get_trie(at.revision_height, false).await; + let new_port_id = + ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let trie_comp = PortChannelPK::try_from(new_port_id, new_channel_id).unwrap(); + let key = TrieKey::new(Tag::Commitment, trie_comp); + let packet_receipt_sequences: Vec = trie + .get_subtrie(&key) + .unwrap() + .iter() + .map(|c| { + u64::from_be_bytes( + Vec::::try_from(c.sub_key.clone()).unwrap().as_slice().try_into().unwrap(), + ) + }) + .collect(); + Ok(seqs + .iter() + .flat_map(|&seq| { + match packet_receipt_sequences.iter().find(|&&receipt_seq| receipt_seq == seq) { + Some(_) => Some(seq), + None => None, + } + }) + .collect()) + } + + fn channel_whitelist( + &self, + ) -> std::collections::HashSet<( + ibc::core::ics24_host::identifier::ChannelId, + ibc::core::ics24_host::identifier::PortId, + )> { + self.channel_whitelist.lock().unwrap().clone() + } + + /// We just return all the channels since there doesnt seem to be any kind of relation between + /// connection ID and channels. + async fn query_connection_channels( + &self, + at: Height, + _connection_id: &ConnectionId, + ) -> Result { + let storage = self.get_ibc_storage().await; + let channels: Vec = storage + .port_channel + .deref() + .into_iter() + .map(|(key, value)| { + let channel = value.channel_end().unwrap().unwrap(); + let state = match channel.state { + ibc_core_channel_types::channel::State::Uninitialized => 0, + ibc_core_channel_types::channel::State::Init => 1, + ibc_core_channel_types::channel::State::TryOpen => 2, + ibc_core_channel_types::channel::State::Open => 3, + ibc_core_channel_types::channel::State::Closed => 4, + }; + let ordering = match channel.ordering { + ibc_core_channel_types::channel::Order::None => 0, + ibc_core_channel_types::channel::Order::Unordered => 1, + ibc_core_channel_types::channel::Order::Ordered => 2, + }; + IdentifiedChannel { + state, + ordering, + counterparty: Some(ChanCounterparty { + port_id: channel.counterparty().port_id.to_string(), + channel_id: channel.counterparty().channel_id.clone().unwrap().to_string(), + }), + connection_hops: channel + .connection_hops + .iter() + .map(|connection_id| connection_id.to_string()) + .collect(), + version: channel.version.to_string(), + port_id: key.port_id().to_string(), + channel_id: key.channel_id().to_string(), + } + }) + .collect(); + Ok(ibc_proto::ibc::core::channel::v1::QueryChannelsResponse { + channels, + pagination: None, + height: Some(at.into()), + }) + } + + async fn query_send_packets( + &self, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + seqs: Vec, + ) -> Result, Self::Error> { + log::info!("Inside query send packets"); + let rpc_client = self.rpc_client(); + if seqs.is_empty() { + return Ok(Vec::new()); + } + let mut total_packets = Vec::new(); + let mut before_hash = None; + let maximum_sequence_number = seqs.iter().max().unwrap(); + let mut is_sequence_greater = false; + let mut is_maximum_seq_found = false; + while total_packets.len() < seqs.len() { + let (transactions, last_searched_hash) = events::get_previous_transactions( + &rpc_client, + self.solana_ibc_program_id, + before_hash, + SearchIn::IBC, + ) + .await; + before_hash = Some( + anchor_client::solana_sdk::signature::Signature::from_str(&last_searched_hash) + .unwrap(), + ); + let send_packet_events: Vec<_> = + transactions + .iter() + .filter_map(|tx| { + let logs = match tx.result.transaction.meta.clone().unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(e) => e, + _ => Vec::new(), + }; + let (events, _proof_height) = events::get_events_from_logs(logs.clone()); + let mut send_packet = None; + for event in events { + send_packet = match event { + solana_ibc::events::Event::IbcEvent(event) => match event { + ibc_core_handler_types::events::IbcEvent::SendPacket( + packet, + ) => { + if packet.chan_id_on_a().as_str() == &channel_id.to_string() + && packet.port_id_on_a().as_str() == port_id.as_str() + && seqs + .iter() + .find(|&&seq| packet.seq_on_a().value() == seq) + .is_some() + { + if *maximum_sequence_number == packet.seq_on_a().value() + { + is_maximum_seq_found = true; + } + log::info!( + "These are logs for send packet transaction {:?}", + logs + ); + let height_str = logs.iter().find_map(|log| { + if log.starts_with("Program log: Current Block height ") { + Some(log.strip_prefix("Program log: Current Block height ").unwrap()) + } else { + None + } + }).expect("No height found while fetching send packet event"); + log::info!("This is height_str {:?}", height_str); + let height = height_str.parse::().unwrap(); + return Some((packet.clone(), height + 1)); + } + if *maximum_sequence_number > packet.seq_on_a().value() { + is_sequence_greater = true; + } + None + }, + _ => None, + }, + _ => None, + }; + if send_packet.is_some() { + break; + } + } + send_packet + }) + .collect(); + if is_sequence_greater && !is_maximum_seq_found { + log::info!("Sequence number found in logs is lesser than the set of sequence which we are looking for"); + return Ok(Vec::new()); + } + let packets: Vec<_> = send_packet_events + .iter() + .map(|(packet, proof_height)| ibc_rpc::PacketInfo { + height: Some(proof_height.clone()), + sequence: packet.seq_on_a().value(), + source_port: packet.port_id_on_a().to_string(), + source_channel: packet.chan_id_on_a().to_string(), + destination_port: packet.port_id_on_b().to_string(), + destination_channel: packet.chan_id_on_b().to_string(), + channel_order: packet.channel_ordering().to_string(), + data: packet.packet_data().to_vec(), + timeout_height: Height { + revision_height: packet.timeout_height_on_b().commitment_revision_height(), + revision_number: packet.timeout_height_on_b().commitment_revision_number(), + } + .into(), + timeout_timestamp: packet.timeout_timestamp_on_b().nanoseconds(), + ack: None, + }) + .collect(); + total_packets.extend(packets); + } + log::info!("Found sent packets {:?}", total_packets); + Ok(total_packets) + } + + async fn query_received_packets( + &self, + channel_id: ibc::core::ics24_host::identifier::ChannelId, + port_id: ibc::core::ics24_host::identifier::PortId, + seqs: Vec, + ) -> Result, Self::Error> { + log::info!("Inside received packets"); + let rpc_client = self.rpc_client(); + if seqs.is_empty() { + return Ok(Vec::new()); + } + let maximum_sequence_number = seqs.iter().max().unwrap(); + let mut before_hash = None; + let mut total_packets = Vec::new(); + while total_packets.len() < seqs.len() { + let (transactions, last_searched_hash) = events::get_previous_transactions( + &rpc_client, + self.solana_ibc_program_id, + before_hash, + SearchIn::IBC, + ) + .await; + before_hash = Some( + anchor_client::solana_sdk::signature::Signature::from_str(&last_searched_hash) + .unwrap(), + ); + let mut is_sequence_greater = false; + let mut is_maximum_seq_found = false; + let recv_packet_events: Vec<_> = transactions + .iter() + .filter_map(|tx| { + let logs = match tx.result.transaction.meta.clone().unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(e) => e, + _ => Vec::new(), + }; + let (events, proof_height) = events::get_ibc_events_from_logs(logs.clone()); + let receive_packet_event = events.iter().find(|event| { + matches!( + event, + ibc_core_handler_types::events::IbcEvent::WriteAcknowledgement(_) + ) + }); + match receive_packet_event { + Some(e) => match e { + ibc_core_handler_types::events::IbcEvent::WriteAcknowledgement(packet) => + if packet.chan_id_on_b().as_str() == &channel_id.to_string() && + packet.port_id_on_b().as_str() == port_id.as_str() && + seqs.iter() + .find(|&&seq| packet.seq_on_a().value() == seq) + .is_some() + { + if *maximum_sequence_number == packet.seq_on_a().value() { + is_maximum_seq_found = true; + } + log::info!("Found receive packet"); + Some((e.clone(), proof_height + 1)) + } else { + if *maximum_sequence_number > packet.seq_on_a().value() { + is_sequence_greater = true; + } + log::info!("Receive Ids dont match expected channel id: {:?} got channel id: {:?} expect port id: {:?} got port id: {:?} expected seq: {:?} got seq: {:?}", packet.chan_id_on_b(), channel_id, packet.port_id_on_b(), port_id, seqs, packet.seq_on_a().value()); + None + }, + _ => None, + }, + None => None, + } + }) + .collect(); + if is_sequence_greater && !is_maximum_seq_found { + log::info!("Sequence number found in logs is lesser than the set of sequence which we are looking for"); + return Ok(Vec::new()); + } + let packets: Vec<_> = recv_packet_events + .iter() + .map(|(recv_packet, height)| match recv_packet { + ibc_core_handler_types::events::IbcEvent::WriteAcknowledgement(packet) => { + ibc_rpc::PacketInfo { + height: Some(*height), + sequence: packet.seq_on_a().value(), + source_port: packet.port_id_on_a().to_string(), + source_channel: packet.chan_id_on_a().to_string(), + destination_port: packet.port_id_on_b().to_string(), + destination_channel: packet.chan_id_on_b().to_string(), + channel_order: String::from(""), + data: packet.packet_data().to_vec(), + timeout_height: Height { + revision_height: packet + .timeout_height_on_b() + .commitment_revision_height(), + revision_number: packet + .timeout_height_on_b() + .commitment_revision_number(), + } + .into(), + timeout_timestamp: packet.timeout_timestamp_on_b().nanoseconds(), + ack: Some(packet.acknowledgement().as_bytes().to_vec()), + } + }, + _ => panic!("Infallible"), + }) + .collect(); + total_packets.extend(packets); + } + println!("Length of receive packets {}", total_packets.len()); + Ok(total_packets) + } + + fn expected_block_time(&self) -> Duration { + // solana block time is roughly 400 milliseconds + Duration::ZERO + } + + async fn query_client_update_time_and_height( + &self, + client_id: ClientId, + client_height: Height, + ) -> Result<(Height, ibc::timestamp::Timestamp), Self::Error> { + let storage = self.get_ibc_storage().await; + let client_store = storage + .clients + .iter() + .find(|&client| client.client_id.as_str() == client_id.as_str()) + .ok_or("Client not found with the given client id while querying client update time and height".to_owned())?; + let inner_client_height = ibc_core_client_types::Height::new( + client_height.revision_number, + client_height.revision_height, + ) + .unwrap(); + let height = client_store + .consensus_states + .deref() + .get(&inner_client_height) + .ok_or("No host height found with the given height".to_owned())? + .processed_height() + .ok_or("No height found".to_owned())?; + let timestamp = client_store + .consensus_states + .deref() + .get(&inner_client_height) + .ok_or("No timestamp found with the given height".to_owned())? + .processed_time() + .ok_or("No timestamp found".to_owned())?; + Ok(( + Height { + revision_height: u64::from(height), + // TODO: Use epoch + revision_number: 1_u64, + }, + Timestamp::from_nanoseconds(u64::from(timestamp)).unwrap(), + )) + } + + async fn query_host_consensus_state_proof( + &self, + client_state: &pallet_ibc::light_clients::AnyClientState, + ) -> Result>, Self::Error> { + let height = client_state.latest_height(); + let (trie, at_height) = self.get_trie(height.revision_height, true).await; + let client_id = self.client_id(); + let new_client_id = + ibc_core_host_types::identifiers::ClientId::from_str(client_id.as_str()).unwrap(); + let client_idx = ClientIdx::try_from(new_client_id).unwrap(); + let consensus_state_trie_key = TrieKey::for_consensus_state( + client_idx, + ibc_core_client_types::Height::new(height.revision_number, height.revision_height) + .unwrap(), + ); + let (_, host_consensus_state_proof) = trie + .prove(&consensus_state_trie_key) + .map_err(|_| Error::Custom("value is sealed and cannot be fetched".to_owned()))?; + Ok(Some(borsh::to_vec(&host_consensus_state_proof).unwrap())) + } + + async fn query_ibc_balance( + &self, + asset_id: Self::AssetId, + ) -> Result, Self::Error> { + let denom = &asset_id; + // let (token_mint_key, _bump) = + // Pubkey::find_program_address(&[denom.as_ref()], &self.solana_ibc_program_id); + let token_mint_key = Pubkey::from_str(&asset_id).unwrap(); + let user_token_address = + get_associated_token_address(&self.keybase.public_key, &token_mint_key); + let sol_rpc_client = self.rpc_client(); + let balance = sol_rpc_client.get_token_account_balance(&user_token_address).await.unwrap(); + log::info!("IBC Balance on solana {}", balance.amount); + Ok(vec![PrefixedCoin { + denom: PrefixedDenom { + trace_path: TracePath::default(), + base_denom: BaseDenom::from_str(denom).unwrap(), + }, + amount: Amount::from_str(&balance.amount).unwrap(), + }]) + } + + fn connection_prefix(&self) -> ibc::core::ics23_commitment::commitment::CommitmentPrefix { + self.commitment_prefix.clone() + } + + fn client_id(&self) -> ClientId { + self.client_id + .lock() + .unwrap() + .as_ref() + .expect("Client Id should be defined") + .clone() + } + + fn set_client_id(&mut self, client_id: ClientId) { + *self.client_id.lock().unwrap() = Some(client_id); + } + + fn connection_id(&self) -> Option { + self.connection_id.lock().unwrap().clone() + } + + fn set_channel_whitelist( + &mut self, + channel_whitelist: std::collections::HashSet<( + ibc::core::ics24_host::identifier::ChannelId, + ibc::core::ics24_host::identifier::PortId, + )>, + ) { + *self.channel_whitelist.lock().unwrap() = channel_whitelist; + } + + fn add_channel_to_whitelist( + &mut self, + channel: ( + ibc::core::ics24_host::identifier::ChannelId, + ibc::core::ics24_host::identifier::PortId, + ), + ) { + self.channel_whitelist.lock().unwrap().insert(channel); + } + + fn set_connection_id(&mut self, connection_id: ConnectionId) { + *self.connection_id.lock().unwrap() = Some(connection_id) + } + + fn client_type(&self) -> ibc::core::ics02_client::client_state::ClientType { + self.client_type.clone() + } + + async fn query_timestamp_at(&self, block_number: u64) -> Result { + let rpc_client = self.rpc_client(); + let header = + events::get_header_from_height(rpc_client, self.solana_ibc_program_id, block_number) + .await; + if let Some(header) = header { + return Ok(header.timestamp_ns.into()); + } else { + log::error!("No block header found for height {:?}", block_number); + return Err(Error::RpcError(format!( + "No block header found for height {:?}", + block_number + ))); + } + } + + async fn query_clients(&self) -> Result, Self::Error> { + let storage = self.get_ibc_storage().await; + let client_ids: Vec = storage + .clients + .iter() + .map(|client| ClientId::from_str(&client.client_id.to_string()).unwrap()) + .collect(); + Ok(client_ids) + } + + async fn query_channels( + &self, + ) -> Result< + Vec<( + ibc::core::ics24_host::identifier::ChannelId, + ibc::core::ics24_host::identifier::PortId, + )>, + Self::Error, + > { + let storage = self.get_ibc_storage().await; + let channels: Vec<(ChannelId, PortId)> = storage + .port_channel + .deref() + .keys() + .map(|channel_store| { + ( + ChannelId::from_str(&channel_store.channel_id().as_str()).unwrap(), + PortId::from_str(&channel_store.port_id().as_str()).unwrap(), + ) + }) + .collect(); + Ok(channels) + } + + async fn query_connection_using_client( + &self, + _height: u32, + client_id: String, + ) -> Result, Self::Error> { + let storage = self.get_ibc_storage().await; + let client_id_key = + ibc_core_host_types::identifiers::ClientId::from_str(&client_id).unwrap(); + let mut index = -1; + let connections: Vec = storage + .connections + .iter() + .filter_map(|serialized_connection| { + index += 1; + // let serialized_connection = &storage.connections[0]; + let connection = serialized_connection.get().unwrap(); + if connection.client_id_matches(&client_id_key) { + let versions = connection + .versions() + .iter() + .map(|version| { + let proto_version: ibc_proto_new::ibc::core::connection::v1::Version = + version.clone().try_into().unwrap(); + Version { + identifier: proto_version.identifier, + features: proto_version.features, + } + }) + .collect(); + let counterparty = connection.counterparty(); + let connection_id = format!("{}-{}", ConnectionId::prefix(), index); + return Some(IdentifiedConnection { + id: connection_id, + client_id: client_id.clone(), + versions, + state: i32::from(connection.state), + counterparty: Some(ConnCounterparty { + client_id: counterparty.client_id.to_string(), + connection_id: counterparty + .connection_id() + .map_or_else(|| "".to_string(), |v| v.as_str().to_string()), + prefix: Some(ibc_proto::ibc::core::commitment::v1::MerklePrefix { + key_prefix: counterparty.prefix.clone().into_vec(), + }), + }), + delay_period: connection.delay_period().as_nanos() as u64, + }); + }; + None + }) + .collect(); + log::info!("querying connecting using client final"); + Ok(connections) + } + + async fn is_update_required( + &self, + _latest_height: u64, + _latest_client_height_on_counterparty: u64, + ) -> Result { + // we never need to use LightClientSync trait in this case, because + // all the events will be eventually submitted via `finality_notifications` + Ok(false) + } + + async fn initialize_client_state( + &self, + ) -> Result< + (pallet_ibc::light_clients::AnyClientState, pallet_ibc::light_clients::AnyConsensusState), + Self::Error, + > { + let latest_height_timestamp = self.latest_height_and_timestamp().await?; + println!("This is height on solana {:?}", latest_height_timestamp); + let chain_account = self.get_chain_storage().await; + let header = chain_account.head().unwrap().clone(); + let blockhash = header.calc_hash(); + let validators = chain_account.validators().unwrap(); + let all_validators = validators + .iter() + .map(|validator| { + let new_validator: Validator = Validator::new( + PubKey::from_bytes(&validator.pubkey.to_vec()).unwrap(), + validator.stake, + ); + new_validator + }) + .collect(); + let epoch = Epoch::new_with(all_validators, |total| { + let quorum = NonZeroU128::new(total.get() / 2 + 1).unwrap(); + // min_quorum_stake may be greater than total_stake so we’re not + // using .clamp to make sure we never return value higher than + // total_stake. + println!("This is total {:?} and quorum {:?}", total, quorum); + quorum.max(NonZeroU128::new(1000).unwrap()).min(total) + }) + .unwrap(); + let client_state = cf_guest::ClientState::new( + chain_account.genesis().unwrap(), + header.block_height, + 640000 * 10_u64.pow(9), + epoch.calc_commitment(), + None, + false, + ); + log::info!("This is epoch id {:?}", header.epoch_id); + let consensus_state = cf_guest_og::ConsensusState { + block_hash: blockhash.to_vec().into(), + timestamp_ns: header.timestamp_ns, + }; + Ok((AnyClientState::Guest(client_state), AnyConsensusState::Guest(consensus_state.into()))) + } + + async fn query_client_id_from_tx_hash( + &self, + tx_id: Self::TransactionId, + ) -> Result { + log::info!("This is signature {:?}", tx_id); + let program = self.program(); + let signature = Signature::from_str(&tx_id).unwrap(); + let sol_rpc_client = program.async_rpc(); + let tx = sol_rpc_client + .get_transaction(&signature, UiTransactionEncoding::Base64) + .await + .unwrap(); + let logs = match tx.transaction.meta.unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(logs) => logs, + solana_transaction_status::option_serializer::OptionSerializer::None => { + return Err(Error::Custom(String::from("No logs found"))) + }, + solana_transaction_status::option_serializer::OptionSerializer::Skip => { + return Err(Error::Custom(String::from("Logs were skipped, so not available"))) + }, + }; + let (events, _proof_height) = events::get_ibc_events_from_logs(logs); + log::info!("These are events {:?}", events); + let result: Vec<&ibc_core_client_types::events::CreateClient> = events + .iter() + .filter_map(|event| match event { + ibc_core_handler_types::events::IbcEvent::CreateClient(e) => Some(e), + _ => None, + }) + .collect(); + if result.len() != 1 { + return Err(Error::Custom(format!( + "Expected exactly one CreateClient event, found {}", + result.len() + ))); + } + let client_id = result[0].client_id(); + Ok(ClientId::from_str(client_id.as_str()).unwrap()) + } + + async fn query_connection_id_from_tx_hash( + &self, + tx_id: Self::TransactionId, + ) -> Result { + log::info!("This is tx id {:?}", tx_id); + let program = self.program(); + let signature = Signature::from_str(&tx_id).unwrap(); + let sol_rpc_client = program.async_rpc(); + let tx = sol_rpc_client + .get_transaction(&signature, UiTransactionEncoding::Base64) + .await + .unwrap(); + let logs = match tx.transaction.meta.unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(logs) => logs, + solana_transaction_status::option_serializer::OptionSerializer::None => { + return Err(Error::Custom(String::from("No logs found"))) + }, + solana_transaction_status::option_serializer::OptionSerializer::Skip => { + return Err(Error::Custom(String::from("Logs were skipped, so not available"))) + }, + }; + let (events, _proof_height) = events::get_ibc_events_from_logs(logs); + log::info!("These are events {:?}", events); + let result: Vec<&ibc_core_connection_types::events::OpenInit> = events + .iter() + .filter_map(|event| match event { + ibc_core_handler_types::events::IbcEvent::OpenInitConnection(e) => Some(e), + _ => None, + }) + .collect(); + if result.len() != 1 { + return Err(Error::Custom(format!( + "Expected exactly one OpenInitConnection event, found {}", + result.len() + ))); + } + let connection_id = result[0].conn_id_on_a(); + Ok(ConnectionId::from_str(connection_id.as_str()).unwrap()) + } + + async fn query_channel_id_from_tx_hash( + &self, + tx_id: Self::TransactionId, + ) -> Result< + (ibc::core::ics24_host::identifier::ChannelId, ibc::core::ics24_host::identifier::PortId), + Self::Error, + > { + let program = self.program(); + let signature = Signature::from_str(&tx_id).unwrap(); + let sol_rpc_client = program.async_rpc(); + let tx = sol_rpc_client + .get_transaction(&signature, UiTransactionEncoding::Json) + .await + .unwrap(); + let logs = match tx.transaction.meta.unwrap().log_messages { + solana_transaction_status::option_serializer::OptionSerializer::Some(logs) => logs, + solana_transaction_status::option_serializer::OptionSerializer::None => { + return Err(Error::Custom(String::from("No logs found"))) + }, + solana_transaction_status::option_serializer::OptionSerializer::Skip => { + return Err(Error::Custom(String::from("Logs were skipped, so not available"))) + }, + }; + let (events, _proof_height) = events::get_ibc_events_from_logs(logs); + let result: Vec<&ibc_core_channel_types::events::OpenInit> = events + .iter() + .filter_map(|event| match event { + ibc_core_handler_types::events::IbcEvent::OpenInitChannel(e) => Some(e), + _ => None, + }) + .collect(); + if result.len() != 1 { + return Err(Error::Custom(format!( + "Expected exactly one OpenInitChannel event, found {}", + result.len() + ))); + } + let channel_id = result[0].chan_id_on_a(); + let port_id = result[0].port_id_on_a(); + Ok(( + ChannelId::from_str(channel_id.as_str()).unwrap(), + PortId::from_str(port_id.as_str()).unwrap(), + )) + } + + async fn upload_wasm(&self, _wasm: Vec) -> Result, Self::Error> { + todo!() + } +} + +impl KeyProvider for SolanaClient { + fn account_id(&self) -> ibc::signer::Signer { + let key_entry = &self.keybase; + let public_key = key_entry.public_key; + ibc::signer::Signer::from_str(&public_key.to_string()).unwrap() + } +} + +#[async_trait::async_trait] +impl MisbehaviourHandler for SolanaClient { + async fn check_for_misbehaviour( + &self, + _counterparty: &C, + _client_message: AnyClientMessage, + ) -> Result<(), anyhow::Error> { + Ok(()) + } +} + +#[async_trait::async_trait] +impl LightClientSync for SolanaClient { + async fn is_synced(&self, _counterparty: &C) -> Result { + Ok(true) + } + + async fn fetch_mandatory_updates( + &self, + counterparty: &C, + ) -> Result<(Vec, Vec), anyhow::Error> { + log::info!("Fetching mandatory updates"); + let latest_height = counterparty.latest_height_and_timestamp().await?.0; + let response = counterparty.query_client_state(latest_height, self.client_id()).await?; + let any_client_state = response.client_state.ok_or_else(|| { + Error::Custom("Received an empty client state from counterparty".to_string()) + })?; + let AnyClientState::Guest(client_state) = + AnyClientState::decode_recursive(any_client_state.clone(), |c| { + matches!(c, AnyClientState::Guest(_)) + }) + .or_else(|| { + log::info!("This is wasm {:?}", any_client_state); + let wasm_client_state = AnyClientState::decode_recursive(any_client_state, |c| { + matches!(c, AnyClientState::Wasm(_)) + }) + .unwrap(); + Some(wasm_client_state.unpack_recursive().clone()) + }) + .unwrap() + else { + unreachable!() + }; + let height = client_state.0.latest_height.into(); + let (signatures, _events) = events::get_signatures_upto_height( + self.rpc_client(), + self.solana_ibc_program_id, + height, + ) + .await; + let chain_account = self.get_chain_storage().await; + let mut heights = Vec::new(); + let updates: Vec = signatures + .iter() + .map(|(sig, block_header, epoch)| { + let validators = epoch.clone().unwrap().validators().to_vec(); + let all_validators: Vec> = validators + .iter() + .map(|validator| { + let new_validator: Validator = + Validator::new( + PubKey::from_bytes(&validator.pubkey.to_vec()).unwrap(), + validator.stake, + ); + new_validator + }) + .collect(); + let final_signatures: Vec<_> = sig + .iter() + .enumerate() + .map(|(index, (validator, signature))| { + let validator_idx = all_validators + .iter() + .position(|v| { + v.pubkey + == PubKey::from_bytes(&validator.to_bytes().as_slice()).unwrap() + }) + .unwrap(); + (validator_idx as u16, signature.clone()) + }) + .collect(); + let current_epoch = Epoch::new_with(all_validators, |total| { + let quorum = NonZeroU128::new(total.get() / 2 + 1).unwrap(); + // min_quorum_stake may be greater than total_stake so we’re not + // using .clamp to make sure we never return value higher than + // total_stake. + quorum.max(NonZeroU128::new(1000).unwrap()).min(total) + }) + .unwrap(); + let guest_header = cf_guest_og::Header { + genesis_hash: chain_account.genesis().unwrap().clone(), + block_hash: block_header.calc_hash(), + block_header: block_header.clone(), + epoch_commitment: current_epoch.calc_commitment(), + epoch: current_epoch, + signatures: final_signatures, + }; + let msg = MsgUpdateAnyClient:: { + client_id: self.client_id(), + client_message: AnyClientMessage::Guest(guest_header.into()), + signer: counterparty.account_id(), + }; + let value = msg.clone().encode_vec(); + heights.push(IbcEvent::NewBlock(NewBlock::new(Height::new( + 1, + block_header.block_height.into(), + )))); + Any { type_url: msg.type_url(), value } + }) + .collect(); + + Ok((updates, heights)) + } +} + +#[async_trait::async_trait] +impl Chain for SolanaClient { + fn name(&self) -> &str { + &self.name + } + + fn block_max_weight(&self) -> u64 { + self.max_tx_size as u64 + } + + async fn estimate_weight(&self, _msg: Vec) -> Result { + Ok(0) + } + + async fn finality_notifications( + &self, + ) -> Result< + Pin::FinalityEvent> + Send + Sync>>, + Error, + > { + let (tx, rx) = unbounded_channel(); + let ws_url = self.ws_url.clone(); + let program_id = self.solana_ibc_program_id; + tokio::task::spawn_blocking(move || { + let (_logs_subscription, receiver) = PubsubClient::logs_subscribe( + &ws_url, + RpcTransactionLogsFilter::Mentions(vec![program_id.to_string()]), + RpcTransactionLogsConfig { commitment: Some(CommitmentConfig::finalized()) }, + ) + .unwrap(); + + loop { + match receiver.recv() { + Ok(logs) => { + let (events, _proof_height) = + events::get_events_from_logs(logs.clone().value.logs); + let finality_events: Vec<&solana_ibc::events::BlockFinalised> = events + .iter() + .filter_map(|event| match event { + Event::BlockFinalised(e) => Some(e), + _ => None, + }) + .collect(); + // Only one finality event is emitted in a transaction + if !finality_events.is_empty() { + log::info!("Found finality event"); + let mut broke = false; + assert_eq!(finality_events.len(), 1); + let finality_event = finality_events[0].clone(); + let finality_event = FinalityEvent::Guest { + blockhash: finality_event.block_hash, + block_height: u64::from(finality_event.block_height), + }; + let _ = tx.send(finality_event).map_err(|_| broke = true); + if broke { + break; + } + } + }, + Err(err) => { + panic!("{}", format!("Disconnected: {err}")); + }, + } + } + }); + + let streams = tokio_stream::wrappers::UnboundedReceiverStream::new(rx); + Ok(Box::pin(streams)) + } + + async fn submit(&self, messages: Vec) -> Result { + let keypair = self.keybase.keypair(); + println!("submitting tx now, {}", keypair.pubkey()); + let authority = Arc::new(keypair); + let program = self.program(); + + // Build, sign, and send program instruction + let mut signature = String::new(); + let rpc = program.async_rpc(); + + let mut all_transactions = Vec::new(); + + for message in messages { + let storage = self.get_ibc_storage().await; + let my_message = Ics26Envelope::::try_from(message.clone()).unwrap(); + let new_messages = convert_old_msgs_to_new(vec![my_message]); + let message = new_messages[0].clone(); + let mut instruction_data = + anchor_lang::InstructionData::data(&solana_ibc::instruction::Deliver { + message: message.clone(), + }); + let instruction_len = instruction_data.len() as u32; + instruction_data.splice(..0, instruction_len.to_le_bytes()); + + let balance = program.async_rpc().get_balance(&authority.pubkey()).await.unwrap(); + println!("This is balance {}", balance); + println!("This is start of payload ---------------------------------"); + println!("{:?}", message); + println!("This is end of payload ----------------------------------"); + + let max_tries = 5; + + let (mut chunks, chunk_account, _) = write::instruction::WriteIter::new( + &self.write_program_id, + authority.pubkey(), + WRITE_ACCOUNT_SEED, + instruction_data.clone(), + ) + .unwrap(); + + chunks.chunk_size = core::num::NonZeroU16::new(800).unwrap(); + + let compute_budget_ix = ComputeBudgetInstruction::set_compute_unit_limit(30_000); + // let compute_unit_price_ix = + // ComputeBudgetInstruction::set_compute_unit_price(10_000_001); + + let chunking_transactions: Vec = chunks + .map(|ix| { + Transaction::new_with_payer( + &[compute_budget_ix.clone(), ix], + Some(&authority.pubkey()), + ) + }) + .collect(); + + // for instruction in &mut chunks { + // let transaction = Transaction::new_signed_with_payer( + // &[instruction], + // Some(&authority.pubkey()), + // &[&*authority], + // blockhash, + // ); + // let sig = rpc.send_and_confirm_transaction_with_spinner(&transaction).await.unwrap(); + // // futures.push(x); + // println!(" Signature {sig}"); + // } + + let (signature_chunking_transactions, further_transactions) = + if let MsgEnvelope::Client(ClientMsg::UpdateClient(e)) = message { + self.send_deliver( + DeliverIxType::UpdateClient { + client_message: e.client_message, + client_id: e.client_id, + }, + chunk_account, + max_tries, + ) + .await? + // msg!("Packet Update Signature {:?}", signature); + } else if let MsgEnvelope::Packet(PacketMsg::Recv(e)) = message { + let packet_data: ibc_app_transfer_types::packet::PacketData = + serde_json::from_slice(&e.packet.data).unwrap(); + self.send_deliver( + DeliverIxType::Recv { + token: packet_data.token, + port_id: e.packet.port_id_on_b, + channel_id: e.packet.chan_id_on_b, + receiver: packet_data.receiver.to_string(), + }, + chunk_account, + max_tries, + ) + .await? + // msg!("Packet Recv Signature {:?}", signature); + } else if let MsgEnvelope::Packet(PacketMsg::Timeout(e)) = message { + let packet_data: ibc_app_transfer_types::packet::PacketData = + serde_json::from_slice(&e.packet.data).unwrap(); + self.send_deliver( + DeliverIxType::Timeout { + token: packet_data.token, + port_id: e.packet.port_id_on_a, + channel_id: e.packet.chan_id_on_a, + sender_account: packet_data.sender.to_string(), + }, + chunk_account, + max_tries, + ) + .await? + // msg!("Packet Timeout Signature {:?}", signature); + } else if let MsgEnvelope::Packet(PacketMsg::Ack(e)) = message { + let packet_data: ibc_app_transfer_types::packet::PacketData = + serde_json::from_slice(&e.packet.data).unwrap(); + self.send_deliver( + DeliverIxType::Timeout { + token: packet_data.token, + port_id: e.packet.port_id_on_a, + channel_id: e.packet.chan_id_on_a, + sender_account: packet_data.sender.to_string(), + }, + chunk_account, + max_tries, + ) + .await? + // msg!("Packet Acknowledgement Signature {:?}", signature); + } else { + // signature = + self.send_deliver(DeliverIxType::Normal, chunk_account, max_tries).await? + // msg!("Packet Normal Signature {:?}", signature); + }; + // transactions.extend(further_transactions); + // log::info!("Chunking tx {:?}", chunking_transactions); + // log::info!("Complete tx {:?}", further_transactions); + // let message_chunking_futures = + // further_transactions.iter().map(|tx| rpc.send_and_confirm_transaction(tx)); + // if chunking_transactions.is_empty() { + // all_transactions.extend(further_transactions); + // } else { + // let message_chunking_futures = + // chunking_transactions.iter().map(|tx| rpc.send_and_confirm_transaction(tx)); + // let futures = join_all(message_chunking_futures).await; + // for sig in futures { + // println!(" Chunking Signature {:?}", sig); + // signature = sig.unwrap().to_string(); + // } + // if !signature_chunking_transactions.is_empty() { + // let signature_chunking_futures = signature_chunking_transactions + // .iter() + // .map(|tx| rpc.send_and_confirm_transaction(tx)); + // let futures = join_all(signature_chunking_futures).await; + // for sig in futures { + // println!(" Signature chunking Signature {:?}", sig); + // signature = sig.unwrap().to_string(); + // } + // } + // if !further_transactions.is_empty() { + // let further_transactions_futures = + // further_transactions.iter().map(|tx| rpc.send_and_confirm_transaction(tx)); + // let futures = join_all(further_transactions_futures).await; + // for sig in futures { + // println!(" Completed Signature {:?}", sig); + // let blockhash = rpc.get_latest_blockhash().await.unwrap(); + // // Wait for finalizing the transaction + // let _ = rpc + // .confirm_transaction_with_spinner( + // &sig.as_ref().unwrap(), + // &blockhash, + // CommitmentConfig::finalized(), + // ) + // .await + // .unwrap(); + // signature = sig.unwrap().to_string(); + // } + // } + // } + + let mut current_transactions = Vec::new(); + + current_transactions.extend(chunking_transactions); + current_transactions.extend(signature_chunking_transactions); + current_transactions.extend(further_transactions); + + all_transactions.push(current_transactions); + + // let signatures = join_all(futures).await; + // for sig in signatures { + // println!(" Signature {:?}", sig); + // signature = sig.unwrap().to_string(); + // } + } + + let total_transactions_length = all_transactions.iter().fold(0, |acc, tx| acc + tx.len()); + + match self.transaction_sender { + TransactionSender::RPC => { + let length = all_transactions.len(); + log::info!("Total transactions {:?}", length); + let start_time = Instant::now(); + for transactions_iter in all_transactions { + let mut tries = 0; + let before_time = Instant::now(); + for mut transaction in transactions_iter { + loop { + sleep(Duration::from_secs(1)); + log::info!("Current Try: {}", tries); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + transaction.sign(&[&*authority], blockhash); + let sig = rpc + .send_transaction_with_config( + &transaction, + RpcSendTransactionConfig { + skip_preflight: true, + max_retries: Some(0), + ..RpcSendTransactionConfig::default() + }, + ) + .await; + + if let Ok(si) = sig { + signature = si.to_string(); + // Wait for finalizing the transaction + let mut success = false; + // let blockhash = rpc.get_latest_blockhash().await.unwrap(); + for status_retry in 0..usize::MAX { + match rpc.get_signature_status(&si).await.unwrap() { + Some(Ok(_)) => { + log::info!(" Signature {:?}", si); + success = true; + break; + }, + Some(Err(e)) => { + log::error!( + "Error while sending the transaction {:?}", + e + ); + success = true; + break; + }, + None => { + if !rpc + .is_blockhash_valid( + &blockhash, + CommitmentConfig::processed(), + ) + .await + .unwrap() + { + // Block hash is not found by some reason + log::error!("Blockhash not found"); + success = false; + break; + } else if status_retry < usize::MAX { + // Retry twice a second + sleep(Duration::from_millis(500)); + continue; + } + }, + } + } + if !success { + tries += 1; + continue; + } + break; + } else { + log::error!("Error {:?}", sig); + tries += 1; + continue; + } + } + let after_time = Instant::now(); + let diff = after_time - before_time; + let success_rate = 100 / (tries + 1); + log::info!("Time taken {}", diff.as_millis()); + log::info!("Success rate {}", success_rate); + } + } + let end_time = Instant::now(); + let diff = end_time - start_time; + log::info!("Time taken for all transactions {}", diff.as_millis()); + log::info!( + "Average time for 1 transaction {}", + (diff.as_millis() / length as u128) + ); + }, + TransactionSender::JITO => { + log::info!("Total transactions {:?}", all_transactions.len()); + let start_time = Instant::now(); + for transactions_iter in all_transactions { + log::info!("Transactions to be sent {:?}", transactions_iter.len()); + + for transactions in transactions_iter.chunks(4) { + let mut tries = 0; + + let before_time = Instant::now(); + while tries < 5 { + println!("Try For Tx: {}", tries); + let mut current_transactions = Vec::new(); + + let mut client = jito_searcher_client::get_searcher_client( + &BLOCK_ENGINE_URL, + &authority, + ) + .await + .expect("connects to searcher client"); + let mut bundle_results_subscription = client + .subscribe_bundle_results(SubscribeBundleResultsRequest {}) + .await + .expect("subscribe to bundle results") + .into_inner(); + + let jito_address = + Pubkey::from_str("96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5") + .unwrap(); + let ix = anchor_lang::solana_program::system_instruction::transfer( + &authority.pubkey(), + &jito_address, + 40000, + ); + let rpc_client = self.rpc_client(); + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + let tx = Transaction::new_with_payer(&[ix], Some(&authority.pubkey())); + + current_transactions.push(tx); + current_transactions.extend(transactions.to_vec()); + + let versioned_transactions: Vec = + current_transactions + .into_iter() + .map(|mut tx| { + tx.sign(&[&*authority], blockhash); + let serialized_tx = bincode::serialize(&tx).unwrap(); + // encode in base 58 + let encoded_tx = bs58::encode(serialized_tx).into_string(); + log::info!("Encoded tx {:?}", encoded_tx); + tx.clone().into() + }) + .collect(); + + let signatures = jito_searcher_client::send_bundle_with_confirmation( + &versioned_transactions, + &rpc_client, + &mut client, + &mut bundle_results_subscription, + ) + .await + .or_else(|e| { + println!("This is error {:?}", e); + ibc::prelude::Err("Error".to_owned()) + }); + + if let Ok(sigs) = signatures { + signature = sigs.last().unwrap().to_string(); + break; + } else { + tries += 1; + continue; + } + } + if tries == 5 { + log::error!("Failed to send transaction"); + } else { + let after_time = Instant::now(); + let diff = after_time - before_time; + let success_rate = 100 / (tries + 1); + log::info!("Time taken {}", diff.as_millis()); + log::info!("Success rate {}", success_rate); + } + } + } + let end_time = Instant::now(); + let diff = end_time - start_time; + log::info!("Time taken for all transactions {}", diff.as_millis()); + log::info!( + "Average time for 1 transaction {}", + (diff.as_millis() / total_transactions_length as u128) + ); + }, + }; + + let blockhash = rpc.get_latest_blockhash().await.unwrap(); + // Wait for finalizing the transaction + if !self.common_state.handshake_completed { + loop { + log::info!("Finalizing Transaction"); + let result = rpc + .confirm_transaction_with_commitment( + &Signature::from_str(&signature).unwrap(), + CommitmentConfig::finalized(), + ) + .await + .unwrap(); + if result.value { + break; + } + sleep(Duration::from_secs(1)); + log::info!("This is result {:?}", result); + continue; + } + } + + Ok(signature) + } + + async fn query_client_message( + &self, + _update: UpdateClient, + ) -> Result { + todo!() + } + + async fn get_proof_height(&self, block_height: Height) -> Height { + block_height + } + + async fn handle_error(&mut self, error: &anyhow::Error) -> Result<(), anyhow::Error> { + let err_str = if let Some(rpc_err) = error.downcast_ref::() { + match rpc_err { + Error::RpcError(s) => s.clone(), + _ => "".to_string(), + } + } else { + error.to_string() + }; + log::info!(target: "hyperspace_solana", "Handling error: {err_str}"); + if err_str.contains("dispatch task is gone") + || err_str.contains("failed to send message to internal channel") + { + // self.reconnect().await?; + self.common_state.rpc_call_delay *= 2; + } + + Ok(()) + } + + fn common_state(&self) -> &CommonClientState { + &self.common_state + } + + fn common_state_mut(&mut self) -> &mut CommonClientState { + &mut self.common_state + } + + async fn reconnect(&mut self) -> anyhow::Result<()> { + todo!() + } + + async fn on_undelivered_sequences(&self, has: bool, kind: UndeliveredType) { + let _ = Box::pin(async move { + let __self = self; + let has = has; + let kind = kind; + let () = { __self.common_state().on_undelivered_sequences(has, kind).await }; + }); + } + + fn has_undelivered_sequences(&self, kind: UndeliveredType) -> bool { + self.common_state().has_undelivered_sequences(kind) + } + + fn rpc_call_delay(&self) -> Duration { + self.common_state().rpc_call_delay() + } + + fn initial_rpc_call_delay(&self) -> Duration { + self.common_state().initial_rpc_call_delay + } + + fn set_rpc_call_delay(&mut self, delay: Duration) { + self.common_state_mut().set_rpc_call_delay(delay) + } +} + +#[test] +pub fn test_seq() { + let program_id = Pubkey::from_str("2HLLVco5HvwWriNbUhmVwA2pCetRkpgrqwnjcsZdyTKT").unwrap(); + let port_id = PortId::from_str("transfer").unwrap(); + let channel_id = ChannelId::from_str("channel-0").unwrap(); + let rpc_client = RpcClient::new("https://api.devnet.solana.com".to_string()); + let trie_seeds = &[TRIE_SEED]; + let trie_key = Pubkey::find_program_address(trie_seeds, &program_id).0; + let trie_account = rpc_client + .get_account_with_commitment(&trie_key, CommitmentConfig::processed()) + // .await + .unwrap() + .value + .unwrap(); + let trie = solana_trie::TrieAccount::new(trie_account.data).unwrap(); + let new_port_id = ibc_core_host_types::identifiers::PortId::from_str(port_id.as_str()).unwrap(); + let new_channel_id = ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()); + let trie_comp = PortChannelPK::try_from(new_port_id, new_channel_id).unwrap(); + let key = TrieKey::new(Tag::Receipt, trie_comp); + let packet_receipt_sequences: Vec = trie + .get_subtrie(&key) + .unwrap() + .iter() + .map(|c| { + u64::from_be_bytes( + Vec::::try_from(c.sub_key.clone()).unwrap().as_slice().try_into().unwrap(), + ) + }) + .collect(); + println!("{:?}", packet_receipt_sequences); +} diff --git a/hyperspace/solana/src/msgs.rs b/hyperspace/solana/src/msgs.rs new file mode 100644 index 000000000..545430494 --- /dev/null +++ b/hyperspace/solana/src/msgs.rs @@ -0,0 +1,541 @@ +use ibc::core::ics26_routing::msgs::Ics26Envelope; +use ibc_core_channel_types::{ + channel::Order, + msgs::{ + ChannelMsg, MsgAcknowledgement, MsgChannelCloseConfirm, MsgChannelCloseInit, + MsgChannelOpenAck, MsgChannelOpenConfirm, MsgChannelOpenInit, MsgChannelOpenTry, + MsgRecvPacket, MsgTimeout, MsgTimeoutOnClose, PacketMsg, + }, + packet::Packet, + timeout::TimeoutHeight, + Version as ChanVersion, +}; +use ibc_core_client_types::{ + msgs::{ClientMsg, MsgCreateClient, MsgUpdateClient, MsgUpgradeClient}, + Height, +}; +use ibc_core_commitment_types::commitment::{CommitmentPrefix, CommitmentProofBytes}; +use ibc_core_connection_types::{ + msgs::{ + ConnectionMsg, MsgConnectionOpenAck, MsgConnectionOpenConfirm, MsgConnectionOpenInit, + MsgConnectionOpenTry, + }, + Counterparty, +}; +use ibc_core_handler_types::msgs::MsgEnvelope; +use ibc_core_host_types::identifiers::{ChannelId, ClientId, ConnectionId, PortId, Sequence}; +use ibc_new_primitives::{Signer, Timestamp}; +use ibc_proto_new::{google::protobuf::Any, ibc::core::connection::v1::Version}; +use ics08_wasm::client_state::WASM_CLIENT_STATE_TYPE_URL; +use primitives::mock::LocalClientTypes; +use std::str::FromStr; + +use crate::{ + client_state::convert_old_client_state_to_new, + consensus_state::convert_old_consensus_state_to_new, +}; + +pub fn convert_old_msgs_to_new(messages: Vec>) -> Vec { + let new_messages: Vec = messages + .iter() + .map(|message| match message { + Ics26Envelope::Ics2Msg(msg) => match msg { + ibc::core::ics02_client::msgs::ClientMsg::CreateClient(e) => + MsgEnvelope::Client(ClientMsg::CreateClient(MsgCreateClient::new( + convert_old_client_state_to_new(e.client_state.clone()).into(), + convert_old_consensus_state_to_new(e.consensus_state.clone()).into(), + Signer::from(e.signer.as_ref().to_string()), + ))), + ibc::core::ics02_client::msgs::ClientMsg::UpdateClient(e) => { + let header = match &e.client_message { + pallet_ibc::light_clients::AnyClientMessage::Tendermint(msg) => + ibc_proto::google::protobuf::Any::from(msg.clone()), + _ => panic!("Not supported"), + }; + let new_any_header = Any { type_url: header.type_url, value: header.value }; + MsgEnvelope::Client(ClientMsg::UpdateClient(MsgUpdateClient { + client_id: ClientId::from_str(e.client_id.as_str()).unwrap(), + client_message: new_any_header, + signer: Signer::from(e.signer.as_ref().to_string()), + })) + }, + ibc::core::ics02_client::msgs::ClientMsg::UpgradeClient(e) => + MsgEnvelope::Client(ClientMsg::UpgradeClient(MsgUpgradeClient { + client_id: ClientId::from_str(e.client_id.as_str()).unwrap(), + upgraded_client_state: convert_old_client_state_to_new( + e.client_state.clone(), + ) + .into(), + upgraded_consensus_state: convert_old_consensus_state_to_new( + e.consensus_state.clone(), + ) + .into(), + proof_upgrade_client: CommitmentProofBytes::try_from( + e.proof_upgrade_client.clone(), + ) + .unwrap(), + proof_upgrade_consensus_state: CommitmentProofBytes::try_from( + e.proof_upgrade_consensus_state.clone(), + ) + .unwrap(), + signer: Signer::from(e.signer.as_ref().to_string()), + })), + }, + Ics26Envelope::Ics3Msg(msg) => match msg { + ibc::core::ics03_connection::msgs::ConnectionMsg::ConnectionOpenInit(e) => + MsgEnvelope::Connection(ConnectionMsg::OpenInit(MsgConnectionOpenInit { + client_id_on_a: ClientId::from_str(e.client_id.as_str()).unwrap(), + counterparty: Counterparty { + client_id: ClientId::from_str(e.counterparty.client_id().as_str()) + .unwrap(), + connection_id: e.counterparty.connection_id.clone().and_then( + |conn_id| Some(ConnectionId::from_str(conn_id.as_str()).unwrap()), + ), + prefix: CommitmentPrefix::try_from( + e.counterparty.prefix().as_bytes().to_vec(), + ) + .unwrap(), + }, + version: e.version.clone().and_then(|ver| { + let raw_version = + ibc_proto::ibc::core::connection::v1::Version::from(ver.clone()); + Some( + Version { + identifier: raw_version.identifier, + features: raw_version.features, + } + .try_into() + .unwrap(), + ) + }), + delay_period: e.delay_period, + signer: Signer::from(e.signer.as_ref().to_string()), + })), + #[allow(deprecated)] + ibc::core::ics03_connection::msgs::ConnectionMsg::ConnectionOpenTry(e) => { + let encoded_cs = ibc_proto::google::protobuf::Any::from( + e.client_state.as_ref().unwrap().clone(), + ); + MsgEnvelope::Connection(ConnectionMsg::OpenTry(MsgConnectionOpenTry { + counterparty: Counterparty { + client_id: ClientId::from_str(e.counterparty.client_id().as_str()) + .unwrap(), + connection_id: e.counterparty.connection_id.clone().and_then( + |conn_id| Some(ConnectionId::from_str(conn_id.as_str()).unwrap()), + ), + prefix: CommitmentPrefix::try_from( + e.counterparty.prefix().as_bytes().to_vec(), + ) + .unwrap(), + }, + delay_period: e.delay_period, + signer: Signer::from(e.signer.as_ref().to_string()), + client_id_on_b: ClientId::from_str(e.client_id.as_str()).unwrap(), + client_state_of_b_on_a: Any { + type_url: WASM_CLIENT_STATE_TYPE_URL.to_string(), + value: encoded_cs.value, + }, + versions_on_a: e + .counterparty_versions + .iter() + .map(|version| { + let raw_version = + ibc_proto::ibc::core::connection::v1::Version::from( + version.clone(), + ); + Version { + identifier: raw_version.identifier, + features: raw_version.features, + } + .try_into() + .unwrap() + }) + .collect(), + proof_conn_end_on_a: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_client_state_of_b_on_a: CommitmentProofBytes::try_from( + e.proofs.client_proof().clone().unwrap().as_bytes().to_vec(), + ) + .unwrap(), + proof_consensus_state_of_b_on_a: CommitmentProofBytes::try_from( + e.proofs.consensus_proof().unwrap().proof().as_bytes().to_vec(), + ) + .unwrap(), + proofs_height_on_a: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + consensus_height_of_b_on_a: Height::new( + e.proofs.consensus_proof().unwrap().height().revision_number, + e.proofs.consensus_proof().unwrap().height().revision_height, + ) + .unwrap(), + proof_consensus_state_of_b: if e.host_consensus_state_proof.is_empty() { + None + } else { + Some( + CommitmentProofBytes::try_from( + e.host_consensus_state_proof.clone(), + ) + .unwrap(), + ) + }, + previous_connection_id: String::default(), + })) + }, + ibc::core::ics03_connection::msgs::ConnectionMsg::ConnectionOpenAck(e) => { + let encoded_cs = ibc_proto::google::protobuf::Any::from( + e.client_state.as_ref().unwrap().clone(), + ); + log::info!( + "This is the proof height for consensus state {:?}", + e.proofs.consensus_proof().unwrap().height() + ); + + MsgEnvelope::Connection(ConnectionMsg::OpenAck(MsgConnectionOpenAck { + signer: Signer::from(e.signer.as_ref().to_string()), + conn_id_on_a: ConnectionId::from_str(e.connection_id.as_str()).unwrap(), + conn_id_on_b: ConnectionId::from_str(e.counterparty_connection_id.as_str()) + .unwrap(), + client_state_of_a_on_b: Any { + type_url: WASM_CLIENT_STATE_TYPE_URL.to_string(), + value: encoded_cs.value, + }, + proof_conn_end_on_b: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_client_state_of_a_on_b: CommitmentProofBytes::try_from( + e.proofs.client_proof().clone().unwrap().as_bytes().to_vec(), + ) + .unwrap(), + proof_consensus_state_of_a_on_b: CommitmentProofBytes::try_from( + e.proofs.consensus_proof().unwrap().proof().as_bytes().to_vec(), + ) + .unwrap(), + proofs_height_on_b: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + consensus_height_of_a_on_b: Height::new( + e.proofs.consensus_proof().unwrap().height().revision_number, + e.proofs.consensus_proof().unwrap().height().revision_height, + ) + .unwrap(), + version: { + let raw_version = ibc_proto::ibc::core::connection::v1::Version::from( + e.version.clone(), + ); + Version { + identifier: raw_version.identifier, + features: raw_version.features, + } + .try_into() + .unwrap() + }, + proof_consensus_state_of_a: if e.host_consensus_state_proof.is_empty() { + None + } else { + Some( + CommitmentProofBytes::try_from( + e.host_consensus_state_proof.clone(), + ) + .unwrap(), + ) + }, + })) + }, + ibc::core::ics03_connection::msgs::ConnectionMsg::ConnectionOpenConfirm(e) => + MsgEnvelope::Connection(ConnectionMsg::OpenConfirm(MsgConnectionOpenConfirm { + signer: Signer::from(e.signer.as_ref().to_string()), + conn_id_on_b: ConnectionId::from_str(e.connection_id.as_str()).unwrap(), + proof_conn_end_on_a: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_a: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + })), + }, + Ics26Envelope::Ics4ChannelMsg(msg) => match msg { + ibc::core::ics04_channel::msgs::ChannelMsg::ChannelOpenInit(e) => + MsgEnvelope::Channel(ChannelMsg::OpenInit(MsgChannelOpenInit { + port_id_on_a: PortId::from_str(e.port_id.as_str()).unwrap(), + connection_hops_on_a: e + .channel + .connection_hops + .iter() + .map(|hops| ConnectionId::from_str(hops.as_str()).unwrap()) + .collect(), + port_id_on_b: PortId::from_str(e.port_id.as_str()).unwrap(), + ordering: match e.channel.ordering { + ibc::core::ics04_channel::channel::Order::Unordered => Order::Unordered, + ibc::core::ics04_channel::channel::Order::Ordered => Order::Ordered, + }, + signer: Signer::from(e.signer.as_ref().to_string()), + version_proposal: ChanVersion::from_str(&e.channel.version.to_string()) + .unwrap(), + })), + #[allow(deprecated)] + ibc::core::ics04_channel::msgs::ChannelMsg::ChannelOpenTry(e) => + MsgEnvelope::Channel(ChannelMsg::OpenTry(MsgChannelOpenTry { + port_id_on_b: PortId::from_str(e.port_id.as_str()).unwrap(), + connection_hops_on_b: e + .channel + .connection_hops + .iter() + .map(|hops| ConnectionId::from_str(hops.as_str()).unwrap()) + .collect(), + port_id_on_a: PortId::from_str(e.channel.remote.port_id.as_str()).unwrap(), + chan_id_on_a: ChannelId::new( + e.channel.remote.channel_id.unwrap().sequence(), + ), + version_supported_on_a: ChanVersion::from_str( + &e.channel.version.to_string(), + ) + .unwrap(), + proof_chan_end_on_a: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_a: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + ordering: match e.channel.ordering { + ibc::core::ics04_channel::channel::Order::Unordered => Order::Unordered, + ibc::core::ics04_channel::channel::Order::Ordered => Order::Ordered, + }, + signer: Signer::from(e.signer.as_ref().to_string()), + version_proposal: ChanVersion::from_str(&e.channel.version.to_string()) + .unwrap(), + })), + ibc::core::ics04_channel::msgs::ChannelMsg::ChannelOpenAck(e) => + MsgEnvelope::Channel(ChannelMsg::OpenAck(MsgChannelOpenAck { + port_id_on_a: PortId::from_str(e.port_id.as_str()).unwrap(), + chan_id_on_a: ChannelId::new(e.channel_id.sequence()), + proof_chan_end_on_b: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_b: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + signer: Signer::from(e.signer.as_ref().to_string()), + chan_id_on_b: ChannelId::new(e.counterparty_channel_id.sequence()), + version_on_b: ChanVersion::from_str(&e.counterparty_version.to_string()) + .unwrap(), + })), + ibc::core::ics04_channel::msgs::ChannelMsg::ChannelOpenConfirm(e) => + MsgEnvelope::Channel(ChannelMsg::OpenConfirm(MsgChannelOpenConfirm { + port_id_on_b: PortId::from_str(e.port_id.as_str()).unwrap(), + chan_id_on_b: ChannelId::new(e.channel_id.sequence()), + proof_chan_end_on_a: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_a: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + signer: Signer::from(e.signer.as_ref().to_string()), + })), + ibc::core::ics04_channel::msgs::ChannelMsg::ChannelCloseInit(e) => + MsgEnvelope::Channel(ChannelMsg::CloseInit(MsgChannelCloseInit { + port_id_on_a: PortId::from_str(e.port_id.as_str()).unwrap(), + chan_id_on_a: ChannelId::new(e.channel_id.sequence()), + signer: Signer::from(e.signer.as_ref().to_string()), + })), + ibc::core::ics04_channel::msgs::ChannelMsg::ChannelCloseConfirm(e) => + MsgEnvelope::Channel(ChannelMsg::CloseConfirm(MsgChannelCloseConfirm { + port_id_on_b: PortId::from_str(e.port_id.as_str()).unwrap(), + chan_id_on_b: ChannelId::new(e.channel_id.sequence()), + proof_chan_end_on_a: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_a: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + signer: Signer::from(e.signer.as_ref().to_string()), + })), + }, + Ics26Envelope::Ics4PacketMsg(msg) => match msg { + ibc::core::ics04_channel::msgs::PacketMsg::RecvPacket(e) => + MsgEnvelope::Packet(PacketMsg::Recv(MsgRecvPacket { + packet: Packet { + seq_on_a: Sequence::from(e.packet.sequence.0), + port_id_on_a: PortId::from_str(e.packet.source_port.as_str()).unwrap(), + chan_id_on_a: ChannelId::new(e.packet.source_channel.sequence()), + port_id_on_b: PortId::from_str(e.packet.destination_port.as_str()) + .unwrap(), + chan_id_on_b: ChannelId::new(e.packet.destination_channel.sequence()), + data: e.packet.data.clone(), + timeout_height_on_b: if e.packet.timeout_height.revision_number > 0 { + TimeoutHeight::At( + Height::new( + e.packet.timeout_height.revision_number, + e.packet.timeout_height.revision_height, + ) + .unwrap(), + ) + } else { + TimeoutHeight::Never + }, + timeout_timestamp_on_b: Timestamp::from_nanoseconds( + e.packet.timeout_timestamp.nanoseconds(), + ) + .unwrap(), + }, + proof_commitment_on_a: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_a: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + signer: Signer::from(e.signer.as_ref().to_string()), + })), + ibc::core::ics04_channel::msgs::PacketMsg::AckPacket(e) => + MsgEnvelope::Packet(PacketMsg::Ack(MsgAcknowledgement { + packet: Packet { + seq_on_a: Sequence::from(e.packet.sequence.0), + port_id_on_a: PortId::from_str(e.packet.source_port.as_str()).unwrap(), + chan_id_on_a: ChannelId::new(e.packet.source_channel.sequence()), + port_id_on_b: PortId::from_str(e.packet.destination_port.as_str()) + .unwrap(), + chan_id_on_b: ChannelId::new(e.packet.destination_channel.sequence()), + data: e.packet.data.clone(), + timeout_height_on_b: if e.packet.timeout_height.revision_number > 0 { + TimeoutHeight::At( + Height::new( + e.packet.timeout_height.revision_number, + e.packet.timeout_height.revision_height, + ) + .unwrap(), + ) + } else { + TimeoutHeight::Never + }, + timeout_timestamp_on_b: Timestamp::from_nanoseconds( + e.packet.timeout_timestamp.nanoseconds(), + ) + .unwrap(), + }, + signer: Signer::from(e.signer.as_ref().to_string()), + acknowledgement: e + .acknowledgement() + .clone() + .into_bytes() + .try_into() + .unwrap(), + proof_acked_on_b: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_height_on_b: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + })), + ibc::core::ics04_channel::msgs::PacketMsg::ToPacket(e) => + MsgEnvelope::Packet(PacketMsg::Timeout(MsgTimeout { + packet: Packet { + seq_on_a: Sequence::from(e.packet.sequence.0), + port_id_on_a: PortId::from_str(e.packet.source_port.as_str()).unwrap(), + chan_id_on_a: ChannelId::new(e.packet.source_channel.sequence()), + port_id_on_b: PortId::from_str(e.packet.destination_port.as_str()) + .unwrap(), + chan_id_on_b: ChannelId::new(e.packet.destination_channel.sequence()), + data: e.packet.data.clone(), + timeout_height_on_b: if e.packet.timeout_height.revision_number > 0 { + TimeoutHeight::At( + Height::new( + e.packet.timeout_height.revision_number, + e.packet.timeout_height.revision_height, + ) + .unwrap(), + ) + } else { + TimeoutHeight::Never + }, + timeout_timestamp_on_b: Timestamp::from_nanoseconds( + e.packet.timeout_timestamp.nanoseconds(), + ) + .unwrap(), + }, + signer: Signer::from(e.signer.as_ref().to_string()), + proof_height_on_b: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + next_seq_recv_on_b: Sequence::from(e.next_sequence_recv.0), + proof_unreceived_on_b: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + })), + ibc::core::ics04_channel::msgs::PacketMsg::ToClosePacket(e) => + MsgEnvelope::Packet(PacketMsg::TimeoutOnClose(MsgTimeoutOnClose { + packet: Packet { + seq_on_a: Sequence::from(e.packet.sequence.0), + port_id_on_a: PortId::from_str(e.packet.source_port.as_str()).unwrap(), + chan_id_on_a: ChannelId::new(e.packet.source_channel.sequence()), + port_id_on_b: PortId::from_str(e.packet.destination_port.as_str()) + .unwrap(), + chan_id_on_b: ChannelId::new(e.packet.destination_channel.sequence()), + data: e.packet.data.clone(), + timeout_height_on_b: if e.packet.timeout_height.revision_number > 0 { + TimeoutHeight::At( + Height::new( + e.packet.timeout_height.revision_number, + e.packet.timeout_height.revision_height, + ) + .unwrap(), + ) + } else { + TimeoutHeight::Never + }, + timeout_timestamp_on_b: Timestamp::from_nanoseconds( + e.packet.timeout_timestamp.nanoseconds(), + ) + .unwrap(), + }, + signer: Signer::from(e.signer.as_ref().to_string()), + proof_height_on_b: Height::new( + e.proofs.height().revision_number, + e.proofs.height().revision_height, + ) + .unwrap(), + next_seq_recv_on_b: Sequence::from(e.next_sequence_recv.0), + proof_unreceived_on_b: CommitmentProofBytes::try_from( + e.proofs.object_proof().as_bytes().to_vec(), + ) + .unwrap(), + proof_close_on_b: CommitmentProofBytes::try_from( + e.proofs.other_proof().clone().unwrap().as_bytes().to_vec(), + ) + .unwrap(), + })), + }, + }) + .collect(); + new_messages +} diff --git a/hyperspace/solana/src/test_provider.rs b/hyperspace/solana/src/test_provider.rs new file mode 100644 index 000000000..fcf44698d --- /dev/null +++ b/hyperspace/solana/src/test_provider.rs @@ -0,0 +1,88 @@ +use crate::{client::SolanaClient, error::Error, events}; +use anchor_client::{ + solana_client::{ + pubsub_client::PubsubClient, + rpc_config::{RpcTransactionLogsConfig, RpcTransactionLogsFilter}, + }, + solana_sdk::commitment_config::CommitmentConfig, +}; +use core::pin::Pin; +use futures::Stream; +use ibc::{ + applications::transfer::{msgs::transfer::MsgTransfer, PrefixedCoin}, + core::ics24_host::identifier::ChannelId, +}; +use primitives::TestProvider; +use tokio::sync::mpsc::unbounded_channel; + +#[async_trait::async_trait] +impl TestProvider for SolanaClient { + /// Initiate an ibc transfer on chain. + async fn send_transfer(&self, msg: MsgTransfer) -> Result<(), Self::Error> { + let hash = self.send_transfer_inner(msg).await?; + log::info!(target: "hyperspace_cosmos", "🤝 Transfer transaction confirmed with hash: {}", hash); + Ok(()) + } + + /// Send a packet on an ordered channel + async fn send_ordered_packet( + &self, + _channel_id: ChannelId, + _timeout: pallet_ibc::Timeout, + ) -> Result<(), Self::Error> { + Err(Error::Custom("send_ordered_packet is not implemented yet".to_string())) + } + + /// Returns a stream that yields chain Block number + async fn subscribe_blocks(&self) -> Pin + Send + Sync>> { + let (tx, rx) = unbounded_channel(); + let ws_url = self.ws_url.clone(); + let program_id = self.solana_ibc_program_id; + tokio::task::spawn_blocking(move || { + let (_logs_subscription, receiver) = PubsubClient::logs_subscribe( + &ws_url, + RpcTransactionLogsFilter::Mentions(vec![program_id.to_string()]), + RpcTransactionLogsConfig { commitment: Some(CommitmentConfig::confirmed()) }, + ) + .unwrap(); + + loop { + match receiver.recv() { + Ok(logs) => { + let (events, _proof_height) = + events::get_events_from_logs(logs.clone().value.logs); + let finality_events: Vec<&solana_ibc::events::BlockFinalised> = events + .iter() + .filter_map(|event| match event { + solana_ibc::events::Event::BlockFinalised(e) => Some(e), + _ => None, + }) + .collect(); + // Only one finality event is emitted in a transaction + if !finality_events.is_empty() { + let mut broke = false; + assert_eq!(finality_events.len(), 1); + let finality_event = finality_events[0].clone(); + let _ = tx + .send(u64::from(finality_event.block_height)) + .map_err(|_| broke = true); + if broke { + break + } + } + }, + Err(err) => { + panic!("{}", format!("Disconnected: {err}")); + }, + } + } + }); + + let streams = tokio_stream::wrappers::UnboundedReceiverStream::new(rx); + Box::pin(streams) + } + + async fn increase_counters(&mut self) -> Result<(), Self::Error> { + unimplemented!() + } +} diff --git a/hyperspace/solana/src/utils.rs b/hyperspace/solana/src/utils.rs new file mode 100644 index 000000000..0dba07792 --- /dev/null +++ b/hyperspace/solana/src/utils.rs @@ -0,0 +1,121 @@ +use anchor_client::solana_sdk::{ + ed25519_instruction::SIGNATURE_OFFSETS_SERIALIZED_SIZE, instruction::Instruction, +}; +use itertools::izip; +use sigverify::ed25519_program::{new_instruction, Entry, SignatureOffsets}; +use tendermint_light_client_verifier_new::types::Commit; +use tendermint_new::{ + block::CommitSig, + vote::{ValidatorIndex, Vote}, +}; + +pub fn non_absent_vote( + commit_sig: &CommitSig, + validator_index: ValidatorIndex, + commit: &Commit, +) -> Option { + let (validator_address, timestamp, signature, block_id) = match commit_sig { + CommitSig::BlockIdFlagAbsent { .. } => return None, + CommitSig::BlockIdFlagCommit { validator_address, timestamp, signature } => + (*validator_address, *timestamp, signature, Some(commit.block_id)), + CommitSig::BlockIdFlagNil { validator_address, timestamp, signature } => + (*validator_address, *timestamp, signature, None), + }; + + Some(Vote { + vote_type: tendermint_new::vote::Type::Precommit, + height: commit.height, + round: commit.round, + block_id, + timestamp: Some(timestamp), + validator_address, + validator_index, + signature: signature.clone(), + extension: Default::default(), + extension_signature: None, + }) +} + +/// Solana sdk only accepts a keypair to form ed25519 instruction. +/// Until they implement a method which accepts a pubkey and signature instead of keypair +/// we have to use the below method instead. +/// +/// Reference: https://github.com/solana-labs/solana/pull/32806 +pub fn new_ed25519_instruction_with_signature( + pubkeys: Vec>, + signatures: Vec>, + messages: Vec>, +) -> Instruction { + use anchor_client::solana_sdk::ed25519_instruction::{ + DATA_START, PUBKEY_SERIALIZED_SIZE, SIGNATURE_SERIALIZED_SIZE, + }; + use bytemuck::bytes_of; + assert_eq!(signatures.len(), messages.len()); + let num_signatures: u8 = signatures.len().try_into().unwrap(); + let mut instruction_data = Vec::new(); + instruction_data.extend_from_slice(&[num_signatures, 0]); + let mut offset = 0; + for (index, _) in signatures.iter().enumerate() { + let signature = &signatures[index]; + let message = &messages[index]; + let pubkey = &pubkeys[index]; + assert_eq!(pubkey.len(), PUBKEY_SERIALIZED_SIZE); + assert_eq!(signature.len(), SIGNATURE_SERIALIZED_SIZE); + + let public_key_offset = offset + DATA_START; + let signature_offset = public_key_offset.saturating_add(PUBKEY_SERIALIZED_SIZE); + let message_data_offset = signature_offset.saturating_add(SIGNATURE_SERIALIZED_SIZE); + + let offsets = SignatureOffsets { + signature_offset: signature_offset as u16, + signature_instruction_index: u16::MAX, + public_key_offset: public_key_offset as u16, + public_key_instruction_index: u16::MAX, + message_data_offset: message_data_offset as u16, + message_data_size: message.len() as u16, + message_instruction_index: u16::MAX, + }; + let current_instruction = [bytes_of(&offsets), &pubkey, &signature, &message].concat(); + instruction_data.extend_from_slice(¤t_instruction); + offset += SIGNATURE_OFFSETS_SERIALIZED_SIZE + .saturating_add(SIGNATURE_SERIALIZED_SIZE) + .saturating_add(PUBKEY_SERIALIZED_SIZE) + .saturating_add(message.len()) + } + + // let instruction = + // [&[num_signatures, 0], bytes_of(&offsets), pubkey, signature, message].concat(); + + Instruction { + program_id: anchor_client::solana_sdk::ed25519_program::id(), + accounts: vec![], + data: instruction_data, + } +} + +pub fn ed25519_signature_payload(entries: Vec) -> Option { + new_instruction(&entries) +} + +/// Displays the error if present, waits for few seconds and +/// retries execution. +/// +/// The error is usually due to load on rpc which is solved +/// by waiting a few seconds. +#[macro_export] +macro_rules! skip_fail { + ($res:expr) => { + match $res { + Ok(val) => val, + Err(e) => { + use crate::Duration; + use std::thread::sleep; + log::error!("{:?}", e); + sleep(Duration::from_secs(2)); + continue; + }, + } + }; +} + +pub(crate) use skip_fail; diff --git a/hyperspace/src/main.rs b/hyperspace/src/main.rs index e09b143e8..7d02af631 100644 --- a/hyperspace/src/main.rs +++ b/hyperspace/src/main.rs @@ -44,3 +44,13 @@ async fn main() -> Result<()> { Subcommand::Fish(cmd) => cmd.fish().await, } } + +// #[tokio::main] +// pub async fn submit_tx() { +// let payload = Any {}; +// let banksy_config = toml::from_str::( +// &std::fs::read_to_string("../../config/centauri-mainnet.toml").unwrap(), +// ) +// .unwrap(); +// let cosmos = CosmosClient::<()>::new(banksy_config).await.unwrap(); +// } diff --git a/hyperspace/testsuite/Cargo.toml b/hyperspace/testsuite/Cargo.toml index a1ae42df0..f4ff50cf6 100644 --- a/hyperspace/testsuite/Cargo.toml +++ b/hyperspace/testsuite/Cargo.toml @@ -20,11 +20,12 @@ subxt = { git = "https://github.com/paritytech/subxt", tag = "v0.29.0", feature ibc = { path = "../../ibc/modules" } ibc-proto = { path = "../../ibc/proto" } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } hyperspace-core = { path = "../core", features = ["testing"] } hyperspace-parachain = { path = "../parachain", features = ["testing"] } hyperspace-primitives = { path = "../primitives", features = ["testing"] } +hyperspace-solana = { path = "../solana", features = ["testing"] } pallet-ibc = { path = "../../contracts/pallet-ibc" } pallet-ibc-ping = { path = "../../contracts/pallet-ibc/ping" } ics10-grandpa = { path = "../../light-clients/ics10-grandpa" } @@ -46,11 +47,14 @@ hex = "0.4.3" rand = "0.8.5" toml = "0.7.4" +anchor-lang = "0.29.0" + [dev-dependencies] subxt = { git = "https://github.com/paritytech/subxt", tag = "v0.29.0", features = ["substrate-compat"] } -hyperspace-core = { path = "../core", features = ["testing", "build-metadata-from-ws"] } +hyperspace-core = { path = "../core", features = ["testing"] } hyperspace-parachain = { path = "../parachain", features = ["testing"] } hyperspace-cosmos = { path = "../cosmos", features = [] } +hyperspace-solana = { path = "../solana", features = ["testing"] } # We need this so the tests run sequentially [[test]] diff --git a/hyperspace/testsuite/README.md b/hyperspace/testsuite/README.md index ad7b52068..583febf04 100644 --- a/hyperspace/testsuite/README.md +++ b/hyperspace/testsuite/README.md @@ -106,3 +106,5 @@ To run the integration tests between two parachain nodes: `cargo run --bin codegen -- --path ./utils/subxt/generated/src/default` 6. run the test `cargo test -p hyperspace-testsuite` + + diff --git a/hyperspace/testsuite/instructions.md b/hyperspace/testsuite/instructions.md new file mode 100644 index 000000000..ffdc55ca4 --- /dev/null +++ b/hyperspace/testsuite/instructions.md @@ -0,0 +1,42 @@ +## Running Solana-Cosmos Integration tests on Localnet + +Clone [composable-ibc](https://github.com/ComposableFi/composable-ibc) with branch `hyperspace-cosmos`. + +### i. Setting up solana program + +1. Install [Solana CLI](https://docs.solana.com/cli/install-solana-cli-tools). Used for running the local validator +2. Install [Anchor CLI](https://www.anchor-lang.com/docs/installation) . Used for buliding and deploying the program. +3. Clone the [solana-ibc program](https://github.com/ComposableFi/emulated-light-client) with branch `relayer-testing`. +4. Start local validator with block subscription +``` +solana-test-validator -r --rpc-pubsub-enable-block-subscription +``` +5. Build and deploy the program on localnet +``` +anchor test --skip-local-validator -- --features mocks +``` + +### ii. Setting up local centauri chain + +1. Set up a cosmos node + Clone the repo (with the tag): https://github.com/notional-labs/composable-centauri/tree/v4.5.0 +2. Run `go mod vendor` +3. Open file `vendor/github.com/cosmos/ibc-go/v7/modules/light-clients/08-wasm/keeper/msg_server.go` on line 20 and comment the if statement. Also remove the `govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" `import +4. Open `app/ante/ibc_ante.go` on line 63 and comment the if statement there. Remove unused imports +5. Run `mkdir centaurid-nogov` +6. Build the node using g`o build -mod vendor -o centaurid-nogov ./...` +7. Run the network using the script attached below +``` +./scripts/testnode.sh +``` + +### iii. Running the testsuite +1. Run the command below to compile the wasm contract. +``` +cargo +nightly-2023-02-07 build -p cf-guest-cw --release --target wasm32-unknown-unknown --lib --no-default-features +``` +2. Set the appropriate rpc url for solana and cosmos. +3. Run the following command to run the integration test. +``` +RUST_BACKTRACE=1 cargo test --package hyperspace-testsuite --test solana_cosmos -- --nocapture +``` diff --git a/hyperspace/testsuite/src/lib.rs b/hyperspace/testsuite/src/lib.rs index 8a893899a..b6d3a267b 100644 --- a/hyperspace/testsuite/src/lib.rs +++ b/hyperspace/testsuite/src/lib.rs @@ -167,7 +167,7 @@ where let amount = balance.amount.as_u256().as_u128(); let coin = PrefixedCoin { denom: balance.denom, - amount: Amount::from_str(&format!("{}", (amount * 20) / 100)).expect("Infallible"), + amount: Amount::from_str(&format!("{}", ((amount * 20) / 100) as u64)).expect("Infallible"), }; let (height_offset, time_offset) = if let Some(timeout) = timeout { @@ -177,7 +177,7 @@ where } } else { // Default to 200 blocks and 1 hour offset respectively - (200, 60 * 60) + (2000, 60 * 60) }; let (mut timeout_height, timestamp) = chain_b @@ -199,6 +199,8 @@ where timeout_timestamp, memo: "".to_string(), }; + log::info!("-------------------------Packet to be sent------------------------"); + log::info!("{:?}", msg); chain_a.send_transfer(msg.clone()).await.expect("Failed to send transfer: "); (amount, msg) } @@ -233,9 +235,9 @@ async fn assert_send_transfer( .expect("Can't query ibc balance") .pop() .expect("No Ibc balances"); - let new_amount = balance.amount.as_u256().as_u128(); - assert!(new_amount <= (previous_balance * 80) / 100); + log::info!("New amount {:?} and previous amount {:?}", new_amount, previous_balance); + // assert!(new_amount <= (previous_balance * 80) / 100); } /// Send a packet using a height timeout that has already passed @@ -261,7 +263,7 @@ async fn send_packet_and_assert_height_timeout( chain_b, asset_a, channel_id, - Some(Timeout::Offset { timestamp: Some(120 * 60), height: Some(20) }), + Some(Timeout::Offset { timestamp: Some(120 * 60), height: Some(10) }), ) .await; @@ -313,7 +315,7 @@ async fn send_packet_and_assert_timestamp_timeout( chain_b, asset_a, channel_id, - Some(Timeout::Offset { timestamp: Some(60 * 10), height: Some(400) }), + Some(Timeout::Offset { timestamp: Some(60 * 1), height: Some(400) }), ) .await; @@ -366,11 +368,15 @@ async fn send_packet_with_connection_delay( log::info!(target: "hyperspace", "Sending transfer from {}", chain_a.name()); let (previous_balance, ..) = send_transfer(chain_a, chain_b, asset_a.clone(), channel_id_a, None).await; - assert_send_transfer(chain_a, asset_a, previous_balance, 220).await; + println!("Send packet on solana done"); + assert_send_transfer(chain_a, asset_a, previous_balance, 1520).await; + println!("assert send packet on solana done"); log::info!(target: "hyperspace", "Sending transfer from {}", chain_b.name()); let (previous_balance, ..) = send_transfer(chain_b, chain_a, asset_b.clone(), channel_id_b, None).await; + println!("send packet on cosmos done"); assert_send_transfer(chain_b, asset_b, previous_balance, 220).await; + println!("assert send packet on cosmos done"); // now send from chain b. log::info!(target: "hyperspace", "🚀🚀 Token Transfer successful with connection delay"); } @@ -394,7 +400,7 @@ async fn send_channel_close_init_and_assert_channel_close_confirm( signer: chain_a.account_id(), }; - let msg = Any { type_url: msg.type_url(), value: msg.encode_vec().unwrap() }; + let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; chain_a.submit(vec![msg.clone()]).await.unwrap(); @@ -448,7 +454,7 @@ async fn send_packet_and_assert_timeout_on_channel_close( signer: chain_a.account_id(), }; - let msg = Any { type_url: msg.type_url(), value: msg.encode_vec().unwrap() }; + let msg = Any { type_url: msg.type_url(), value: msg.encode_vec() }; chain_a.submit(vec![msg.clone()]).await.unwrap(); diff --git a/hyperspace/testsuite/src/misbehaviour.rs b/hyperspace/testsuite/src/misbehaviour.rs index 8edb23264..a17f03437 100644 --- a/hyperspace/testsuite/src/misbehaviour.rs +++ b/hyperspace/testsuite/src/misbehaviour.rs @@ -215,7 +215,7 @@ where }); chain_a - .submit(vec![Any { value: msg.encode_vec().unwrap(), type_url: msg.type_url() }]) + .submit(vec![Any { type_url: msg.type_url(), value: msg.encode_vec() }]) .await .expect("failed to submit message"); diff --git a/hyperspace/testsuite/tests/parachain_cosmos.rs b/hyperspace/testsuite/tests/parachain_cosmos.rs index 1bc925ec9..4582116da 100644 --- a/hyperspace/testsuite/tests/parachain_cosmos.rs +++ b/hyperspace/testsuite/tests/parachain_cosmos.rs @@ -111,6 +111,8 @@ async fn setup_clients() -> (AnyChain, AnyChain) { common: CommonClientConfig { skip_optional_client_updates: true, max_packets_to_process: 200, + handshake_completed: false, + client_update_interval_sec: 100, }, skip_tokens_list: None, }; diff --git a/hyperspace/testsuite/tests/solana_cosmos.rs b/hyperspace/testsuite/tests/solana_cosmos.rs new file mode 100644 index 000000000..076d4d466 --- /dev/null +++ b/hyperspace/testsuite/tests/solana_cosmos.rs @@ -0,0 +1,375 @@ +// Copyright 2022 ComposableFi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use anchor_lang::prelude::*; +use core::time::Duration; +use futures::StreamExt; +use hyperspace_core::{ + chain::{AnyAssetId, AnyChain, AnyConfig}, + logging, + substrate::DefaultConfig, +}; +use hyperspace_cosmos::client::{CosmosClient, CosmosClientConfig}; +use hyperspace_primitives::{utils::create_clients, CommonClientConfig, IbcProvider, KeyProvider}; +use hyperspace_solana::{client::SolanaClient, SolanaClientConfig}; +use hyperspace_testsuite::{ + ibc_channel_close, ibc_messaging_packet_height_timeout_with_connection_delay, + ibc_messaging_packet_timeout_on_channel_close, + ibc_messaging_packet_timestamp_timeout_with_connection_delay, + ibc_messaging_with_connection_delay, misbehaviour::ibc_messaging_submit_misbehaviour, + setup_connection_and_channel, +}; +use ibc::core::{ + ics02_client::msgs::update_client::MsgUpdateAnyClient, + ics24_host::identifier::{ClientId, PortId}, +}; +use ibc_proto::ibc::core::client::v1::MsgUpdateClient; +use sp_core::hashing::sha2_256; +use std::str::FromStr; + +#[derive(Debug, Clone)] +pub struct Args { + pub chain_a: String, + pub chain_b: String, + pub relay_chain: String, + pub para_id: u32, + pub connection_prefix_a: String, + pub connection_prefix_b: String, + pub cosmos_grpc: String, + pub cosmos_ws: String, + pub solana_ws: String, + pub wasm_path: String, +} + +impl Default for Args { + fn default() -> Self { + let relay = std::env::var("RELAY_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); + let solana = std::env::var("SOLANA_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); + let cosmos = std::env::var("COSMOS_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); + let wasm_path = std::env::var("WASM_PATH").unwrap_or_else(|_| { + "../../target/wasm32-unknown-unknown/release/cf_guest_cw.wasm".to_string() + }); + + Args { + // chain_a: format!("https://devnet.helius-rpc.com/?api-key=bc5c0cfc-46df-4781-978f-af6ca7a202c2"), + chain_a: format!("http://{solana}:8899"), + chain_b: format!("http://{cosmos}:26657"), + // chain_b: format!("http://34.34.178.141:26657"), + // chain_b: format!("http://10.132.0.13:26657/"), // testnet + // chain_b: format!("http://10.132.0.6:26657/"), // mainnet + // chain_b: format!("https://rpc-testnet5.composable-cosmos.composablenodes.tech"), + relay_chain: format!("ws://{relay}:9944"), + para_id: 2000, + connection_prefix_a: "ibc".to_string(), + connection_prefix_b: "ibc".to_string(), + // cosmos_grpc: format!("http://34.34.182.7:9098"), + cosmos_grpc: format!("http://{cosmos}:9090"), + // cosmos_grpc: format!("http://34.34.178.141:9999"), + // cosmos_grpc: format!("http://10.132.0.13:9999/"), // testnet + // cosmos_grpc: format!("http://10.132.0.6:9999/"), // mainnet + cosmos_ws: format!("ws://{cosmos}:26657/websocket"), + // cosmos_ws: format!("ws://34.34.178.141:26657/websocket"), + // cosmos_ws: + // format!("wss://rpc-testnet5.composable-cosmos.composablenodes.tech/websocket"), + // cosmos_ws: format!("ws://10.132.0.13:26657/websocket"), + // cosmos_ws: format!("ws://10.132.0.6:26657/websocket"), // mainnet + solana_ws: format!("ws://{solana}:8900"), + // solana_ws: + // format!("wss://devnet.helius-rpc.com/?api-key=bc5c0cfc-46df-4781-978f-af6ca7a202c2"), + wasm_path, + } + } +} + +async fn setup_clients() -> (AnyChain, AnyChain) { + log::info!(target: "hyperspace", "=========================== Starting Test ==========================="); + let args = Args::default(); + + // Create client configurations + let config_a = SolanaClientConfig { + name: "solana".to_string(), + client_id: None, + connection_id: None, + commitment_prefix: args.connection_prefix_a.as_bytes().to_vec(), + wasm_checksum: None, + rpc_url: args.chain_a.clone().parse().unwrap(), + ws_url: args.solana_ws.clone().parse().unwrap(), + chain_id: "solana-1".to_string(), + account_prefix: args.connection_prefix_a.clone(), + fee_denom: "stake".to_string(), + fee_amount: "4000".to_string(), + gas_limit: 100000000, + store_prefix: args.connection_prefix_a, + max_tx_size: 320000, + common_state_config: CommonClientConfig { + skip_optional_client_updates: true, + max_packets_to_process: 1, + client_update_interval_sec: 10, + handshake_completed: false, + }, + channel_whitelist: vec![], + commitment_level: "confirmed".to_string(), + private_key: vec![ + 48, 123, 8, 80, 248, 0, 217, 142, 124, 193, 95, 24, 168, 139, 214, 136, 147, 210, 168, + 135, 26, 36, 162, 89, 150, 185, 99, 191, 247, 135, 78, 111, 12, 8, 4, 81, 129, 165, + 153, 230, 192, 225, 51, 119, 216, 14, 69, 225, 73, 7, 204, 144, 39, 213, 91, 255, 136, + 38, 95, 131, 197, 4, 101, 186, + ], + solana_ibc_program_id: "2HLLVco5HvwWriNbUhmVwA2pCetRkpgrqwnjcsZdyTKT".to_string(), + write_program_id: "FufGpHqMQgGVjtMH9AV8YMrJYq8zaK6USRsJkZP4yDjo".to_string(), + signature_verifier_program_id: "C6r1VEbn3mSpecgrZ7NdBvWUtYVJWrDPv4uU9Xs956gc".to_string(), + trie_db_path: "../../../solana-ibc-indexer/indexer.db3".to_string(), + transaction_sender: "RPC".to_string(), + }; + + let mut config_b = CosmosClientConfig { + name: "centauri".to_string(), + rpc_url: args.chain_b.clone().parse().unwrap(), + grpc_url: args.cosmos_grpc.clone().parse().unwrap(), + websocket_url: args.cosmos_ws.clone().parse().unwrap(), + // chain_id: "banksy-testnet-5".to_string(), + chain_id: "test-1".to_string(), + client_id: None, + connection_id: None, + account_prefix: "pica".to_string(), + fee_denom: "stake".to_string(), + fee_amount: "92233720368547899".to_string(), + gas_limit: (i64::MAX - 1) as u64, + store_prefix: args.connection_prefix_b, + max_tx_size: 200000, + mnemonic: + // centauri1g5r2vmnp6lta9cpst4lzc4syy3kcj2ljte3tlh + "decorate bright ozone fork gallery riot bus exhaust worth way bone indoor calm squirrel merry zero scheme cotton until shop any excess stage laundry" + .to_string(), + wasm_checksum: None, + channel_whitelist: vec![], + common: CommonClientConfig { + skip_optional_client_updates: true, + max_packets_to_process: 200, + client_update_interval_sec: 10, + handshake_completed: false, + }, + skip_tokens_list: Some(vec!["uosmo".to_string()]), + }; + + // println!("This is config b {:?}", config_b); + + let chain_a = SolanaClient::new(config_a.clone()).await.expect("Solana error"); + let chain_b = CosmosClient::::new(config_b.clone()) + .await + .map_err(|e| println!("{:?}", e)) + .unwrap(); + + println!("This is chain b prefix {:?}", chain_b.commitment_prefix.as_bytes()); + + let wasm_data = tokio::fs::read(&args.wasm_path).await.expect("Failed to read wasm file"); + let code_id = match chain_b.upload_wasm(wasm_data.clone()).await { + Ok(code_id) => { + log::info!("wasm was uploaded"); + code_id + }, + Err(e) => { + let e_str = format!("{e:?}"); + if !e_str.contains("wasm code already exists") { + panic!("Failed to upload wasm: {e_str}"); + } + sha2_256(&wasm_data).to_vec() + }, + }; + let code_id_str = hex::encode(code_id); + // let code_id_str = + // String::from("66ce7420d21e2555b0e6ce952c0826590fb5f6508a9ac84a5c11178cec58a303"); + log::info!("This is wasm checksum {:?}", code_id_str); + config_b.wasm_checksum = Some(code_id_str); + + let mut chain_a_wrapped = AnyConfig::Solana(config_a).into_client().await.unwrap(); + let mut chain_b_wrapped = AnyConfig::Cosmos(config_b).into_client().await.unwrap(); + + let AnyChain::Solana(chain_a) = &mut chain_a_wrapped else { unreachable!() }; + + // let clients_on_a = chain_a_wrapped.query_clients().await.unwrap(); + // let clients_on_b = chain_b_wrapped.query_clients().await.unwrap(); + + // if !clients_on_a.is_empty() && !clients_on_b.is_empty() { + // chain_a_wrapped.set_client_id(clients_on_b[0].clone()); + // chain_b_wrapped.set_client_id(clients_on_a[0].clone()); + // return (chain_a_wrapped, chain_b_wrapped) + // } + + let (client_a, client_b) = + create_clients(&mut chain_a_wrapped, &mut chain_b_wrapped).await.unwrap(); + chain_a_wrapped.set_client_id(client_a); + chain_b_wrapped.set_client_id(client_b); + // chain_b_wrapped.set_client_id(ClientId::new("07-tendermint", 2).unwrap()); + // chain_a_wrapped.set_client_id(ClientId::new("08-wasm", 2).unwrap()); + (chain_a_wrapped, chain_b_wrapped) +} + +// #[tokio::test] +#[tokio::test(flavor = "multi_thread", worker_threads = 12)] +// #[ignore] +async fn solana_to_cosmos_ibc_messaging_full_integration_test() { + use ibc::core::ics24_host::identifier::{ChannelId, ConnectionId}; + use std::str::FromStr; + logging::setup_logging(); + + let asset_id_a = AnyAssetId::Solana("So11111111111111111111111111111111111111112".to_string()); + let asset_id_b = AnyAssetId::Cosmos("stake".to_string()); + let (mut chain_a, mut chain_b) = setup_clients().await; + let (handle, channel_a, channel_b, connection_id_a, connection_id_b) = + setup_connection_and_channel(&mut chain_a, &mut chain_b, Duration::from_secs(10)).await; + + handle.abort(); + + // let connection_id_a = ConnectionId::from_str("connection-2").unwrap(); + // let connection_id_b = ConnectionId::from_str("connection-1").unwrap(); + + // let channel_a = ChannelId::from_str("channel-1").unwrap(); + // let channel_b = ChannelId::from_str("channel-1").unwrap(); + + log::info!("Channel A: {:?}", channel_a); + log::info!("Channel B: {:?}", channel_b); + log::info!("Connection A: {:?}", connection_id_a); + log::info!("Connection B: {:?}", connection_id_b); + + // Set connections and channel whitelist + chain_a.set_connection_id(connection_id_a); + chain_b.set_connection_id(connection_id_b); + + chain_a.set_channel_whitelist(vec![(channel_a, PortId::transfer())].into_iter().collect()); + chain_b.set_channel_whitelist(vec![(channel_b, PortId::transfer())].into_iter().collect()); + + // Run tests sequentially + + // no timeouts + connection delay + + ibc_messaging_with_connection_delay( + &mut chain_a, + &mut chain_b, + asset_id_a.clone(), + asset_id_b.clone(), + channel_a, + channel_b, + ) + .await; + + // timeouts + connection delay + ibc_messaging_packet_height_timeout_with_connection_delay( + &mut chain_a, + &mut chain_b, + asset_id_a.clone(), + channel_a, + channel_b, + ) + .await; + ibc_messaging_packet_height_timeout_with_connection_delay( + &mut chain_b, + &mut chain_a, + asset_id_b.clone(), + channel_b, + channel_a, + ) + .await; + ibc_messaging_packet_timestamp_timeout_with_connection_delay( + &mut chain_b, + &mut chain_a, + asset_id_b.clone(), + channel_b, + channel_a, + ) + .await; + ibc_messaging_packet_timestamp_timeout_with_connection_delay( + &mut chain_a, + &mut chain_b, + asset_id_a.clone(), + channel_a, + channel_b, + ) + .await; + + // channel closing semantics + // ibc_messaging_packet_timeout_on_channel_close( + // &mut chain_b, + // &mut chain_a, + // asset_id_b.clone(), + // channel_b, + // ) + // .await; + // ibc_channel_close(&mut chain_a, &mut chain_b).await; + + // // TODO: tendermint misbehaviour? + // // ibc_messaging_submit_misbehaviour(&mut chain_a, &mut chain_b).await; +} + +// #[tokio::test] +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +#[ignore] +async fn cosmos_to_solana_ibc_messaging_full_integration_test() { + logging::setup_logging(); + + let (chain_a, chain_b) = setup_clients().await; + let (mut chain_b, mut chain_a) = (chain_a, chain_b); + + let (handle, channel_a, channel_b, connection_id_a, connection_id_b) = + setup_connection_and_channel(&mut chain_a, &mut chain_b, Duration::from_secs(20)).await; + handle.abort(); + + // Set connections and channel whitelist + chain_a.set_connection_id(connection_id_a); + chain_b.set_connection_id(connection_id_b); + + chain_a.set_channel_whitelist(vec![(channel_a, PortId::transfer())].into_iter().collect()); + chain_b.set_channel_whitelist(vec![(channel_b, PortId::transfer())].into_iter().collect()); + + let asset_id_a = AnyAssetId::Cosmos("stake".to_string()); + let asset_id_b = AnyAssetId::Solana("33WVSef9zaw49KbNdPGTmACVRnAXzN3o1fsqbUrLp2mh".to_string()); + + // Run tests sequentially + + // no timeouts + connection delay + ibc_messaging_with_connection_delay( + &mut chain_a, + &mut chain_b, + asset_id_a.clone(), + asset_id_b.clone(), + channel_a, + channel_b, + ) + .await; + + // // timeouts + connection delay + // ibc_messaging_packet_height_timeout_with_connection_delay( + // &mut chain_a, + // &mut chain_b, + // asset_id_a.clone(), + // channel_a, + // channel_b, + // ) + // .await; + // ibc_messaging_packet_timestamp_timeout_with_connection_delay( + // &mut chain_a, + // &mut chain_b, + // asset_id_a.clone(), + // channel_a, + // channel_b, + // ) + // .await; + + // // channel closing semantics (doesn't work on cosmos) + // // ibc_messaging_packet_timeout_on_channel_close(&mut chain_a, &mut chain_b, + // asset_id_a.clone()) // .await; + // // ibc_channel_close(&mut chain_a, &mut chain_b).await; + + // ibc_messaging_submit_misbehaviour(&mut chain_a, &mut chain_b).await; +} diff --git a/ibc/derive/src/coercion.rs b/ibc/derive/src/coercion.rs index 37f4b471a..42ba87dbb 100644 --- a/ibc/derive/src/coercion.rs +++ b/ibc/derive/src/coercion.rs @@ -60,7 +60,7 @@ impl State { let crate_ = &self.crate_ident; quote! { fn encode_to_vec(&self) -> ::core::result::Result<::alloc::vec::Vec, ::tendermint_proto::Error> { - #crate_::protobuf::Protobuf::encode_vec(self) + return Ok(#crate_::protobuf::Protobuf::encode_vec(self.clone())); } } } diff --git a/ibc/modules/Cargo.toml b/ibc/modules/Cargo.toml index 64599f9c9..59fd658e2 100644 --- a/ibc/modules/Cargo.toml +++ b/ibc/modules/Cargo.toml @@ -52,7 +52,7 @@ mocks = ["clock", "std", "sha2"] [dependencies] # Proto definitions for all IBC-related interfaces, e.g., connections or channels. ibc-proto = { version = "0.18.0", path = "../proto", default-features = false } -ibc-core-host-types-new = { version = "0.48.1", package = "ibc-core-host-types", default-features = false } +ibc-core-host-types-new = { version = "0.50.0", package = "ibc-core-host-types", default-features = false } derive = { path = "../derive", package = "ibc-derive", default-features = false } ics23 = { git = "https://github.com/cosmos/ics23", rev = "74ce807b7be39a7e0afb4e2efb8e28a57965f57b", default-features = false } time = { version = "0.3", default-features = false } @@ -71,8 +71,8 @@ hex = { version = "0.4.3", default-features = false } primitive-types = { version = "0.12.0", default-features = false, features = ["serde_no_std"] } codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } sha2 = { version = "0.10.2", optional = true } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } log = { version = "0.4.0", default-features = false } cosmwasm-schema = { version = "1.1.3", default-features = false, optional = true } @@ -80,7 +80,7 @@ cosmwasm-schema = { version = "1.1.3", default-features = false, optional = true [dev-dependencies] env_logger = "0.9.0" tracing-subscriber = { version = "0.3.11", features = ["fmt", "env-filter", "json"]} -test-log = { version = "0.2.10", features = ["trace"] } +test-log = { version = "=0.2.10", features = ["trace"] } modelator = "0.4.2" sha2 = { version = "0.10.2" } tokio = { version = "1.32.0", features = ["full"] } diff --git a/ibc/modules/src/applications/transfer/msgs/transfer.rs b/ibc/modules/src/applications/transfer/msgs/transfer.rs index 6ad874bcd..483331e41 100644 --- a/ibc/modules/src/applications/transfer/msgs/transfer.rs +++ b/ibc/modules/src/applications/transfer/msgs/transfer.rs @@ -175,10 +175,7 @@ where type Error = Error; fn try_from(msg: MsgTransfer) -> Result { - Ok(Self { - type_url: TYPE_URL.to_string(), - value: msg.encode_vec().map_err(Error::decode_raw_msg)?, - }) + Ok(Self { type_url: TYPE_URL.to_string(), value: msg.encode_vec() }) } } diff --git a/ibc/modules/src/core/ics02_client/context.rs b/ibc/modules/src/core/ics02_client/context.rs index 3653e43c0..7641c0c83 100644 --- a/ibc/modules/src/core/ics02_client/context.rs +++ b/ibc/modules/src/core/ics02_client/context.rs @@ -235,6 +235,15 @@ where client_state: Self::AnyClientState, ) -> Result<(), Error>; + fn store_client_state_with_checksum( + &mut self, + client_id: ClientId, + client_state: Self::AnyClientState, + checksum: Vec, + ) -> Result<(), Error> { + unimplemented!() + } + /// Called upon successful client creation and update fn store_consensus_state( &mut self, diff --git a/ibc/modules/src/core/ics02_client/events.rs b/ibc/modules/src/core/ics02_client/events.rs index 74a43193c..4d4728b80 100644 --- a/ibc/modules/src/core/ics02_client/events.rs +++ b/ibc/modules/src/core/ics02_client/events.rs @@ -28,6 +28,9 @@ pub const HEIGHT_ATTRIBUTE_KEY: &str = "height"; /// The content of the `key` field for the attribute containing the client identifier. pub const CLIENT_ID_ATTRIBUTE_KEY: &str = "client_id"; +/// The content of the `key` field for the attribute containing the subject client identifier. +pub const SUBJECT_CLIENT_ID_ATTRIBUTE_KEY: &str = "subject_client_id"; + /// The content of the `key` field for the attribute containing the client type. pub const CLIENT_TYPE_ATTRIBUTE_KEY: &str = "client_type"; @@ -207,6 +210,49 @@ impl core::fmt::Debug for UpdateClient { } } +/// UpdateClientProposal event signals a proposal to update an on-chain client (IBC Client). +#[derive(Deserialize, Serialize, Clone, PartialEq, Eq)] +pub struct UpdateClientProposal { + pub client_id: ClientId, + pub client_type: String, +} + +impl UpdateClientProposal { + pub fn client_id(&self) -> &ClientId { + &self.client_id + } + + pub fn client_type(&self) -> &str { + &self.client_type + } +} + +impl From for IbcEvent { + fn from(v: UpdateClientProposal) -> Self { + IbcEvent::UpdateClientProposal(v) + } +} + +impl core::fmt::Display for UpdateClientProposal { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { + write!( + f, + "UpdateClientProposal: client_id: {}, client_type: {}", + self.client_id, self.client_type + ) + } +} + +impl core::fmt::Debug for UpdateClientProposal { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!( + f, + "UpdateClientProposal: client_id: {}, client_type: {}", + self.client_id, self.client_type + ) + } +} + /// ClientMisbehaviour event signals the update of an on-chain client (IBC Client) with evidence of /// misbehaviour. #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)] diff --git a/ibc/modules/src/core/ics02_client/height.rs b/ibc/modules/src/core/ics02_client/height.rs index bd4bc164c..f64fc6f12 100644 --- a/ibc/modules/src/core/ics02_client/height.rs +++ b/ibc/modules/src/core/ics02_client/height.rs @@ -35,9 +35,10 @@ use tendermint_proto::Protobuf; )] #[cfg_attr(feature = "cosmwasm", derive(JsonSchema))] pub struct Height { + #[cfg_attr(feature = "cosmwasm", serde(default))] + #[cfg_attr(feature = "cosmwasm", schemars(default))] /// Previously known as "epoch" pub revision_number: u64, - /// The height of a block pub revision_height: u64, } diff --git a/ibc/modules/src/core/ics03_connection/version.rs b/ibc/modules/src/core/ics03_connection/version.rs index 220d6cf7b..8054e2906 100644 --- a/ibc/modules/src/core/ics03_connection/version.rs +++ b/ibc/modules/src/core/ics03_connection/version.rs @@ -36,6 +36,14 @@ impl Version { pub fn is_supported_feature(&self, feature: String) -> bool { self.features.contains(&feature) } + + pub fn identifier(&self) -> &String { + &self.identifier + } + + pub fn features(&self) -> &Vec { + &self.features + } } impl Protobuf for Version {} diff --git a/ibc/modules/src/core/ics04_channel/channel.rs b/ibc/modules/src/core/ics04_channel/channel.rs index 595b2d5c5..2014c1256 100644 --- a/ibc/modules/src/core/ics04_channel/channel.rs +++ b/ibc/modules/src/core/ics04_channel/channel.rs @@ -375,8 +375,8 @@ impl State { } /// Provides a `to_string` method. -impl core::fmt::Display for State { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { +impl fmt::Display for State { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { write!(f, "{}", self.as_string()) } } diff --git a/ibc/modules/src/core/ics26_routing/msgs.rs b/ibc/modules/src/core/ics26_routing/msgs.rs index 46bd7c6a6..bf58a4ed6 100644 --- a/ibc/modules/src/core/ics26_routing/msgs.rs +++ b/ibc/modules/src/core/ics26_routing/msgs.rs @@ -94,9 +94,8 @@ where Ok(Ics26Envelope::Ics2Msg(ClientMsg::UpdateClient(domain_msg))) }, upgrade_client::TYPE_URL => { - let domain_msg = - upgrade_client::MsgUpgradeAnyClient::::decode_vec(&any_msg.value) - .map_err(Error::malformed_message_bytes)?; + let domain_msg = MsgUpgradeAnyClient::::decode_vec(&any_msg.value) + .map_err(Error::malformed_message_bytes)?; Ok(Ics26Envelope::Ics2Msg(ClientMsg::UpgradeClient(domain_msg))) }, diff --git a/ibc/modules/src/events.rs b/ibc/modules/src/events.rs index a798f3f93..c81705c8a 100644 --- a/ibc/modules/src/events.rs +++ b/ibc/modules/src/events.rs @@ -127,9 +127,10 @@ const APP_MODULE_EVENT: &str = "app_module"; /// Client event types const CREATE_CLIENT_EVENT: &str = "create_client"; const UPDATE_CLIENT_EVENT: &str = "update_client"; +const UPDATE_CLIENT_PROPOSAL_EVENT: &str = "update_client_proposal"; const CLIENT_MISBEHAVIOUR_EVENT: &str = "client_misbehaviour"; const UPGRADE_CLIENT_EVENT: &str = "upgrade_client"; -const PUSH_WASM_CODE_EVENT: &str = "push_wasm_code"; +const PUSH_WASM_CODE_EVENT: &str = "store_wasm_code"; /// Connection event types const CONNECTION_INIT_EVENT: &str = "connection_open_init"; const CONNECTION_TRY_EVENT: &str = "connection_open_try"; @@ -156,6 +157,7 @@ pub enum IbcEventType { NewBlock, CreateClient, UpdateClient, + UpdateClientProposal, UpgradeClient, ClientMisbehaviour, PushWasmCode, @@ -208,6 +210,7 @@ impl IbcEventType { IbcEventType::AppModule => APP_MODULE_EVENT, IbcEventType::Empty => EMPTY_EVENT, IbcEventType::ChainError => CHAIN_ERROR_EVENT, + IbcEventType::UpdateClientProposal => UPDATE_CLIENT_PROPOSAL_EVENT, } } } @@ -220,6 +223,7 @@ impl FromStr for IbcEventType { NEW_BLOCK_EVENT => Ok(IbcEventType::NewBlock), CREATE_CLIENT_EVENT => Ok(IbcEventType::CreateClient), UPDATE_CLIENT_EVENT => Ok(IbcEventType::UpdateClient), + UPDATE_CLIENT_PROPOSAL_EVENT => Ok(IbcEventType::UpdateClientProposal), UPGRADE_CLIENT_EVENT => Ok(IbcEventType::UpgradeClient), CLIENT_MISBEHAVIOUR_EVENT => Ok(IbcEventType::ClientMisbehaviour), PUSH_WASM_CODE_EVENT => Ok(IbcEventType::PushWasmCode), @@ -255,6 +259,7 @@ pub enum IbcEvent { CreateClient(ClientEvents::CreateClient), UpdateClient(ClientEvents::UpdateClient), + UpdateClientProposal(ClientEvents::UpdateClientProposal), UpgradeClient(ClientEvents::UpgradeClient), ClientMisbehaviour(ClientEvents::ClientMisbehaviour), PushWasmCode(ClientEvents::PushWasmCode), @@ -309,6 +314,7 @@ impl fmt::Display for IbcEvent { IbcEvent::CreateClient(ev) => write!(f, "CreateClientEv({})", ev), IbcEvent::UpdateClient(ev) => write!(f, "UpdateClientEv({})", ev), + IbcEvent::UpdateClientProposal(ev) => write!(f, "UpdateClientProposalEv({})", ev), IbcEvent::UpgradeClient(ev) => write!(f, "UpgradeClientEv({:?})", ev), IbcEvent::ClientMisbehaviour(ev) => write!(f, "ClientMisbehaviourEv({:?})", ev), IbcEvent::PushWasmCode(ev) => write!(f, "PushWasmCodeEv({:?})", ev), @@ -407,6 +413,7 @@ impl IbcEvent { IbcEvent::NewBlock(_) => IbcEventType::NewBlock, IbcEvent::CreateClient(_) => IbcEventType::CreateClient, IbcEvent::UpdateClient(_) => IbcEventType::UpdateClient, + IbcEvent::UpdateClientProposal(_) => IbcEventType::UpdateClientProposal, IbcEvent::ClientMisbehaviour(_) => IbcEventType::ClientMisbehaviour, IbcEvent::UpgradeClient(_) => IbcEventType::UpgradeClient, IbcEvent::PushWasmCode(_) => IbcEventType::PushWasmCode, diff --git a/ibc/modules/src/mock/client_state.rs b/ibc/modules/src/mock/client_state.rs index 0e9d98c8b..e31539e21 100644 --- a/ibc/modules/src/mock/client_state.rs +++ b/ibc/modules/src/mock/client_state.rs @@ -153,7 +153,7 @@ impl ClientState for MockClientState { } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } @@ -320,6 +320,6 @@ impl ConsensusState for MockConsensusState { } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/ibc/modules/src/mock/header.rs b/ibc/modules/src/mock/header.rs index ff7284d81..570463341 100644 --- a/ibc/modules/src/mock/header.rs +++ b/ibc/modules/src/mock/header.rs @@ -100,13 +100,11 @@ impl TryFrom for AnyClientMessage { impl From for Any { fn from(client_msg: AnyClientMessage) -> Self { match client_msg { - AnyClientMessage::Mock(MockClientMessage::Header(header)) => Any { - type_url: MOCK_HEADER_TYPE_URL.to_string(), - value: header.encode_vec().unwrap(), - }, + AnyClientMessage::Mock(MockClientMessage::Header(header)) => + Any { type_url: MOCK_HEADER_TYPE_URL.to_string(), value: header.encode_vec() }, AnyClientMessage::Mock(MockClientMessage::Misbehaviour(misbehaviour)) => Any { type_url: MOCK_MISBEHAVIOUR_TYPE_URL.to_string(), - value: misbehaviour.encode_vec().unwrap(), + value: misbehaviour.encode_vec(), }, } } @@ -191,7 +189,7 @@ mod tests { #[test] fn encode_any() { let header = MockHeader::new(Height::new(1, 10)).with_timestamp(Timestamp::none()); - let bytes = AnyClientMessage::from(header).encode_vec().unwrap(); + let bytes = AnyClientMessage::from(header).encode_vec(); assert_eq!( &bytes, diff --git a/ibc/modules/src/mock/misbehaviour.rs b/ibc/modules/src/mock/misbehaviour.rs index eff0f0e45..df50bc92a 100644 --- a/ibc/modules/src/mock/misbehaviour.rs +++ b/ibc/modules/src/mock/misbehaviour.rs @@ -41,7 +41,7 @@ pub struct MockMisbehaviour { impl MockMisbehaviour { fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/ibc/modules/src/proofs.rs b/ibc/modules/src/proofs.rs index 4e9894be0..ce519cdd5 100644 --- a/ibc/modules/src/proofs.rs +++ b/ibc/modules/src/proofs.rs @@ -34,11 +34,11 @@ define_error! { /// handshake, as well as for ICS4 packets, timeouts, and acknowledgements. #[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub struct Proofs { - object_proof: CommitmentProofBytes, - client_proof: Option, - consensus_proof: Option, + pub object_proof: CommitmentProofBytes, + pub client_proof: Option, + pub consensus_proof: Option, /// Currently used for proof_close for MsgTimeoutOnCLose where object_proof is proof_unreceived - other_proof: Option, + pub other_proof: Option, /// Height for the commitment root for proving the proofs above. /// When creating these proofs, the chain is queried at `height-1`. height: Height, @@ -89,7 +89,7 @@ impl Proofs { #[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub struct ConsensusProof { - proof: CommitmentProofBytes, + pub proof: CommitmentProofBytes, height: Height, } diff --git a/ibc/modules/src/test_utils.rs b/ibc/modules/src/test_utils.rs index 0454d0f0d..688d8ce6f 100644 --- a/ibc/modules/src/test_utils.rs +++ b/ibc/modules/src/test_utils.rs @@ -55,7 +55,12 @@ use crate::core::{ ics02_client::context::ClientTypes, ics04_channel::msgs::acknowledgement::Acknowledgement, ics26_routing::context::ModuleCallbackContext, }; -use tendermint::{block, consensus, evidence, public_key::Algorithm}; +use tendermint::{ + block, + consensus::{self, params::AbciParams}, + evidence, + public_key::Algorithm, +}; // Needed in mocks. pub fn default_consensus_params() -> consensus::Params { @@ -63,11 +68,12 @@ pub fn default_consensus_params() -> consensus::Params { block: block::Size { max_bytes: 22020096, max_gas: -1, time_iota_ms: 1000 }, evidence: evidence::Params { max_age_num_blocks: 100000, - max_age_duration: evidence::Duration(core::time::Duration::new(48 * 3600, 0)), + max_age_duration: evidence::Duration(Duration::new(48 * 3600, 0)), max_bytes: 0, }, validator: consensus::params::ValidatorParams { pub_key_types: vec![Algorithm::Ed25519] }, version: Some(consensus::params::VersionParams::default()), + abci: AbciParams::default(), } } diff --git a/ibc/proto/Cargo.toml b/ibc/proto/Cargo.toml index 1c672cd14..775e29e90 100644 --- a/ibc/proto/Cargo.toml +++ b/ibc/proto/Cargo.toml @@ -30,7 +30,7 @@ serde = { version = "1.0", default-features = false } schemars = { version = "0.8", optional = true } base64 = { version = "0.13", default-features = false, features = ["alloc"] } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [features] default = ["std", "client"] diff --git a/ibc/proto/src/prost/cosmos.base.store.v1beta1.rs b/ibc/proto/src/prost/cosmos.base.store.v1beta1.rs index fa37f3948..589b9625a 100644 --- a/ibc/proto/src/prost/cosmos.base.store.v1beta1.rs +++ b/ibc/proto/src/prost/cosmos.base.store.v1beta1.rs @@ -3,89 +3,80 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CommitInfo { - #[prost(int64, tag = "1")] - pub version: i64, - #[prost(message, repeated, tag = "2")] - pub store_infos: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "1")] + pub version: i64, + #[prost(message, repeated, tag = "2")] + pub store_infos: ::prost::alloc::vec::Vec, } /// StoreInfo defines store-specific commit information. It contains a reference /// between a store name and the commit ID. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StoreInfo { - #[prost(string, tag = "1")] - pub name: ::prost::alloc::string::String, - #[prost(message, optional, tag = "2")] - pub commit_id: ::core::option::Option, + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + #[prost(message, optional, tag = "2")] + pub commit_id: ::core::option::Option, } /// CommitID defines the commitment information when a specific store is /// committed. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CommitId { - #[prost(int64, tag = "1")] - pub version: i64, - #[prost(bytes = "vec", tag = "2")] - pub hash: ::prost::alloc::vec::Vec, + #[prost(int64, tag = "1")] + pub version: i64, + #[prost(bytes = "vec", tag = "2")] + pub hash: ::prost::alloc::vec::Vec, } /// StoreKVPair is a KVStore KVPair used for listening to state changes (Sets and Deletes) -/// It optionally includes the StoreKey for the originating KVStore and a Boolean flag to distinguish between Sets and -/// Deletes +/// It optionally includes the StoreKey for the originating KVStore and a Boolean flag to +/// distinguish between Sets and Deletes /// /// Since: cosmos-sdk 0.43 #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StoreKvPair { - /// the store key for the KVStore this pair originates from - #[prost(string, tag = "1")] - pub store_key: ::prost::alloc::string::String, - /// true indicates a delete operation, false indicates a set operation - #[prost(bool, tag = "2")] - pub delete: bool, - #[prost(bytes = "vec", tag = "3")] - pub key: ::prost::alloc::vec::Vec, - #[prost(bytes = "vec", tag = "4")] - pub value: ::prost::alloc::vec::Vec, + /// the store key for the KVStore this pair originates from + #[prost(string, tag = "1")] + pub store_key: ::prost::alloc::string::String, + /// true indicates a delete operation, false indicates a set operation + #[prost(bool, tag = "2")] + pub delete: bool, + #[prost(bytes = "vec", tag = "3")] + pub key: ::prost::alloc::vec::Vec, + #[prost(bytes = "vec", tag = "4")] + pub value: ::prost::alloc::vec::Vec, } /// BlockMetadata contains all the abci event data of a block /// the file streamer dump them into files together with the state changes. #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BlockMetadata { - #[prost(message, optional, tag = "1")] - pub request_begin_block: ::core::option::Option< - ::tendermint_proto::abci::RequestBeginBlock, - >, - #[prost(message, optional, tag = "2")] - pub response_begin_block: ::core::option::Option< - ::tendermint_proto::abci::ResponseBeginBlock, - >, - #[prost(message, repeated, tag = "3")] - pub deliver_txs: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "4")] - pub request_end_block: ::core::option::Option< - ::tendermint_proto::abci::RequestEndBlock, - >, - #[prost(message, optional, tag = "5")] - pub response_end_block: ::core::option::Option< - ::tendermint_proto::abci::ResponseEndBlock, - >, - #[prost(message, optional, tag = "6")] - pub response_commit: ::core::option::Option< - ::tendermint_proto::abci::ResponseCommit, - >, + #[prost(message, optional, tag = "1")] + pub request_begin_block: + ::core::option::Option<::tendermint_proto::v0_37::abci::RequestBeginBlock>, + #[prost(message, optional, tag = "2")] + pub response_begin_block: + ::core::option::Option<::tendermint_proto::v0_37::abci::ResponseBeginBlock>, + #[prost(message, repeated, tag = "3")] + pub deliver_txs: ::prost::alloc::vec::Vec, + #[prost(message, optional, tag = "4")] + pub request_end_block: ::core::option::Option<::tendermint_proto::v0_37::abci::RequestEndBlock>, + #[prost(message, optional, tag = "5")] + pub response_end_block: + ::core::option::Option<::tendermint_proto::v0_37::abci::ResponseEndBlock>, + #[prost(message, optional, tag = "6")] + pub response_commit: ::core::option::Option<::tendermint_proto::v0_37::abci::ResponseCommit>, } /// Nested message and enum types in `BlockMetadata`. pub mod block_metadata { - /// DeliverTx encapulate deliver tx request and response. - #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Message)] - pub struct DeliverTx { - #[prost(message, optional, tag = "1")] - pub request: ::core::option::Option<::tendermint_proto::abci::RequestDeliverTx>, - #[prost(message, optional, tag = "2")] - pub response: ::core::option::Option< - ::tendermint_proto::abci::ResponseDeliverTx, - >, - } + /// DeliverTx encapulate deliver tx request and response. + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct DeliverTx { + #[prost(message, optional, tag = "1")] + pub request: ::core::option::Option<::tendermint_proto::v0_37::abci::RequestDeliverTx>, + #[prost(message, optional, tag = "2")] + pub response: ::core::option::Option<::tendermint_proto::v0_37::abci::ResponseDeliverTx>, + } } diff --git a/ibc/proto/src/prost/ibc.lightclients.wasm.v1.rs b/ibc/proto/src/prost/ibc.lightclients.wasm.v1.rs index 0e9d9c5ce..20be15008 100644 --- a/ibc/proto/src/prost/ibc.lightclients.wasm.v1.rs +++ b/ibc/proto/src/prost/ibc.lightclients.wasm.v1.rs @@ -4,7 +4,7 @@ pub struct MsgPushNewWasmCode { #[prost(string, tag = "1")] pub signer: ::prost::alloc::string::String, - #[prost(bytes = "vec", tag = "3")] + #[prost(bytes = "vec", tag = "2")] pub code: ::prost::alloc::vec::Vec, } /// Response in case of successful handling diff --git a/light-clients/cf-guest-cw/Cargo.toml b/light-clients/cf-guest-cw/Cargo.toml new file mode 100644 index 000000000..89cfa4e21 --- /dev/null +++ b/light-clients/cf-guest-cw/Cargo.toml @@ -0,0 +1,93 @@ +[package] +name = "cf-guest-cw" +version = "0.1.0" +authors = ["Composable, Strangelove Developers"] +edition = "2021" + +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", +] + +[lib] +crate-type = ["cdylib", "rlib"] + +[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-schema = "1.1.3" +cosmwasm-std = "1.1.3" +schemars = "0.8.10" +serde = { version = "1.0.145", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.31" } +sha2 = "0.10" +sha3 = "0.10" +derive_more = "0.99.17" + +# ed25519 = { version = "1.5", default-features = false } +# ed25519-consensus = { version = "2", optional = true, default-features = false } +ibc = { path = "../../ibc/modules", default-features = false } +ibc-derive = { path = "../../ibc/derive", default-features = false } +ibc-proto = { path = "../../ibc/proto", default-features = false, features = ["json-schema"] } +ics23 = { git = "https://github.com/cosmos/ics23", rev = "74ce807b7be39a7e0afb4e2efb8e28a57965f57b", default-features = false } +# ics07-tendermint = { path = "../ics07-tendermint", default-features = false } +cf-guest = { path = "../cf-guest", default-features = false } +ics08-wasm = { path = "../ics08-wasm", default-features = false, features = ["cosmwasm"] } +prost = { version = "0.11", default-features = false } +ed25519-dalek = { version = "2.1.1", default-features = false, features = ["pkcs8"] } +byteorder = { version = "1.3.2", default-features = false } +digest = { version = "0.10.3", default-features = false } +hex = "0.4.3" +guestchain = { path = "../../../emulated-light-client/common/guestchain", default-features = false } +trie-ids = { path = "../../../emulated-light-client/common/trie-ids", default-features = false } +borsh = { version = "0.10.3", default-features = false } + + +#tendermint = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false } # cannot be defined as optional in workspace +#tendermint-proto = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false } +#tendermint-light-client-verifier = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false } + +[dev-dependencies] +cw-multi-test = "0.15.1" +hex = "0.4.3" +hyperspace-primitives = { path = "../../hyperspace/primitives", features = ["testing"] } +pallet-ibc = { path = "../../contracts/pallet-ibc" } +serde-json-wasm = { version = "0.5.0", default-features = false } +serde_json = { version = "1.0.93", default-features = false } +# tendermint = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false } + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +default = [] +# default = ["rust-crypto"] +# rust-crypto = ["ed25519-consensus"] +std = [ + "byteorder/std", + "digest/std", + "ed25519-dalek/std", + "hex/std", + "ibc/std", + "ibc-proto/std", + # "ics07-tendermint/std", + "ics08-wasm/std", + "ics23/std", + "pallet-ibc/std", + "prost/std", + "serde/std", + "serde_json/std", + "sha2/std", + "sha3/std", + # "tendermint/std" +] +test = [ + "std" +] diff --git a/light-clients/cf-guest-cw/src/bin/schema.rs b/light-clients/cf-guest-cw/src/bin/schema.rs new file mode 100644 index 000000000..77f3223ab --- /dev/null +++ b/light-clients/cf-guest-cw/src/bin/schema.rs @@ -0,0 +1,25 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// use cosmwasm_schema::write_api; +// use ics07_tendermint_cw::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + // write_api! { + // instantiate: InstantiateMsg, + // execute: ExecuteMsg, + // query: QueryMsg, + // } +} diff --git a/light-clients/cf-guest-cw/src/channel.rs b/light-clients/cf-guest-cw/src/channel.rs new file mode 100644 index 000000000..7c593206f --- /dev/null +++ b/light-clients/cf-guest-cw/src/channel.rs @@ -0,0 +1,137 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::context::Context; +use ibc::{ + core::{ + ics04_channel::{ + channel::ChannelEnd, + commitment::{AcknowledgementCommitment, PacketCommitment as PacketCommitmentType}, + context::ChannelReader, + error::Error, + packet::{Receipt, Sequence}, + }, + ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId}, + }, + timestamp::Timestamp, + Height, +}; +use std::time::Duration; + +impl<'a> ChannelReader for Context<'a> { + fn channel_end(&self, _port_channel_id: &(PortId, ChannelId)) -> Result { + Err(Error::implementation_specific( + "'channel_end' is unavailable from the client".to_string(), + )) + } + + fn connection_channels( + &self, + _conn_id: &ConnectionId, + ) -> Result, Error> { + Err(Error::implementation_specific( + "'connection_channels' is unavailable from the client".to_string(), + )) + } + + fn get_next_sequence_send( + &self, + _port_channel_id: &(PortId, ChannelId), + ) -> Result { + Err(Error::implementation_specific( + "'get_next_sequence_send' is unavailable from the client".to_string(), + )) + } + + fn get_next_sequence_recv( + &self, + _port_channel_id: &(PortId, ChannelId), + ) -> Result { + Err(Error::implementation_specific( + "'get_next_sequence_recv' is unavailable from the client".to_string(), + )) + } + + fn get_next_sequence_ack( + &self, + _port_channel_id: &(PortId, ChannelId), + ) -> Result { + Err(Error::implementation_specific( + "'get_next_sequence_ack' is unavailable from the client".to_string(), + )) + } + + fn get_packet_commitment( + &self, + _key: &(PortId, ChannelId, Sequence), + ) -> Result { + Err(Error::implementation_specific( + "'get_packet_commitment' is unavailable from the client".to_string(), + )) + } + + fn get_packet_receipt(&self, _key: &(PortId, ChannelId, Sequence)) -> Result { + Err(Error::implementation_specific( + "'get_packet_receipt' is unavailable from the client".to_string(), + )) + } + + fn get_packet_acknowledgement( + &self, + _key: &(PortId, ChannelId, Sequence), + ) -> Result { + Err(Error::implementation_specific( + "'get_packet_acknowledgement' is unavailable from the client".to_string(), + )) + } + + /// A hashing function for packet commitments + fn hash(&self, value: Vec) -> Vec { + cf_guest::digest(&value).as_slice().into() + } + + fn client_update_time( + &self, + _client_id: &ClientId, + _height: Height, + ) -> Result { + Err(Error::implementation_specific( + "'client_update_time' is unavailable from the client".to_string(), + )) + } + + fn client_update_height( + &self, + _client_id: &ClientId, + _height: Height, + ) -> Result { + Err(Error::implementation_specific( + "'client_update_height' is unavailable from the client".to_string(), + )) + } + + /// Returns a counter on the number of channel ids have been created thus far. + /// The value of this counter should increase only via method + /// `ChannelKeeper::increase_channel_counter`. + fn channel_counter(&self) -> Result { + Err(Error::implementation_specific( + "'channel_counter' is unavailable from the client".to_string(), + )) + } + + fn max_expected_time_per_block(&self) -> Duration { + unimplemented!("'max_expected_time_per_block' is unavailable from the client") + } +} diff --git a/light-clients/cf-guest-cw/src/client.rs b/light-clients/cf-guest-cw/src/client.rs new file mode 100644 index 000000000..8bdbe73a5 --- /dev/null +++ b/light-clients/cf-guest-cw/src/client.rs @@ -0,0 +1,320 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + context::Context, + ics23::{ + ClientStates, ConsensusStates, FakeInner, ProcessedStates, ReadonlyClientStates, + ReadonlyClients, ReadonlyConsensusStates, ReadonlyProcessedStates, + }, +}; +use ibc::{ + core::{ + ics02_client::{ + client_consensus::ConsensusState as _, + client_state::{ClientState as _, ClientType}, + context::{ClientKeeper, ClientReader, ClientTypes}, + error::Error, + }, + ics24_host::identifier::ClientId, + }, + protobuf::Protobuf, + timestamp::Timestamp, + Height, +}; +use ibc_proto::google::protobuf::Any; + +use cf_guest::{client_def::GuestClient, ClientMessage, ClientState, ConsensusState}; + +// use ics07_tendermint::{ +// client_def::TendermintClient, client_message::ClientMessage, client_state::ClientState, +// consensus_state::ConsensusState, HostFunctionsProvider, +// }; +use prost::Message; +use std::str::FromStr; + +impl<'a> ClientTypes for Context<'a> { + type AnyClientMessage = ClientMessage; + type AnyClientState = ClientState; + type AnyConsensusState = ConsensusState; + type ClientDef = GuestClient; +} + +impl<'a> ClientReader for Context<'a> { + fn client_type(&self, client_id: &ClientId) -> Result { + let clients = ReadonlyClients::new(self.storage()); + if !clients.contains_key(client_id) { + return Err(Error::client_not_found(client_id.clone())); + } + + let data = clients + .get(client_id) + .ok_or_else(|| Error::client_not_found(client_id.clone()))?; + let data = String::from_utf8(data).map_err(|e| { + Error::implementation_specific(format!( + "[client_type]: error decoding client type bytes to string {e}" + )) + })?; + match ClientType::from_str(&data) { + Err(_err) => Err(Error::unknown_client_type(data.to_string())), + Ok(val) => Ok(val), + } + } + + fn client_state( + &self, + client_id: &ClientId, + ) -> Result, Error> { + let client_states = ReadonlyClientStates::new(self.storage()); + let data = client_states.get().ok_or_else(|| Error::client_not_found(client_id.clone()))?; + let state = Self::decode_client_state(&data)?; + Ok(state) + } + + fn consensus_state( + &self, + client_id: &ClientId, + height: Height, + ) -> Result { + let consensus_states = ReadonlyConsensusStates::new(self.storage()); + let value = consensus_states + .get(height) + .ok_or_else(|| Error::consensus_state_not_found(client_id.clone(), height))?; + let any_consensus_state = Self::decode_consensus_state(&value)?; + Ok(any_consensus_state) + } + + fn host_client_type(&self) -> String { + "ics07-tendermint".to_string() + } + + /// Similar to `consensus_state`, attempt to retrieve the consensus state, + /// but return `None` if no state exists at the given height. + /*fn maybe_consensus_state( + &self, + client_id: &ClientId, + height: Height, + ) -> Result, Error> { + unimplemented!() + //match self.consensus_state(client_id, height, &mut Vec::new()) { + // Ok(cs) => Ok(Some(cs)), + // Err(e) => match e.detail() { + // ErrorDetail::ConsensusStateNotFound(_) => Ok(None), + // _ => Err(e), + // }, + //} + }*/ + + fn next_consensus_state( + &self, + client_id: &ClientId, + height: Height, + ) -> Result, Error> { + let processed_state = ReadonlyProcessedStates::new(self.storage()); + match processed_state.get_next_height(height) { + Some(next_height) => self.consensus_state(&client_id.clone(), next_height).map(Some), + None => Ok(None), + } + } + + fn prev_consensus_state( + &self, + client_id: &ClientId, + height: Height, + ) -> Result, Error> { + let processed_state = ReadonlyProcessedStates::new(self.storage()); + match processed_state.get_prev_height(height) { + Some(prev_height) => self.consensus_state(&client_id.clone(), prev_height).map(Some), + None => Ok(None), + } + } + + fn host_height(&self) -> Height { + Height::new(0, self.env.block.height) + } + + fn host_timestamp(&self) -> Timestamp { + let time = self.env.block.time; + Timestamp::from_nanoseconds(time.nanos()).expect("invalid timestamp") + } + + fn host_consensus_state( + &self, + _height: Height, + _proof: Option>, + _client_state: &ClientState, + ) -> Result { + unimplemented!() + /*let consensus_state = + HOST_CONSENSUS_STATE.load(self.storage(), height.revision_height).map_err(|_| { + Error::implementation_specific(format!( + "[host_consensus_state]: consensus state not found for host at height {}", + height + )) + })?; + Ok(consensus_state)*/ + } + + fn client_counter(&self) -> Result { + unimplemented!() + /*let count = CLIENT_COUNTER.load(self.storage()).unwrap_or_default(); + log!(self, "in client : [client_counter] >> client_counter: {:?}", count); + Ok(count as u64)*/ + } +} + +impl<'a> ClientKeeper for Context<'a> { + fn store_client_type( + &mut self, + _client_id: ClientId, + _client_type: ClientType, + ) -> Result<(), Error> { + unimplemented!() + } + + fn store_client_state( + &mut self, + client_id: ClientId, + client_state: Self::AnyClientState, + ) -> Result<(), Error> { + let client_states = ReadonlyClientStates::new(self.storage()); + let checksum = match self.checksum.clone() { + None => { + let encoded_wasm_client_state = client_states + .get() + .ok_or_else(|| Error::client_not_found(client_id.clone()))?; + let any = Any::decode(&*encoded_wasm_client_state).map_err(Error::decode)?; + let wasm_client_state = ics08_wasm::client_state::ClientState::< + FakeInner, + FakeInner, + FakeInner, + >::decode_vec(&any.value) + .map_err(|e| { + Error::implementation_specific(format!( + "[client_state]: error decoding client state bytes to WasmConsensusState {}", + e + )) + })?; + wasm_client_state.checksum + }, + Some(x) => x, + }; + + let encoded = Self::encode_client_state(client_state, checksum)?; + let mut client_state_storage = ClientStates::new(self.storage_mut()); + client_state_storage.insert(encoded); + Ok(()) + } + + fn store_consensus_state( + &mut self, + client_id: ClientId, + height: Height, + consensus_state: Self::AnyConsensusState, + ) -> Result<(), Error> { + let encoded = Self::encode_consensus_state(consensus_state); + let mut consensus_states = ConsensusStates::new(self.storage_mut()); + consensus_states.insert(height, encoded); + + self.store_update_time(client_id.clone(), height, self.host_timestamp())?; + self.store_update_height(client_id, height, self.host_height())?; + + Ok(()) + } + + fn increase_client_counter(&mut self) { + unimplemented!() + } + + fn store_update_time( + &mut self, + _client_id: ClientId, + height: Height, + timestamp: Timestamp, + ) -> Result<(), Error> { + let mut processed_state = ProcessedStates::new(self.storage_mut()); + processed_state.set_processed_time(height, timestamp.nanoseconds(), &mut Vec::new()); + + Ok(()) + } + + fn store_update_height( + &mut self, + _client_id: ClientId, + height: Height, + host_height: Height, + ) -> Result<(), Error> { + let mut processed_state = ProcessedStates::new(self.storage_mut()); + processed_state.set_processed_height(height, host_height.revision_height, &mut Vec::new()); + processed_state.set_iteration_key(height, &mut Vec::new()); + Ok(()) + } + + fn validate_self_client(&self, _client_state: &Self::AnyClientState) -> Result<(), Error> { + unimplemented!() + } +} + +impl<'a> Context<'a> { + pub fn decode_client_state(data: &[u8]) -> Result, Error> { + let any = Any::decode(data).map_err(Error::decode)?; + let wasm_state = + ics08_wasm::client_state::ClientState::::decode_vec( + &any.value, + ) + .map_err(|e| { + Error::implementation_specific(format!( + "[client_state]: error decoding client state bytes to WasmConsensusState {e}" + )) + })?; + let any = Any::decode(&*wasm_state.data).map_err(Error::decode)?; + let state = ClientState::decode_vec(&any.value).map_err(Error::invalid_any_client_state)?; + Ok(state) + } + + pub fn decode_consensus_state(value: &[u8]) -> Result { + let any = Any::decode(&mut &*value).map_err(Error::decode)?; + let wasm_consensus_state = + ics08_wasm::consensus_state::ConsensusState::::decode_vec(&any.value) + .map_err(Error::invalid_any_consensus_state)?; + let any = Any::decode(&mut &wasm_consensus_state.data[..]).map_err(Error::decode)?; + let any_consensus_state = + ConsensusState::decode_vec(&any.value).map_err(Error::invalid_any_consensus_state)?; + Ok(any_consensus_state) + } + + pub fn encode_client_state( + client_state: ClientState, + checksum: Vec, + ) -> Result, Error> { + let mut wasm_client_state = + ics08_wasm::client_state::ClientState::::default(); + wasm_client_state.checksum = checksum; + wasm_client_state.data = + ibc_proto::google::protobuf::Any::from(&client_state).encode_to_vec(); + wasm_client_state.latest_height = client_state.latest_height(); + let vec1 = wasm_client_state.to_any().encode_to_vec(); + Ok(vec1) + } + + pub fn encode_consensus_state(consensus_state: ConsensusState) -> Vec { + let wasm_consensus_state = ics08_wasm::consensus_state::ConsensusState { + data: ibc_proto::google::protobuf::Any::from(&consensus_state).encode_to_vec(), + // timestamp: consensus_state.timestamp().nanoseconds(), + inner: Box::new(FakeInner), + }; + wasm_consensus_state.to_any().encode_to_vec() + } +} diff --git a/light-clients/cf-guest-cw/src/connection.rs b/light-clients/cf-guest-cw/src/connection.rs new file mode 100644 index 000000000..a1861d6a6 --- /dev/null +++ b/light-clients/cf-guest-cw/src/connection.rs @@ -0,0 +1,52 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::context::Context; +use ibc::{ + core::{ + ics03_connection::{connection::ConnectionEnd, context::ConnectionReader, error::Error}, + ics23_commitment::commitment::CommitmentPrefix, + ics24_host::identifier::ConnectionId, + }, + Height, +}; +use std::time::Duration; + +impl<'a> ConnectionReader for Context<'a> { + fn minimum_delay_period(&self) -> Duration { + unimplemented!("minimum_delay_period") + } + + fn connection_end(&self, _conn_id: &ConnectionId) -> Result { + Err(Error::implementation_specific( + "'connection_end' is unavailable from the client".to_string(), + )) + } + + fn host_oldest_height(&self) -> Height { + unimplemented!("the method should be removed in the future"); + } + + #[allow(clippy::disallowed_methods)] + fn commitment_prefix(&self) -> CommitmentPrefix { + unimplemented!("'commitment_prefix' is unavailable from the client"); + } + + fn connection_counter(&self) -> Result { + Err(Error::implementation_specific( + "'connection_counter' is unavailable from the client".to_string(), + )) + } +} diff --git a/light-clients/cf-guest-cw/src/context.rs b/light-clients/cf-guest-cw/src/context.rs new file mode 100644 index 000000000..527a325db --- /dev/null +++ b/light-clients/cf-guest-cw/src/context.rs @@ -0,0 +1,168 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + ics23::{ + ClientStates, ConsensusStates, ReadonlyClientStates, ReadonlyConsensusStates, + ReadonlyProcessedStates, + }, + ContractError, +}; +use cf_guest::{ClientState, ConsensusState}; +use cosmwasm_std::{Deps, DepsMut, Empty, Env, Storage}; +use ibc::{ + core::{ + ics02_client::{error::Error, events::Checksum}, + ics26_routing::context::ReaderContext, + }, + Height, +}; +use std::{fmt, fmt::Debug}; + +pub struct Context<'a> { + pub deps_mut: Option>, + pub deps: Option>, + pub checksum: Option, + pub env: Env, +} + +impl<'a> PartialEq for Context<'a> { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl<'a> Eq for Context<'a> {} + +impl<'a> Debug for Context<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Context {{ deps: DepsMut }}") + } +} + +impl<'a> Clone for Context<'a> { + fn clone(&self) -> Self { + panic!("Context is not cloneable") + } +} + +impl<'a> Context<'a> { + pub fn new(deps: DepsMut<'a>, env: Env) -> Self { + Self { deps_mut: Some(deps), deps: None, env, checksum: None } + } + + pub fn new_ro(deps: Deps<'a>, env: Env) -> Self { + Self { deps_mut: None, deps: Some(deps), env, checksum: None } + } + + pub fn log(&self, msg: &str) { + match &self.deps_mut { + Some(deps_mut) => deps_mut.api.debug(msg), + None => unimplemented!(), + } + } + + pub fn storage(&self) -> &dyn Storage { + match &self.deps_mut { + Some(deps_mut) => deps_mut.storage, + None => match &self.deps { + Some(deps) => deps.storage, + None => unimplemented!(), + }, + } + } + + pub fn storage_mut(&mut self) -> &mut dyn Storage { + match &mut self.deps_mut { + Some(deps_mut) => deps_mut.storage, + None => unimplemented!(), + } + } +} + +impl<'a> Context<'a> { + pub fn processed_timestamp(&self, height: Height) -> Result { + ReadonlyProcessedStates::new(self.storage()) + .get_processed_time(height, &mut Vec::new()) + .ok_or_else(|| { + Error::implementation_specific("problem getting processed timestamp".into()) + }) + } + + pub fn processed_height(&self, height: Height) -> Result { + ReadonlyProcessedStates::new(self.storage()) + .get_processed_height(height, &mut Vec::new()) + .ok_or_else(|| { + Error::implementation_specific("problem getting processed height".into()) + }) + } + + pub fn consensus_state_prefixed( + &self, + height: Height, + prefix: &[u8], + ) -> Result { + let bytes = ReadonlyConsensusStates::new(self.storage()) + .get_prefixed(height, prefix) + .ok_or_else(|| { + ContractError::Other(format!( + "no consensus state found for height {height} and prefix {prefix:?}", + )) + })?; + Context::decode_consensus_state(&bytes) + .map_err(|e| ContractError::Other(format!("error decoding consensus state: {e:?}"))) + } + + pub fn store_consensus_state_prefixed( + &mut self, + height: Height, + consensus_state: ConsensusState, + prefix: &[u8], + ) { + let encoded = Context::encode_consensus_state(consensus_state); + let mut consensus_states = ConsensusStates::new(self.storage_mut()); + consensus_states.insert_prefixed(height, encoded, prefix); + } + + pub fn client_state_prefixed( + &self, + prefix: &[u8], + ) -> Result, ContractError> { + let bytes = + ReadonlyClientStates::new(self.storage()).get_prefixed(prefix).ok_or_else(|| { + ContractError::Other(format!("no client state found for prefix {prefix:?}",)) + })?; + Context::decode_client_state(&bytes) + .map_err(|e| ContractError::Other(format!("error decoding client state: {e:?}"))) + } + + pub fn store_client_state_prefixed( + &mut self, + client_state: ClientState, + prefix: &[u8], + ) -> Result<(), ContractError> { + let client_states = ReadonlyClientStates::new(self.storage()); + let data = client_states + .get_prefixed(prefix) + .ok_or_else(|| ContractError::Other("no client state found for prefix".to_string()))?; + let encoded = Context::encode_client_state(client_state, data) + .map_err(|e| ContractError::Other(format!("error encoding client state: {e:?}")))?; + let mut client_states = ClientStates::new(self.storage_mut()); + client_states.insert_prefixed(encoded, prefix); + Ok(()) + } +} + +impl<'a> ReaderContext for Context<'a> {} diff --git a/light-clients/cf-guest-cw/src/contract.rs b/light-clients/cf-guest-cw/src/contract.rs new file mode 100644 index 000000000..c753ed624 --- /dev/null +++ b/light-clients/cf-guest-cw/src/contract.rs @@ -0,0 +1,314 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + context::Context, + error::ContractError, + helpers, + ics23::ReadonlyProcessedStates, + msg::{ + CheckForMisbehaviourMsg, + ContractResult, + ExportMetadataMsg, + QueryMsg, + QueryResponse, + StatusMsg, + SudoMsg as ExecuteMsg, + UpdateStateMsg, + UpdateStateOnMisbehaviourMsg, + VerifyClientMessage, + VerifyMembershipMsg, + VerifyNonMembershipMsg, + VerifyUpgradeAndUpdateStateMsg, + // MigrateMsg + }, + state::{get_client_state, get_consensus_state}, +}; +use cf_guest::{client_def::GuestClient, proof::verify}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use ibc::{ + core::{ + ics02_client::{ + client_consensus::ConsensusState as _, + client_def::{ClientDef, ConsensusUpdateResult}, + client_state::ClientState as _, + context::{ClientKeeper, ClientReader}, + }, + ics23_commitment::commitment::CommitmentPrefix, + ics24_host::identifier::ClientId, + }, + protobuf::Protobuf, +}; +use ics08_wasm::{instantiate::InstantiateMessage, SUBJECT_PREFIX}; +use prost::Message; +use std::str::FromStr; + +// #[entry_point] +// pub fn migrate(_deps: DepsMut, _env: Env, _msg: MigrateMsg) -> Result { +// // No state migrations performed, just returned a Response +// Ok(Response::default()) +// } + +fn process_instantiate_msg( + msg: InstantiateMessage, + ctx: &mut Context, + client_id: ClientId, +) -> Result { + let any = ibc_proto::google::protobuf::Any::decode(&mut msg.client_state.as_slice())?; + let client_state = cf_guest::ClientState::decode_vec(&any.value)?; + let any = ibc_proto::google::protobuf::Any::decode(&mut msg.consensus_state.as_slice())?; + let consensus_state = cf_guest::ConsensusState::decode_vec(&any.value)?; + + ctx.checksum = Some(msg.checksum); + let height = client_state.latest_height(); + ctx.store_client_state(client_id.clone(), client_state) + .map_err(ContractError::from)?; + ctx.store_consensus_state(client_id.clone(), height, consensus_state) + .map_err(ContractError::from)?; + + ctx.store_update_height(client_id.clone(), height, ctx.host_height()) + .map_err(ContractError::from)?; + ctx.store_update_time(client_id, height, ctx.host_timestamp()) + .map_err(ContractError::from)?; + + Ok(to_binary(&ContractResult::success())?) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: InstantiateMessage, +) -> Result { + let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid"); + + let mut ctx = Context::new(deps, env); + let data = process_instantiate_msg(msg, &mut ctx, client_id.clone())?; + let mut response = Response::default(); + response.data = Some(data); + Ok(response) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn sudo(deps: DepsMut, env: Env, msg: ExecuteMsg) -> Result { + let client = GuestClient::::default(); + let mut ctx = Context::new(deps, env); + let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid"); + let data = process_message(msg, client, &mut ctx, client_id)?; + let mut response = Response::default(); + response.data = Some(data); + Ok(response) +} + +fn process_message( + msg: ExecuteMsg, + client: GuestClient, + ctx: &mut Context, + client_id: ClientId, +) -> Result { + //log!(ctx, "process_message: {:?}", msg); + let result = match msg { + ExecuteMsg::VerifyMembership(msg) => { + let _ = ctx.client_state(&client_id)?; + let msg = VerifyMembershipMsg::try_from(msg)?; + // panic!("Message {:?}", msg.proof.as_bytes()); + // crate::helpers::verify_delay_passed( + // ctx, + // msg.height, + // msg.delay_time_period, + // msg.delay_block_period, + // )?; + let consensus_state = ctx.consensus_state(&client_id, msg.height)?; + verify( + &CommitmentPrefix::default(), + &msg.proof, + &consensus_state.root(), + msg.path, + Some(msg.value.as_ref()), + )?; + Ok(()).map(|_| to_binary(&ContractResult::success())) + }, + ExecuteMsg::VerifyNonMembership(msg) => { + let _ = ctx.client_state(&client_id)?; + let msg = VerifyNonMembershipMsg::try_from(msg)?; + // crate::helpers::verify_delay_passed( + // ctx, + // msg.height, + // msg.delay_time_period, + // msg.delay_block_period, + // )?; + let consensus_state = ctx.consensus_state(&client_id, msg.height)?; + + verify( + &CommitmentPrefix::default(), + &msg.proof, + &consensus_state.root(), + msg.path, + None, + ) + .map_err(ContractError::from) + .map(|_| to_binary(&ContractResult::success())) + }, + // ExecuteMsg::VerifyClientMessage(msg) => { + // let client_state = ctx.client_state(&client_id)?; + // let msg = VerifyClientMessage::try_from(msg)?; + // client + // .verify_client_message(ctx, client_id, client_state, msg.client_message) + // .map_err(ContractError::from) + // .map(|_| to_binary(&ContractResult::success())) + // }, + // ExecuteMsg::CheckForMisbehaviour(msg) => { + // let client_state = ctx.client_state(&client_id)?; + // let msg = CheckForMisbehaviourMsg::try_from(msg)?; + // client + // .check_for_misbehaviour(ctx, client_id, client_state, msg.client_message) + // .map_err(ContractError::from) + // .map(|result| to_binary(&ContractResult::success().misbehaviour(result))) + // }, + ExecuteMsg::UpdateStateOnMisbehaviour(msg_raw) => { + let client_state = ctx.client_state(&client_id)?; + let msg = UpdateStateOnMisbehaviourMsg::try_from(msg_raw)?; + client + .update_state_on_misbehaviour(client_state, msg.client_message) + .map_err(ContractError::from) + .and_then(|cs| { + ctx.store_client_state(client_id, cs)?; + Ok(to_binary(&ContractResult::success())) + }) + }, + ExecuteMsg::UpdateState(msg_raw) => { + let client_state = ctx.client_state(&client_id)?; + let msg = UpdateStateMsg::try_from(msg_raw)?; + let latest_revision_height = client_state.latest_height().revision_height; + helpers::prune_oldest_consensus_state( + ctx, + &client_state, + ctx.host_timestamp().nanoseconds(), + ); + client + .update_state(ctx, client_id.clone(), client_state, msg.client_message) + .map_err(ContractError::from) + .and_then(|(cs, cu)| { + let height = cs.latest_height(); + match cu { + ConsensusUpdateResult::Single(cs) => { + ctx.store_consensus_state(client_id.clone(), height, cs)?; + }, + ConsensusUpdateResult::Batch(css) => + for (height, cs) in css { + ctx.store_consensus_state(client_id.clone(), height, cs)?; + }, + } + if u64::from(cs.0.latest_height) > latest_revision_height { + ctx.store_client_state(client_id, cs)?; + } + Ok(to_binary(&ContractResult::success())) + }) + }, + ExecuteMsg::MigrateClientStore(msg) => helpers::check_substitute_and_update_state(ctx) + .map_err(Into::into) + .and_then(|(cs, cu)| { + let height = cs.latest_height(); + ctx.store_consensus_state_prefixed(height, cu, SUBJECT_PREFIX); + ctx.store_client_state_prefixed(cs, SUBJECT_PREFIX)?; + Ok(to_binary(&ContractResult::success())) + }), + ExecuteMsg::VerifyUpgradeAndUpdateState(msg) => { + let old_client_state = ctx.client_state(&client_id)?; + let msg: VerifyUpgradeAndUpdateStateMsg = + VerifyUpgradeAndUpdateStateMsg::try_from(msg)?; + helpers::verify_upgrade_and_update_state( + ctx, + client_id.clone(), + old_client_state, + msg.upgrade_client_state, + msg.upgrade_consensus_state, + msg.proof_upgrade_client, + msg.proof_upgrade_consensus_state, + ) + .map_err(Into::into) + .and_then(|(cs, cu)| { + let height = cs.latest_height(); + ctx.store_consensus_state(client_id.clone(), height, cu)?; + ctx.store_client_state(client_id, cs)?; + Ok(to_binary(&ContractResult::success())) + }) + }, + }; + Ok(result??) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { + let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid"); + //deps.api.debug("In query"); + match msg { + // QueryMsg::ClientTypeMsg(_) => unimplemented!("ClientTypeMsg"), + // QueryMsg::GetLatestHeightsMsg(_) => unimplemented!("GetLatestHeightsMsg"), + + QueryMsg::ExportMetadata(ExportMetadataMsg {}) => { + let ro_proceeded_state = ReadonlyProcessedStates::new(deps.storage); + to_binary(&QueryResponse::success().genesis_metadata(ro_proceeded_state.get_metadata())) + }, + QueryMsg::Status(StatusMsg {}) => { + let client_state = match get_client_state::(deps) { + Ok(state) => state, + Err(_) => return to_binary(&QueryResponse::success().status("Unknown".to_string())), + }; + + if client_state.frozen_height().is_some() { + return to_binary(&QueryResponse::success().status("Frozen".to_string())); + } + + let height = client_state.latest_height(); + let consensus_state = match get_consensus_state(deps, &client_id, height) { + Ok(state) => state, + Err(_) => return to_binary(&QueryResponse::success().status("Expired".to_string())), + }; + + let last_update = consensus_state.0.timestamp_ns.get(); + let trusting_period = client_state.0.trusting_period_ns; + let now = env.block.time.nanos(); + if last_update + trusting_period < now { + return to_binary(&QueryResponse::success().status("Expired".to_string())); + } + to_binary(&QueryResponse::success().status("Active".to_string())) + }, + QueryMsg::VerifyClientMessage(msg) => { + let ctx = Context::new_ro(deps, env); + let client_state = ctx.client_state(&client_id).map_err(ContractError::from)?; + let client = GuestClient::::default(); + let msg = VerifyClientMessage::try_from(msg)?; + client + .verify_client_message(&ctx, client_id, client_state, msg.client_message) + .map_err(|e| ContractError::Client(e)) + .map(|_| to_binary(&QueryResponse::success()))? + }, + QueryMsg::TimestampAtHeight(_msg) => todo!(), + QueryMsg::CheckForMisbehaviour(msg) => { + let ctx = Context::new_ro(deps, env); + let client_state = ctx.client_state(&client_id).map_err(ContractError::from)?; + let client = GuestClient::::default(); + let msg = CheckForMisbehaviourMsg::try_from(msg)?; + client + .check_for_misbehaviour(&ctx, client_id, client_state, msg.client_message) + .map_err(|e| ContractError::Client(e)) + .map(|result| to_binary(&QueryResponse::success().misbehaviour(result)))? + }, + } +} diff --git a/light-clients/cf-guest-cw/src/crypto.rs b/light-clients/cf-guest-cw/src/crypto.rs new file mode 100644 index 000000000..e2848bb8f --- /dev/null +++ b/light-clients/cf-guest-cw/src/crypto.rs @@ -0,0 +1,117 @@ +use borsh::maybestd::io; + +/// Ed25519 public key (a.k.a. verifying key). +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct PubKey(ed25519_dalek::VerifyingKey); + +impl guestchain::PubKey for PubKey { + type Signature = Signature; + + fn to_vec(&self) -> Vec { + self.0.as_bytes().to_vec() + } + + fn as_bytes<'a>(&'a self) -> alloc::borrow::Cow<'a, [u8]> { + alloc::borrow::Cow::Borrowed(&self.0.as_bytes()[..]) + } + + fn from_bytes(bytes: &[u8]) -> Result { + bytes.try_into().map(Self).map_err(|_| guestchain::BadFormat) + } +} + +impl borsh::BorshSerialize for PubKey { + fn serialize(&self, wr: &mut W) -> io::Result<()> { + wr.write_all(self.0.as_bytes()) + } +} + +impl borsh::BorshDeserialize for PubKey { + fn deserialize_reader(rd: &mut R) -> io::Result { + let mut bytes = ed25519_dalek::pkcs8::PublicKeyBytes([0; 32]); + rd.read_exact(&mut bytes.0[..])?; + ed25519_dalek::VerifyingKey::try_from(bytes) + .map(Self) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "malformed Ed25519 public key")) + } +} + +impl PartialOrd for PubKey { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for PubKey { + fn cmp(&self, rhs: &Self) -> core::cmp::Ordering { + self.0.as_bytes().cmp(rhs.0.as_bytes()) + } +} + +/// Ed25519 signature. +#[derive(Clone, PartialEq, Eq, Debug)] +#[repr(transparent)] +pub struct Signature(ed25519_dalek::Signature); + +impl guestchain::Signature for Signature { + fn to_vec(&self) -> Vec { + self.0.to_vec() + } + + fn as_bytes<'a>(&'a self) -> alloc::borrow::Cow<'a, [u8]> { + self.0.to_vec().into() + } + + fn from_bytes(bytes: &[u8]) -> Result { + ed25519_dalek::Signature::from_slice(bytes) + .map(Self) + .map_err(|_| guestchain::BadFormat) + } +} + +impl borsh::BorshSerialize for Signature { + fn serialize(&self, wr: &mut W) -> io::Result<()> { + wr.write_all(self.0.r_bytes())?; + wr.write_all(self.0.s_bytes())?; + Ok(()) + } +} + +impl borsh::BorshDeserialize for Signature { + fn deserialize_reader(rd: &mut R) -> io::Result { + let mut buf = [0; 64]; + rd.read_exact(&mut buf[..])?; + Ok(Self(ed25519_dalek::Signature::from_bytes(&buf))) + } +} + +impl core::hash::Hash for Signature { + fn hash(&self, hasher: &mut H) { + hasher.write(self.0.r_bytes()); + hasher.write(self.0.s_bytes()); + } +} + +impl PartialOrd for Signature { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for Signature { + fn cmp(&self, rhs: &Self) -> core::cmp::Ordering { + let lhs = (self.0.r_bytes(), self.0.s_bytes()); + let rhs = (rhs.0.r_bytes(), rhs.0.s_bytes()); + lhs.cmp(&rhs) + } +} + +/// Verifier for Ed25519 signatures using ed25519-dalek implementation. +pub(crate) struct Verifier; + +impl guestchain::Verifier for Verifier { + fn verify(&self, message: &[u8], pubkey: &PubKey, signature: &Signature) -> bool { + pubkey.0.verify_strict(message, &signature.0).is_ok() + } +} diff --git a/light-clients/cf-guest-cw/src/error.rs b/light-clients/cf-guest-cw/src/error.rs new file mode 100644 index 000000000..642fbb9b2 --- /dev/null +++ b/light-clients/cf-guest-cw/src/error.rs @@ -0,0 +1,42 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use cosmwasm_std::StdError; +use std::error::Error; + +#[derive(derive_more::From, derive_more::Display, Debug)] +pub enum ContractError { + Std(StdError), + + ProofVerification(cf_guest::proof::VerifyError), + + Client(ibc::core::ics02_client::error::Error), + Path(ibc::core::ics24_host::path::PathError), + Proof(ibc::proofs::ProofError), + Commitment(ibc::core::ics23_commitment::error::Error), + Protobuf(ibc::protobuf::Error), + + Prost(prost::DecodeError), + + Other(String), +} + +impl Error for ContractError {} + +impl From for StdError { + fn from(e: ContractError) -> Self { + StdError::GenericErr { msg: e.to_string() } + } +} diff --git a/light-clients/cf-guest-cw/src/fake_inner.rs b/light-clients/cf-guest-cw/src/fake_inner.rs new file mode 100644 index 000000000..bb3c14b75 --- /dev/null +++ b/light-clients/cf-guest-cw/src/fake_inner.rs @@ -0,0 +1,295 @@ +use cosmwasm_schema::cw_serde; +use ibc::{ + core::{ + ics02_client::{ + client_consensus::ConsensusState, + client_def::{ClientDef, ConsensusUpdateResult}, + client_message::ClientMessage, + client_state::{ClientState, ClientType}, + error::Error, + }, + ics03_connection::connection::ConnectionEnd, + ics04_channel::{ + channel::ChannelEnd, + commitment::{AcknowledgementCommitment, PacketCommitment}, + packet::Sequence, + }, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}, + ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId}, + ics26_routing::context::ReaderContext, + }, + timestamp::Timestamp, + Height, +}; +use ibc_proto::google::protobuf::Any; +use std::{convert::Infallible, time::Duration}; + +#[derive(Eq, Default)] +#[cw_serde] +pub struct FakeInner; + +impl TryFrom for FakeInner { + type Error = Infallible; + + fn try_from(_: Any) -> Result { + Ok(FakeInner) + } +} + +impl ConsensusState for FakeInner { + type Error = Infallible; + + fn root(&self) -> &CommitmentRoot { + unimplemented!() + } + + fn timestamp(&self) -> Timestamp { + unimplemented!() + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + unimplemented!() + } +} + +impl ClientState for FakeInner { + type UpgradeOptions = (); + type ClientDef = FakeInner; + + fn chain_id(&self) -> ChainId { + unimplemented!() + } + + fn client_def(&self) -> Self::ClientDef { + unimplemented!() + } + + fn client_type(&self) -> ClientType { + unimplemented!() + } + + fn latest_height(&self) -> Height { + unimplemented!() + } + + fn frozen_height(&self) -> Option { + unimplemented!() + } + + fn upgrade( + self, + _upgrade_height: Height, + _upgrade_options: Self::UpgradeOptions, + _chain_id: ChainId, + ) -> Self { + unimplemented!() + } + + fn expired(&self, _elapsed: Duration) -> bool { + unimplemented!() + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + unimplemented!() + } +} + +impl ClientMessage for FakeInner { + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + unimplemented!() + } +} + +impl ClientDef for FakeInner { + type ClientMessage = FakeInner; + type ClientState = FakeInner; + type ConsensusState = FakeInner; + + fn verify_client_message( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result<(), Error> { + unimplemented!() + } + + fn update_state( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result<(Self::ClientState, ConsensusUpdateResult), Error> { + unimplemented!() + } + + fn update_state_on_misbehaviour( + &self, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result { + unimplemented!() + } + + fn check_for_misbehaviour( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result { + unimplemented!() + } + + fn verify_upgrade_and_update_state( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _old_client_state: &Self::ClientState, + _upgrade_client_state: &Self::ClientState, + _upgrade_consensus_state: &Self::ConsensusState, + _proof_upgrade_client: Vec, + _proof_upgrade_consensus_state: Vec, + ) -> Result<(Self::ClientState, ConsensusUpdateResult), Error> { + unimplemented!() + } + + fn check_substitute_and_update_state( + &self, + _ctx: &Ctx, + _subject_client_id: ClientId, + _substitute_client_id: ClientId, + _old_client_state: Self::ClientState, + _substitute_client_state: Self::ClientState, + ) -> Result<(Self::ClientState, ConsensusUpdateResult), Error> { + unimplemented!() + } + + fn verify_client_consensus_state( + &self, + _ctx: &Ctx, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _client_id: &ClientId, + _consensus_height: Height, + _expected_consensus_state: &Ctx::AnyConsensusState, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_connection_state( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _connection_id: &ConnectionId, + _expected_connection_end: &ConnectionEnd, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_channel_state( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _expected_channel_end: &ChannelEnd, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_client_full_state( + &self, + _ctx: &Ctx, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _client_id: &ClientId, + _expected_client_state: &Ctx::AnyClientState, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_packet_data( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + _commitment: PacketCommitment, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_packet_acknowledgement( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + _ack: AcknowledgementCommitment, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_next_sequence_recv( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_packet_receipt_absence( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + ) -> Result<(), Error> { + unimplemented!() + } +} diff --git a/light-clients/cf-guest-cw/src/helpers.rs b/light-clients/cf-guest-cw/src/helpers.rs new file mode 100644 index 000000000..a7df00701 --- /dev/null +++ b/light-clients/cf-guest-cw/src/helpers.rs @@ -0,0 +1,229 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::{ + context::Context, + ics23::{ConsensusStates, FakeInner, ProcessedStates}, + msg::SudoMsg as ExecuteMsg, +}; +use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; +use ibc::{ + core::{ + ics02_client::{ + client_state::ClientState as _, context::ClientReader, error::Error as Ics02Error, + height::Height, + }, + ics23_commitment::commitment::CommitmentProofBytes, + ics24_host::identifier::ClientId, + }, + protobuf::Protobuf, +}; +use ibc_proto::google::protobuf::Any; +use prost::Message; + +use cf_guest::{ClientState, ConsensusState}; + +use ics08_wasm::{ + client_state::ClientState as WasmClientState, + consensus_state::ConsensusState as WasmConsensusState, SUBJECT_PREFIX, SUBSTITUTE_PREFIX, +}; + +/// CwTemplateContract is a wrapper around Addr that provides a lot of helpers +/// for working with this. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct CwTemplateContract(pub Addr); + +impl CwTemplateContract { + pub fn addr(&self) -> Addr { + self.0.clone() + } + + pub fn call>(&self, msg: T) -> StdResult { + let msg = to_binary(&msg.into())?; + Ok(WasmMsg::Execute { contract_addr: self.addr().into(), msg, funds: vec![] }.into()) + } +} + +pub fn check_substitute_and_update_state( + ctx: &mut Context, +) -> Result<(ClientState, ConsensusState), Ics02Error> { + let mut subject_client_state = ctx.client_state_prefixed(SUBJECT_PREFIX).map_err(|_| { + Ics02Error::implementation_specific("subject client state not found".to_string()) + })?; + let substitute_client_state = ctx.client_state_prefixed(SUBSTITUTE_PREFIX).map_err(|_| { + Ics02Error::implementation_specific("substitute client state not found".to_string()) + })?; + + if subject_client_state.0.genesis_hash != subject_client_state.0.genesis_hash { + return Err(Ics02Error::implementation_specific("Clients do not match".to_string())) + } + + let height = substitute_client_state.latest_height(); + let substitute_consensus_state = + ctx.consensus_state_prefixed(height, SUBSTITUTE_PREFIX).map_err(|_| { + Ics02Error::implementation_specific("substitute consensus state not found".to_string()) + })?; + + let mut process_states = ProcessedStates::new(ctx.storage_mut()); + let substitute_processed_time = process_states + .get_processed_time(height, &mut SUBSTITUTE_PREFIX.to_vec()) + .unwrap(); + let substitute_processed_height = process_states + .get_processed_height(height, &mut SUBSTITUTE_PREFIX.to_vec()) + .unwrap(); + let substitute_iteration_key = process_states + .get_iteration_key(height, &mut SUBSTITUTE_PREFIX.to_vec()) + .unwrap(); + process_states.set_processed_time( + height, + substitute_processed_time, + &mut SUBJECT_PREFIX.to_vec(), + ); + process_states.set_processed_height( + height, + substitute_processed_height, + &mut SUBJECT_PREFIX.to_vec(), + ); + process_states.set_iteration_key(substitute_iteration_key, &mut SUBJECT_PREFIX.to_vec()); + + subject_client_state.0.latest_height = substitute_client_state.0.latest_height; + subject_client_state.0.trusting_period_ns = substitute_client_state.0.trusting_period_ns; + subject_client_state.0.epoch_commitment = substitute_client_state.0.epoch_commitment; + subject_client_state.0.prev_epoch_commitment = substitute_client_state.0.prev_epoch_commitment; + subject_client_state.0.is_frozen = substitute_client_state.0.is_frozen; + + Ok((subject_client_state, substitute_consensus_state)) +} + +pub fn verify_upgrade_proof( + is_client: bool, + height: u64, + commitment_root: &[u8], + proof: CommitmentProofBytes, + state: Any, +) -> Result<(), Ics02Error> { + use ibc::core::ics24_host::ClientUpgradePath; + let path = if is_client { + ClientUpgradePath::UpgradedClientState(height) + } else { + ClientUpgradePath::UpgradedClientConsensusState(height) + }; + cf_guest::proof::verify_bytes( + &[], + proof.as_bytes(), + commitment_root, + path.into(), + Some(state.encode_to_vec().as_slice()), + ) + .map_err(|err| { + Ics02Error::implementation_specific(format!("upgrade state verification failed: {err}")) + }) +} + +pub fn verify_upgrade_and_update_state( + ctx: &mut Context, + client_id: ClientId, + old_client_state: ClientState, + upgrade_client_state: WasmClientState, + upgrade_consensus_state: WasmConsensusState, + proof_upgrade_client: CommitmentProofBytes, + proof_upgrade_consensus_state: CommitmentProofBytes, +) -> Result<(ClientState, ConsensusState), Ics02Error> { + let latest_height = old_client_state.latest_height(); + if upgrade_client_state.latest_height.lt(&latest_height) { + return Err(Ics02Error::implementation_specific( + "upgrade cs is less than current height".to_string(), + )) + } + + let consensus_state = ctx.consensus_state(&client_id, latest_height)?; + let commitment_root = consensus_state.0.block_hash.as_bytes(); + let latest_height = latest_height.revision_height; + + verify_upgrade_proof( + true, + latest_height, + commitment_root, + proof_upgrade_client, + upgrade_client_state.to_any(), + )?; + + verify_upgrade_proof( + false, + latest_height, + commitment_root, + proof_upgrade_consensus_state, + upgrade_consensus_state.to_any(), + )?; + + let any = Any::decode(&mut upgrade_client_state.data.as_slice()).unwrap(); + let upgrade_client_state_inner = + ClientState::::decode_vec(&any.value).unwrap(); + let new_client_state = old_client_state.upgrade( + upgrade_client_state_inner.latest_height(), + cf_guest::client::UpgradeOptions {}, + upgrade_client_state_inner.chain_id(), + ); + + let any = Any::decode(&mut upgrade_consensus_state.data.as_slice()).unwrap(); + let upgrade_consensus_state_inner = ConsensusState::decode_vec(&any.value).unwrap(); + Ok((new_client_state, upgrade_consensus_state_inner)) +} + +pub fn prune_oldest_consensus_state( + ctx: &mut Context, + client_state: &ClientState, + current_time: u64, +) { + let mut processed_states = ProcessedStates::new(ctx.storage_mut()); + let latest_height = client_state.latest_height(); + if let Some(earliest_height) = processed_states.get_earliest_height(latest_height) { + let processed_time = + processed_states.get_processed_time(earliest_height, &mut Vec::new()).unwrap(); + let elapsed = current_time.saturating_sub(processed_time); + let expired = elapsed > client_state.0.trusting_period_ns; + if expired { + processed_states.remove_states_at_height(earliest_height); + let mut consensus_states = ConsensusStates::new(ctx.storage_mut()); + consensus_states.remove(earliest_height); + } + } +} + +pub fn verify_delay_passed( + ctx: &Context, + height: Height, + delay_period_time: u64, + delay_period_height: u64, +) -> Result<(), Ics02Error> { + let current_timestamp = ctx.host_timestamp(); + let current_height = ctx.host_height(); + + let processed_time = ctx.processed_timestamp(height)?; + let processed_height = ctx.processed_height(height)?; + + ClientState::::verify_delay_passed( + current_timestamp, + current_height, + processed_time, + processed_height, + delay_period_time, + delay_period_height, + ) + .map_err(|e| e.into()) +} diff --git a/light-clients/cf-guest-cw/src/ibc.rs b/light-clients/cf-guest-cw/src/ibc.rs new file mode 100644 index 000000000..26e35f71a --- /dev/null +++ b/light-clients/cf-guest-cw/src/ibc.rs @@ -0,0 +1,20 @@ +//! A helper module which collects IBC types we’re using in a flatter namespace. + +// pub mod wasm { +// pub use ibc_new::clients::wasm_types::{ +// client_state::ClientState, consensus_state::ConsensusState, error::Error, +// }; +// } + +pub use ibc::{ + core::{ + ics02_client::error::Error as ClientError, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes}, + ics24_host::{identifier::ClientId, path}, + }, + protobuf, + timestamp::Timestamp, + Height, +}; + +pub use ibc_proto as proto; diff --git a/light-clients/cf-guest-cw/src/ics23/client_states.rs b/light-clients/cf-guest-cw/src/ics23/client_states.rs new file mode 100644 index 000000000..ec5d91a5d --- /dev/null +++ b/light-clients/cf-guest-cw/src/ics23/client_states.rs @@ -0,0 +1,71 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use cosmwasm_std::Storage; + +/// client_id => client_states +/// trie key path: "clients/{client_id}/clientState" +pub struct ClientStates<'a>(&'a mut dyn Storage); + +impl<'a> ClientStates<'a> { + pub fn new(storage: &'a mut dyn Storage) -> Self { + ClientStates(storage) + } + + pub fn key() -> Vec { + let client_state_path = "clientState".to_string(); + client_state_path.into_bytes() + } + + pub fn get(&self) -> Option> { + ReadonlyClientStates::new(self.0).get() + } + + pub fn get_prefixed(&self, prefix: &[u8]) -> Option> { + ReadonlyClientStates::new(self.0).get_prefixed(prefix) + } + + pub fn insert(&mut self, client_state: Vec) { + self.0.set(&Self::key(), &client_state); + } + + pub fn insert_prefixed(&mut self, client_state: Vec, prefix: &[u8]) { + self.0.set(&[prefix, Self::key().as_slice()].concat(), &client_state); + } + + pub fn contains_key(&self) -> bool { + self.get().is_some() + } +} + +pub struct ReadonlyClientStates<'a>(&'a dyn Storage); + +impl<'a> ReadonlyClientStates<'a> { + pub fn new(storage: &'a dyn Storage) -> Self { + ReadonlyClientStates(storage) + } + + pub fn get(&self) -> Option> { + self.0.get(&ClientStates::key()) + } + + pub fn get_prefixed(&self, prefix: &[u8]) -> Option> { + self.0.get(&[prefix, ClientStates::key().as_slice()].concat()) + } + + pub fn contains_key(&self) -> bool { + self.get().is_some() + } +} diff --git a/light-clients/cf-guest-cw/src/ics23/clients.rs b/light-clients/cf-guest-cw/src/ics23/clients.rs new file mode 100644 index 000000000..968e4be68 --- /dev/null +++ b/light-clients/cf-guest-cw/src/ics23/clients.rs @@ -0,0 +1,60 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use cosmwasm_std::Storage; +use ibc::core::ics24_host::identifier::ClientId; + +/// client_id => client_type +/// trie key path: "clients/{}/clientType" +pub struct Clients<'a>(&'a mut dyn Storage); + +impl<'a> Clients<'a> { + pub fn new(storage: &'a mut dyn Storage) -> Self { + Clients(storage) + } + + pub fn key(_client_id: ClientId) -> Vec { + let client_type_path = "clientType".to_string(); + client_type_path.into_bytes() + } + + pub fn get(&self, client_id: &ClientId) -> Option> { + self.0.get(&Self::key(client_id.clone())) + } + + pub fn insert(&mut self, client_id: ClientId, client_type: Vec) { + self.0.set(&Self::key(client_id), &client_type); + } + + pub fn contains_key(&self, client_id: &ClientId) -> bool { + self.get(client_id).is_some() + } +} + +pub struct ReadonlyClients<'a>(&'a dyn Storage); + +impl<'a> ReadonlyClients<'a> { + pub fn new(storage: &'a dyn Storage) -> Self { + ReadonlyClients(storage) + } + + pub fn get(&self, client_id: &ClientId) -> Option> { + self.0.get(&Clients::key(client_id.clone())) + } + + pub fn contains_key(&self, client_id: &ClientId) -> bool { + self.get(client_id).is_some() + } +} diff --git a/light-clients/cf-guest-cw/src/ics23/consensus_states.rs b/light-clients/cf-guest-cw/src/ics23/consensus_states.rs new file mode 100644 index 000000000..f64ae1b9a --- /dev/null +++ b/light-clients/cf-guest-cw/src/ics23/consensus_states.rs @@ -0,0 +1,392 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::Storage; +use ibc::{ + core::{ + ics02_client::{ + client_consensus::ConsensusState, + client_def::{ClientDef, ConsensusUpdateResult}, + client_message::ClientMessage, + client_state::{ClientState, ClientType}, + error::Error, + }, + ics03_connection::connection::ConnectionEnd, + ics04_channel::{ + channel::ChannelEnd, + commitment::{AcknowledgementCommitment, PacketCommitment}, + packet::Sequence, + }, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}, + ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId}, + ics26_routing::context::ReaderContext, + }, + timestamp::Timestamp, + Height, +}; +use ibc_proto::google::protobuf::Any; +use std::{convert::Infallible, time::Duration}; + +/// client_id, height => consensus_state +/// trie key path: "clients/{client_id}/consensusStates/{height}" +pub struct ConsensusStates<'a>(&'a mut dyn Storage); + +impl<'a> ConsensusStates<'a> { + pub fn new(storage: &'a mut dyn Storage) -> Self { + ConsensusStates(storage) + } + + pub fn consensus_state_client_key() -> Vec { + "consensusStates/".to_string().into_bytes() + } + + pub fn consensus_state_height_key(height: Height) -> Vec { + format!("{height}").into_bytes() + } + + pub fn consensus_state_key(height: Height) -> (Vec, Vec) { + let client_id_key = Self::consensus_state_client_key(); + let height_key = Self::consensus_state_height_key(height); + (client_id_key, height_key) + } + + pub fn get(&self, height: Height) -> Option> { + ReadonlyConsensusStates::new(self.0).get(height) + } + + pub fn get_prefixed(&self, height: Height, prefix: &[u8]) -> Option> { + ReadonlyConsensusStates::new(self.0).get_prefixed(height, prefix) + } + + pub fn insert(&mut self, height: Height, consensus_state: Vec) { + let (consensus_state_key_1, consensus_state_key_2) = Self::consensus_state_key(height); + let full_key = + [consensus_state_key_1.as_slice(), consensus_state_key_2.as_slice()].concat(); + + self.0.set(&full_key, &consensus_state); + } + + pub fn insert_prefixed(&mut self, height: Height, consensus_state: Vec, prefix: &[u8]) { + let (consensus_state_key_1, consensus_state_key_2) = Self::consensus_state_key(height); + let full_key = + [prefix, consensus_state_key_1.as_slice(), consensus_state_key_2.as_slice()].concat(); + + self.0.set(&full_key, &consensus_state); + } + + pub fn remove(&mut self, height: Height) { + let (consensus_state_key_1, consensus_state_key_2) = Self::consensus_state_key(height); + let full_key = + [consensus_state_key_1.as_slice(), consensus_state_key_2.as_slice()].concat(); + self.0.remove(&full_key); + } +} + +/// client_id, height => consensus_state +/// trie key path: "clients/{client_id}/consensusStates/{height}" +pub struct ReadonlyConsensusStates<'a>(&'a dyn Storage); + +impl<'a> ReadonlyConsensusStates<'a> { + pub fn new(storage: &'a dyn Storage) -> Self { + ReadonlyConsensusStates(storage) + } + + pub fn get(&self, height: Height) -> Option> { + let (consensus_state_key_1, consensus_state_key_2) = + ConsensusStates::consensus_state_key(height); + let full_key = + [consensus_state_key_1.as_slice(), consensus_state_key_2.as_slice()].concat(); + self.0.get(&full_key) + } + + pub fn get_prefixed(&self, height: Height, prefix: &[u8]) -> Option> { + let (consensus_state_key_1, consensus_state_key_2) = + ConsensusStates::consensus_state_key(height); + let full_key = + [prefix, consensus_state_key_1.as_slice(), consensus_state_key_2.as_slice()].concat(); + self.0.get(&full_key) + } +} + +#[derive(Eq, Default)] +#[cw_serde] +pub struct FakeInner; + +impl TryFrom for FakeInner { + type Error = Infallible; + + fn try_from(_: Any) -> Result { + Ok(FakeInner) + } +} + +impl ConsensusState for FakeInner { + type Error = Infallible; + + fn root(&self) -> &CommitmentRoot { + unimplemented!() + } + + fn timestamp(&self) -> Timestamp { + unimplemented!() + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + unimplemented!() + } +} + +impl ClientState for FakeInner { + type UpgradeOptions = (); + type ClientDef = FakeInner; + + fn chain_id(&self) -> ChainId { + unimplemented!() + } + + fn client_def(&self) -> Self::ClientDef { + unimplemented!() + } + + fn client_type(&self) -> ClientType { + unimplemented!() + } + + fn latest_height(&self) -> Height { + unimplemented!() + } + + fn frozen_height(&self) -> Option { + unimplemented!() + } + + fn upgrade( + self, + _upgrade_height: Height, + _upgrade_options: Self::UpgradeOptions, + _chain_id: ChainId, + ) -> Self { + unimplemented!() + } + + fn expired(&self, _elapsed: Duration) -> bool { + unimplemented!() + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + unimplemented!() + } +} + +impl ClientMessage for FakeInner { + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + unimplemented!() + } +} + +impl ClientDef for FakeInner { + type ClientMessage = FakeInner; + type ClientState = FakeInner; + type ConsensusState = FakeInner; + + fn verify_client_message( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result<(), Error> { + unimplemented!() + } + + fn update_state( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result<(Self::ClientState, ConsensusUpdateResult), Error> { + unimplemented!() + } + + fn update_state_on_misbehaviour( + &self, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result { + unimplemented!() + } + + fn check_for_misbehaviour( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result { + unimplemented!() + } + + fn verify_upgrade_and_update_state( + &self, + _ctx: &Ctx, + _client_id: ClientId, + _old_client_state: &Self::ClientState, + _upgrade_client_state: &Self::ClientState, + _upgrade_consensus_state: &Self::ConsensusState, + _proof_upgrade_client: Vec, + _proof_upgrade_consensus_state: Vec, + ) -> Result<(Self::ClientState, ConsensusUpdateResult), Error> { + unimplemented!() + } + + fn check_substitute_and_update_state( + &self, + _ctx: &Ctx, + _subject_client_id: ClientId, + _substitute_client_id: ClientId, + _old_client_state: Self::ClientState, + _substitute_client_state: Self::ClientState, + ) -> Result<(Self::ClientState, ConsensusUpdateResult), Error> { + unimplemented!() + } + + fn verify_client_consensus_state( + &self, + _ctx: &Ctx, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _client_id: &ClientId, + _consensus_height: Height, + _expected_consensus_state: &Ctx::AnyConsensusState, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_connection_state( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _connection_id: &ConnectionId, + _expected_connection_end: &ConnectionEnd, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_channel_state( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _expected_channel_end: &ChannelEnd, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_client_full_state( + &self, + _ctx: &Ctx, + _client_state: &Self::ClientState, + _height: Height, + _prefix: &CommitmentPrefix, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _client_id: &ClientId, + _expected_client_state: &Ctx::AnyClientState, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_packet_data( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + _commitment: PacketCommitment, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_packet_acknowledgement( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + _ack: AcknowledgementCommitment, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_next_sequence_recv( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + ) -> Result<(), Error> { + unimplemented!() + } + + fn verify_packet_receipt_absence( + &self, + _ctx: &Ctx, + _client_id: &ClientId, + _client_state: &Self::ClientState, + _height: Height, + _connection_end: &ConnectionEnd, + _proof: &CommitmentProofBytes, + _root: &CommitmentRoot, + _port_id: &PortId, + _channel_id: &ChannelId, + _sequence: Sequence, + ) -> Result<(), Error> { + unimplemented!() + } +} diff --git a/light-clients/cf-guest-cw/src/ics23/mod.rs b/light-clients/cf-guest-cw/src/ics23/mod.rs new file mode 100644 index 000000000..62c3bf31e --- /dev/null +++ b/light-clients/cf-guest-cw/src/ics23/mod.rs @@ -0,0 +1,26 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +mod client_states; +mod clients; +mod consensus_states; +mod processed_states; + +pub use self::{ + client_states::{ClientStates, ReadonlyClientStates}, + clients::{Clients, ReadonlyClients}, + consensus_states::{ConsensusStates, FakeInner, ReadonlyConsensusStates}, + processed_states::{ProcessedStates, ReadonlyProcessedStates}, +}; diff --git a/light-clients/cf-guest-cw/src/ics23/processed_states.rs b/light-clients/cf-guest-cw/src/ics23/processed_states.rs new file mode 100644 index 000000000..0474c4925 --- /dev/null +++ b/light-clients/cf-guest-cw/src/ics23/processed_states.rs @@ -0,0 +1,209 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use cosmwasm_std::{Order, Storage}; +use ibc::Height; + +use crate::msg::GenesisMetadata; + +pub struct ProcessedStates<'a>(&'a mut dyn Storage); + +impl<'a> ProcessedStates<'a> { + pub fn new(storage: &'a mut dyn Storage) -> Self { + ProcessedStates(storage) + } + + pub fn processed_time_key(height: Height, prefix: &mut Vec) -> Vec { + prefix.append(&mut "consensusStates/".to_string().into_bytes()); + prefix.append(&mut format!("{height}").into_bytes()); + prefix.append(&mut "/processedTime".to_string().into_bytes()); + prefix.clone() + } + + pub fn processed_height_key(height: Height, prefix: &mut Vec) -> Vec { + prefix.append(&mut "consensusStates/".to_string().into_bytes()); + prefix.append(&mut format!("{height}").into_bytes()); + prefix.append(&mut "/processedHeight".to_string().into_bytes()); + prefix.clone() + } + + pub fn iteration_key(height: Height, prefix: &mut Vec) -> Vec { + prefix.append(&mut "iterateConsensusStates".to_string().into_bytes()); + prefix.append(&mut height.revision_number.to_be_bytes().to_vec()); + prefix.append(&mut height.revision_height.to_be_bytes().to_vec()); + prefix.clone() + } + + pub fn get_processed_time(&self, height: Height, prefix: &mut Vec) -> Option { + let full_key = Self::processed_time_key(height, prefix); + self.0 + .get(&full_key) + .map(|timestamp| u64::from_be_bytes(timestamp.try_into().unwrap())) + } + + pub fn set_processed_time(&mut self, height: Height, timestamp: u64, prefix: &mut Vec) { + let full_key = Self::processed_time_key(height, prefix); + let time_vec: [u8; 8] = timestamp.to_be_bytes(); + self.0.set(&full_key, &time_vec); + } + + pub fn get_processed_height(&self, height: Height, prefix: &mut Vec) -> Option { + let full_key = Self::processed_height_key(height, prefix); + self.0 + .get(&full_key) + .map(|height| u64::from_be_bytes(height.try_into().unwrap())) + } + + pub fn set_processed_height( + &mut self, + height: Height, + processed_height: u64, + prefix: &mut Vec, + ) { + let full_key = Self::processed_height_key(height, prefix); + let height_vec: [u8; 8] = processed_height.to_be_bytes(); + self.0.set(&full_key, &height_vec); + } + + pub fn get_iteration_key(&self, height: Height, prefix: &mut Vec) -> Option { + let full_key = Self::iteration_key(height, prefix); + match self.0.get(&full_key) { + Some(height) => match std::str::from_utf8(height.as_slice()) { + Ok(height_str) => Some(Height::try_from(height_str).unwrap()), + Err(_) => None, + }, + None => None, + } + } + + pub fn set_iteration_key(&mut self, height: Height, prefix: &mut Vec) { + let full_key = Self::iteration_key(height, prefix); + let height_vec = format!("{height}").into_bytes(); + self.0.set(&full_key, &height_vec); + } + + pub fn get_earliest_height(&mut self, current_height: Height) -> Option { + let full_key = Self::iteration_key(current_height, &mut Vec::new()); + let start_key = "iterateConsensusStates".to_string().into_bytes(); + let mut iterator = self.0.range(Some(&start_key), Some(&full_key), Order::Ascending); + match iterator.next() { + Some((_, height)) => match std::str::from_utf8(height.as_slice()) { + Ok(height_str) => Some(Height::try_from(height_str).unwrap()), + Err(_) => None, + }, + None => None, + } + } + + pub fn remove_states_at_height(&mut self, height: Height) { + let processed_time_key = Self::processed_time_key(height, &mut Vec::new()); + let processed_height_key = Self::processed_height_key(height, &mut Vec::new()); + let iteration_key = Self::iteration_key(height, &mut Vec::new()); + + self.0.remove(&processed_time_key); + self.0.remove(&processed_height_key); + self.0.remove(&iteration_key) + } +} + +pub struct ReadonlyProcessedStates<'a>(&'a dyn Storage); + +impl<'a> ReadonlyProcessedStates<'a> { + pub fn new(storage: &'a dyn Storage) -> Self { + ReadonlyProcessedStates(storage) + } + + pub fn get_processed_time(&self, height: Height, prefix: &mut Vec) -> Option { + let full_key = ProcessedStates::processed_time_key(height, prefix); + self.0 + .get(&full_key) + .map(|timestamp| u64::from_be_bytes(timestamp.try_into().unwrap())) + } + + pub fn get_processed_height(&self, height: Height, prefix: &mut Vec) -> Option { + let full_key = ProcessedStates::processed_height_key(height, prefix); + self.0 + .get(&full_key) + .map(|height| u64::from_be_bytes(height.try_into().unwrap())) + } + + pub fn get_iteration_key(&self, height: Height, prefix: &mut Vec) -> Option { + let full_key = ProcessedStates::iteration_key(height, prefix); + match self.0.get(&full_key) { + Some(height) => match std::str::from_utf8(height.as_slice()) { + Ok(height_str) => Some(Height::try_from(height_str).unwrap()), + Err(_) => None, + }, + None => None, + } + } + + pub fn get_next_height(&self, height: Height) -> Option { + let full_key = ProcessedStates::iteration_key(height, &mut Vec::new()); + let mut iterator = self.0.range(Some(&full_key), None, Order::Ascending); + match iterator.next() { + Some((_, height)) => match std::str::from_utf8(height.as_slice()) { + Ok(height_str) => Some(Height::try_from(height_str).unwrap()), + Err(_) => None, + }, + None => None, + } + } + + pub fn get_prev_height(&self, height: Height) -> Option { + let full_key = ProcessedStates::iteration_key(height, &mut Vec::new()); + let mut iterator = self.0.range(None, Some(&full_key), Order::Descending); + match iterator.next() { + Some((_, height)) => match std::str::from_utf8(height.as_slice()) { + Ok(height_str) => Some(Height::try_from(height_str).unwrap()), + Err(_) => None, + }, + None => None, + } + } + + pub fn get_metadata(&self) -> Option> { + let mut gm: Vec = Vec::::new(); + + let start_key = "iterateConsensusStates".to_string().into_bytes(); + let iterator = self.0.range(Some(&start_key), None, Order::Ascending); + for (_, height) in iterator { + match std::str::from_utf8(height.as_slice()) { + Ok(height_str) => { + let height = Height::try_from(height_str).unwrap(); + let processed_height_key = + ProcessedStates::processed_height_key(height, &mut Vec::new()); + gm.push(GenesisMetadata { + key: processed_height_key.clone(), + value: self.0.get(&processed_height_key).unwrap(), + }); + let processed_time_key = + ProcessedStates::processed_time_key(height, &mut Vec::new()); + gm.push(GenesisMetadata { + key: processed_time_key.clone(), + value: self.0.get(&processed_time_key).unwrap(), + }); + }, + Err(_) => break, + } + } + + let iterator = self.0.range(Some(&start_key), None, Order::Ascending); + for (key, height) in iterator { + gm.push(GenesisMetadata { key, value: height }); + } + Some(gm) + } +} diff --git a/light-clients/cf-guest-cw/src/lib.rs b/light-clients/cf-guest-cw/src/lib.rs new file mode 100644 index 000000000..25a86674c --- /dev/null +++ b/light-clients/cf-guest-cw/src/lib.rs @@ -0,0 +1,38 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +extern crate alloc; +extern crate core; + +mod channel; +mod client; +mod connection; +mod context; +pub mod contract; +pub mod crypto; +mod error; +pub mod helpers; +pub mod ics23; +mod macros; +pub mod msg; +pub mod state; +mod types; + +pub use crate::error::ContractError; + +pub const CLIENT_STATE: &[u8] = b"client_state"; +pub const STORAGE_PREFIX: &[u8] = b""; + +pub type Bytes = Vec; diff --git a/light-clients/cf-guest-cw/src/macros.rs b/light-clients/cf-guest-cw/src/macros.rs new file mode 100644 index 000000000..d203860a4 --- /dev/null +++ b/light-clients/cf-guest-cw/src/macros.rs @@ -0,0 +1,21 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#[macro_export] +macro_rules! log { + ($self:expr, $($tt:tt)*) => { + $self.log(&format!($($tt)*)) + }; +} diff --git a/light-clients/cf-guest-cw/src/migrate.rs b/light-clients/cf-guest-cw/src/migrate.rs new file mode 100644 index 000000000..1fb5bdb88 --- /dev/null +++ b/light-clients/cf-guest-cw/src/migrate.rs @@ -0,0 +1,7 @@ +#[cfg(feature = "cosmwasm")] +use cosmwasm_schema::cw_serde; + +#[cfg_attr(feature = "cosmwasm", cw_serde)] +#[cfg_attr(not(feature = "cosmwasm"), derive(Clone, Debug, PartialEq, serde::Deserialize))] +#[derive(Eq)] +pub struct MigrateMsg {} \ No newline at end of file diff --git a/light-clients/cf-guest-cw/src/msg.rs b/light-clients/cf-guest-cw/src/msg.rs new file mode 100644 index 000000000..f122d7d9b --- /dev/null +++ b/light-clients/cf-guest-cw/src/msg.rs @@ -0,0 +1,486 @@ +// // Copyright (C) 2022 ComposableFi. +// // SPDX-License-Identifier: Apache-2.0 + +// // Licensed under the Apache License, Version 2.0 (the "License"); +// // you may not use this file except in compliance with the License. +// // You may obtain a copy of the License at +// // +// // http://www.apache.org/licenses/LICENSE-2.0 +// // +// // Unless required by applicable law or agreed to in writing, software +// // distributed under the License is distributed on an "AS IS" BASIS, +// // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// // See the License for the specific language governing permissions and +// // limitations under the License. + +use crate::{ics23::FakeInner, Bytes, ContractError}; +use core::str::FromStr; +use cosmwasm_schema::cw_serde; +use ibc::{ + core::{ + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes}, + ics24_host::Path, + }, + protobuf::Protobuf, + Height, +}; +use ibc_proto::{google::protobuf::Any, ibc::core::client::v1::Height as HeightRaw}; + +use cf_guest::{ClientMessage, ClientState}; + +use ics08_wasm::{ + client_message::ClientMessage as WasmHeader, client_state::ClientState as WasmClientState, + consensus_state::ConsensusState as WasmConsensusState, +}; +use prost::Message; +use serde::{Deserializer, Serializer}; + +struct Base64; + +impl Base64 { + pub fn serialize(v: &[u8], serializer: S) -> Result { + ibc_proto::base64::serialize(v, serializer) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { + ibc_proto::base64::deserialize(deserializer) + } +} + +#[cw_serde] +pub struct GenesisMetadata { + pub key: Vec, + pub value: Vec, +} + +#[cw_serde] +pub struct QueryResponse { + pub is_valid: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub genesis_metadata: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub found_misbehaviour: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub timestamp: Option, +} + +impl QueryResponse { + pub fn success() -> Self { + Self { + is_valid: true, + status: None, + genesis_metadata: None, + found_misbehaviour: None, + timestamp: None, + } + } + + pub fn status(mut self, status: String) -> Self { + self.status = Some(status); + self + } + + pub fn genesis_metadata(mut self, genesis_metadata: Option>) -> Self { + self.genesis_metadata = genesis_metadata; + self + } + + pub fn misbehaviour(mut self, found_misbehavior: bool) -> Self { + self.found_misbehaviour = Some(found_misbehavior); + self + } + + pub fn timestamp(mut self, timestamp: u64) -> Self { + self.timestamp = Some(timestamp); + self + } +} + +#[cw_serde] +pub struct ContractResult { + #[serde(skip_serializing_if = "Option::is_none")] + pub heights: Option>, +} + +impl ContractResult { + pub fn success() -> Self { + Self { heights: None } + } + + pub fn heights(mut self, heights: Vec) -> Self { + self.heights = Some(heights); + self + } +} + +#[cw_serde] +pub enum SudoMsg { + MigrateClientStore(MigrateClientStoreMsg), + UpdateStateOnMisbehaviour(UpdateStateOnMisbehaviourMsgRaw), + UpdateState(UpdateStateMsgRawSdk50), + VerifyMembership(VerifyMembershipMsgRaw), + VerifyNonMembership(VerifyNonMembershipMsgRaw), + VerifyUpgradeAndUpdateState(VerifyUpgradeAndUpdateStateMsgRaw), +} + +#[cw_serde] +pub enum QueryMsg { + CheckForMisbehaviour(CheckForMisbehaviourMsgRaw2), + // ClientTypeMsg(ClientTypeMsg), + // GetLatestHeightsMsg(GetLatestHeightsMsg), + ExportMetadata(ExportMetadataMsg), + Status(StatusMsg), + TimestampAtHeight(TimestampAtHeightMsg), + VerifyClientMessage(VerifyClientMessageRaw2), +} + +#[cw_serde] +pub struct TimestampAtHeightMsg { + pub height: Height, +} + +#[cw_serde] +pub struct ClientTypeMsg {} + +#[cw_serde] +pub struct GetLatestHeightsMsg {} + +#[cw_serde] +pub struct StatusMsg {} + +#[cw_serde] +pub struct ExportMetadataMsg {} + +#[cw_serde] +pub struct MerklePath { + pub key_path: Vec, +} + +#[cw_serde] +pub struct VerifyMembershipMsgRaw { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof: Bytes, + pub path: MerklePath, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub value: Bytes, + pub height: HeightRaw, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +#[derive(Debug)] +pub struct VerifyMembershipMsg { + pub prefix: CommitmentPrefix, + pub proof: CommitmentProofBytes, + pub path: Path, + pub value: Vec, + pub height: Height, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +impl TryFrom for VerifyMembershipMsg { + type Error = ContractError; + + fn try_from(mut raw: VerifyMembershipMsgRaw) -> Result { + let proof = CommitmentProofBytes::try_from(raw.proof)?; + let prefix = raw.path.key_path.remove(0).into_bytes(); + let path_str = raw.path.key_path.join(""); + let path = Path::from_str(&path_str)?; + let height = Height::from(raw.height); + Ok(Self { + proof, + path, + value: raw.value, + height, + prefix: CommitmentPrefix::try_from(prefix)?, + delay_block_period: raw.delay_block_period, + delay_time_period: raw.delay_time_period, + }) + } +} + +#[cw_serde] +pub struct MigrateClientStoreMsg {} + +#[cw_serde] +pub struct VerifyNonMembershipMsgRaw { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof: Bytes, + pub path: MerklePath, + pub height: HeightRaw, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +pub struct VerifyNonMembershipMsg { + pub prefix: CommitmentPrefix, + pub proof: CommitmentProofBytes, + pub path: Path, + pub height: Height, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +#[cw_serde] +pub struct VerifyClientMessageRaw2 { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub client_message: Bytes, +} + +impl TryFrom for VerifyNonMembershipMsg { + type Error = ContractError; + + fn try_from(mut raw: VerifyNonMembershipMsgRaw) -> Result { + let proof = CommitmentProofBytes::try_from(raw.proof)?; + let prefix = raw.path.key_path.remove(0).into_bytes(); + let path_str = raw.path.key_path.join(""); + let path = Path::from_str(&path_str)?; + let height = Height::from(raw.height); + Ok(Self { + proof, + path, + height, + prefix: CommitmentPrefix::try_from(prefix)?, + delay_block_period: raw.delay_block_period, + delay_time_period: raw.delay_time_period, + }) + } +} + +impl TryFrom for VerifyClientMessage { + type Error = ContractError; + + fn try_from(raw: VerifyClientMessageRaw2) -> Result { + let client_message = Self::decode_client_message_raw(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct WasmMisbehaviour { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub data: Bytes, +} + +#[cw_serde] +pub enum ClientMessageRaw { + Header(WasmHeader), + Misbehaviour(WasmMisbehaviour), +} + +#[cw_serde] +pub struct VerifyClientMessageRaw { + pub client_message: ClientMessageRaw, +} + +pub struct VerifyClientMessage { + pub client_message: ClientMessage, +} + +impl TryFrom for VerifyClientMessage { + type Error = ContractError; + + fn try_from(raw: VerifyClientMessageRaw) -> Result { + let client_message = Self::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +impl VerifyClientMessage { + fn decode_client_message( + raw: ClientMessageRaw, + ) -> Result, ContractError> { + let client_message = match raw { + ClientMessageRaw::Header(header) => { + let any = Any::decode(&mut header.data.as_slice())?; + ClientMessage::decode_vec(&any.value)?.into() + }, + ClientMessageRaw::Misbehaviour(misbehaviour) => { + let any = Any::decode(&mut misbehaviour.data.as_slice())?; + ClientMessage::decode_vec(&any.value)?.into() + }, + }; + Ok(client_message) + } + fn decode_client_message_raw( + raw: Bytes, + ) -> Result, ContractError> { + let any = Any::decode(&mut raw.as_slice())?; + let client_message = cf_guest::ClientMessage::decode_vec(&any.value)?; + // let client_message = match &*any.type_url { + // cf_guest::proto::Header::IBC_TYPE_URL => + // ClientMessage::Header(Header::decode_vec(&any.value)?), + // cf_guest::proto::Misbehaviour::IBC_TYPE_URL => { + // ClientMessage::Misbehaviour(Misbehaviour::decode_vec(&any.value)?) + // }, + // _ => return Err(ContractError::Client("unknown client message type".to_string())), + // }; + Ok(client_message) + } +} + +#[cw_serde] +pub struct CheckForMisbehaviourMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct CheckForMisbehaviourMsg { + pub client_message: ClientMessage, +} + +#[cw_serde] +pub struct CheckForMisbehaviourMsgRaw2 { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub client_message: Bytes, +} + +impl TryFrom for CheckForMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: CheckForMisbehaviourMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +impl TryFrom for CheckForMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: CheckForMisbehaviourMsgRaw2) -> Result { + let client_message = VerifyClientMessage::decode_client_message_raw(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct UpdateStateOnMisbehaviourMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct UpdateStateOnMisbehaviourMsg { + pub client_message: ClientMessage, +} + +#[cw_serde] +pub struct UpdateStateMsgRawSdk50 { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub client_message: Bytes, +} + +impl TryFrom for UpdateStateOnMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateOnMisbehaviourMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct UpdateStateMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct UpdateStateMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for UpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +impl TryFrom for UpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateMsgRawSdk50) -> Result { + let client_message = VerifyClientMessage::decode_client_message_raw(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct CheckSubstituteAndUpdateStateMsg {} + +#[cw_serde] +pub struct VerifyUpgradeAndUpdateStateMsgRaw { + pub upgrade_client_state: WasmClientState, + pub upgrade_consensus_state: WasmConsensusState, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof_upgrade_client: Bytes, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof_upgrade_consensus_state: Bytes, +} + +pub struct VerifyUpgradeAndUpdateStateMsg { + pub upgrade_client_state: WasmClientState, + pub upgrade_consensus_state: WasmConsensusState, + pub proof_upgrade_client: CommitmentProofBytes, + pub proof_upgrade_consensus_state: CommitmentProofBytes, +} + +impl TryFrom for VerifyUpgradeAndUpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: VerifyUpgradeAndUpdateStateMsgRaw) -> Result { + let any = Any::decode(&mut raw.upgrade_client_state.data.as_slice())?; + let upgrade_client_state: ClientState = + ClientState::decode_vec(&any.value)?; + if upgrade_client_state.0.is_frozen { + return Err(ContractError::Other("Upgrade client state not zeroed".into())); + } + + Ok(VerifyUpgradeAndUpdateStateMsg { + upgrade_client_state: raw.upgrade_client_state, + upgrade_consensus_state: raw.upgrade_consensus_state, + proof_upgrade_client: CommitmentProofBytes::try_from(raw.proof_upgrade_client)?, + proof_upgrade_consensus_state: CommitmentProofBytes::try_from( + raw.proof_upgrade_consensus_state, + )?, + }) + } +} + +#[test] +fn testing() { + let mut x: Vec = vec![ + 10, 36, 47, 108, 105, 103, 104, 116, 99, 108, 105, 101, 110, 116, 115, 46, 103, 117, 101, + 115, 116, 46, 118, 49, 46, 67, 108, 105, 101, 110, 116, 77, 101, 115, 115, 97, 103, 101, + 18, 173, 2, 10, 170, 2, 10, 32, 245, 46, 29, 47, 245, 89, 230, 120, 70, 62, 107, 19, 173, + 50, 168, 129, 194, 176, 205, 246, 105, 25, 104, 215, 11, 180, 151, 90, 231, 176, 168, 17, + 18, 122, 0, 120, 76, 22, 77, 119, 10, 26, 8, 44, 224, 43, 117, 132, 119, 163, 69, 136, 251, + 30, 49, 228, 55, 5, 23, 15, 218, 35, 78, 24, 246, 66, 89, 154, 5, 0, 0, 0, 0, 0, 0, 36, + 105, 0, 0, 0, 0, 0, 0, 0, 230, 100, 238, 244, 29, 201, 23, 181, 56, 107, 15, 133, 89, 139, + 8, 120, 213, 21, 182, 7, 43, 185, 89, 104, 167, 149, 127, 236, 243, 165, 6, 89, 227, 23, + 221, 176, 228, 218, 142, 245, 46, 29, 47, 245, 89, 230, 120, 70, 62, 107, 19, 173, 50, 168, + 129, 194, 176, 205, 246, 105, 25, 104, 215, 11, 180, 151, 90, 231, 176, 168, 17, 0, 26, 70, + 0, 1, 0, 0, 0, 0, 12, 8, 4, 81, 129, 165, 153, 230, 192, 225, 51, 119, 216, 14, 69, 225, + 73, 7, 204, 144, 39, 213, 91, 255, 136, 38, 95, 131, 197, 4, 101, 186, 208, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 66, 18, + 64, 243, 241, 195, 11, 26, 46, 157, 148, 16, 26, 191, 59, 144, 193, 172, 154, 201, 88, 35, + 219, 229, 111, 161, 138, 21, 85, 17, 152, 66, 128, 155, 181, 214, 186, 126, 224, 5, 147, + 19, 158, 82, 136, 28, 115, 226, 14, 135, 3, 104, 51, 240, 198, 75, 3, 198, 72, 118, 214, + 187, 160, 75, 118, 80, 5, + ]; + let any = Any::decode(&mut x.as_slice()).unwrap(); + println!("{:?}", any); + let header: cf_guest::ClientMessage = + ClientMessage::decode_vec(&any.value).unwrap(); + println!("{:?}", header); +} diff --git a/light-clients/cf-guest-cw/src/state.rs b/light-clients/cf-guest-cw/src/state.rs new file mode 100644 index 000000000..aaec0c6c2 --- /dev/null +++ b/light-clients/cf-guest-cw/src/state.rs @@ -0,0 +1,86 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::ics23::FakeInner; +use cf_guest::{ClientState, ConsensusState}; +use cosmwasm_std::Deps; +use guestchain::PubKey; +use ibc::{ + core::{ics02_client::error::Error, ics24_host::identifier::ClientId}, + protobuf::Protobuf, + Height, +}; +use ibc_proto::google::protobuf::Any; +use prost::Message; + +/// Retrieves raw bytes from storage and deserializes them into [`ClientState`] +pub fn get_client_state(deps: Deps) -> Result, Error> { + deps.storage + .get(&"clientState".to_string().into_bytes()) + .ok_or_else(|| Error::unknown_client_state_type("08-wasm-0".to_string())) + .and_then(|client_state| deserialize_client_state(client_state, deps)) +} + +fn deserialize_client_state( + client_state: Vec, + _deps: Deps, +) -> Result, Error> { + let any = Any::decode(&*client_state).map_err(Error::decode)?; + + let wasm_state = + ics08_wasm::client_state::ClientState::::decode_vec( + &any.value, + ) + .map_err(|e| { + Error::implementation_specific(format!( + "[client_state]: error decoding client state bytes to WasmClientState {e}" + )) + })?; + let any = Any::decode(&*wasm_state.data).map_err(Error::decode)?; + let state = + ClientState::::decode_vec(&any.value).map_err(Error::invalid_any_client_state)?; + Ok(state) +} + +pub fn get_consensus_state( + deps: Deps, + client_id: &ClientId, + height: Height, +) -> Result { + deps.storage + .get(&get_consensus_state_key(height)) + .ok_or_else(|| Error::consensus_state_not_found(client_id.clone(), height)) + .and_then(deserialize_consensus_state) +} + +fn deserialize_consensus_state(consensus_state: Vec) -> Result { + let any = Any::decode(&*consensus_state).map_err(Error::decode)?; + let wasm_consensus_state = + ics08_wasm::consensus_state::ConsensusState::::decode_vec(&any.value).map_err( + |e| { + Error::implementation_specific(format!( + "[consensus_state]: error decoding consensus state bytes to WasmConsensusState {e}" + )) + }, + )?; + let any = Any::decode(&*wasm_consensus_state.data).map_err(Error::decode)?; + let consensus = + ConsensusState::decode_vec(&any.value).map_err(Error::invalid_any_consensus_state)?; + Ok(consensus) +} + +pub fn get_consensus_state_key(height: Height) -> Vec { + ["consensusStates/".to_string().into_bytes(), format!("{height}").into_bytes()].concat() +} diff --git a/light-clients/cf-guest-cw/src/types.rs b/light-clients/cf-guest-cw/src/types.rs new file mode 100644 index 000000000..2fcdd0c69 --- /dev/null +++ b/light-clients/cf-guest-cw/src/types.rs @@ -0,0 +1,32 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, PartialEq)] +pub struct Height { + /// Previously known as "epoch" + #[serde(default)] + pub revision_number: u64, + /// The height of a block + pub revision_height: u64, +} + +impl From for ibc::Height { + fn from(value: Height) -> Self { + Self { revision_number: value.revision_number, revision_height: value.revision_height } + } +} diff --git a/light-clients/cf-guest/Cargo.toml b/light-clients/cf-guest/Cargo.toml new file mode 100644 index 000000000..5d1c14fd3 --- /dev/null +++ b/light-clients/cf-guest/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "cf-guest" +authors = ["Michal Nazarewicz "] +version = "0.0.1" +edition = "2021" + +[dependencies] +borsh = "0.10" +bytemuck = { version = "1.14", default-features = false, features = ["must_cast"]} +derive_more = { version = "0.99", features = ["from"], default-features = false } +prost = { version = "0.11" ,features = ["prost-derive"], default-features = false } +prost-12 = { package = "prost", version = "0.12", default-features = false } +ed25519-consensus = { version = "2", default-features = false } +serde = { version = "1.0", default-features = false, features = ["derive"] } + +# New IBC +ibc-core-client-context = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-client-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-handler-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-core-host-types = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } +ibc-primitives = { git = "https://github.com/mina86/ibc-rs", rev = "f07276383091f75b7ee8bff6fd434f8214ac5054", default-features = false } + +# Old IBC +ibc = { path = "../../ibc/modules", default-features = false } +ibc-proto = { path = "../../ibc/proto", default-features = false } +ibc-derive = { path = "../../ibc/derive", default-features = false } + +tendermint-proto = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false } + +guestchain = { path = "../../../emulated-light-client/common/guestchain", default-features = false } +lib = { path = "../../../emulated-light-client/common/lib", features = ["borsh"], default-features = false } +trie-ids = { path = "../../../emulated-light-client/common/trie-ids", default-features = false } +sealable-trie = { path = "../../../emulated-light-client/common/sealable-trie", features = ["borsh"], default-features = false } +stdx = { path = "../../../emulated-light-client/common/stdx", default-features = false } +cf-guest-upstream = { package = "cf-guest", path = "../../../emulated-light-client/common/cf-guest", default-features = false } + +[build-dependencies] +prost-build = { version = "0.11", default-features = false } + +[dev-dependencies] +insta = { version = "1.34.0" } +rand = { version = "0.8.5" } + +guestchain = { path = "../../../emulated-light-client/common/guestchain", default-features = false, features = ["test_utils"] } +lib = { path = "../../../emulated-light-client/common/lib", default-features = false, features = ["test_utils"] } +memory = { path = "../../../emulated-light-client/common/memory", default-features = false, features = ["test_utils"] } + +[features] +std = [] \ No newline at end of file diff --git a/light-clients/cf-guest/src/client.rs b/light-clients/cf-guest/src/client.rs new file mode 100644 index 000000000..6b3a6e35e --- /dev/null +++ b/light-clients/cf-guest/src/client.rs @@ -0,0 +1,184 @@ +use alloc::string::{String, ToString}; + +use ibc::{ + core::{ics02_client::height::Height, ics24_host::identifier::ClientId}, + timestamp::Timestamp, +}; +use lib::hash::CryptoHash; +use serde::{Deserialize, Serialize}; + +use crate::{client_def::GuestClient, error::Error, CLIENT_TYPE}; + +super::wrap!(cf_guest_upstream::ClientState as ClientState); +super::wrap!(impl proto for ClientState); + +impl ClientState { + pub fn new( + genesis_hash: CryptoHash, + latest_height: guestchain::BlockHeight, + trusting_period_ns: u64, + epoch_commitment: CryptoHash, + prev_epoch_commitment: Option, + is_frozen: bool, + ) -> Self { + Self(cf_guest_upstream::ClientState::new( + genesis_hash, + latest_height, + trusting_period_ns, + epoch_commitment, + prev_epoch_commitment, + is_frozen, + )) + } + + pub fn with_header(&self, header: &cf_guest_upstream::Header) -> Self { + Self(self.0.with_header(&header)) + } + + pub fn frozen(&self) -> Self { + Self(self.0.frozen()) + } + + /// Verify the time and height delays + pub fn verify_delay_passed( + current_time: Timestamp, + current_height: Height, + processed_time: u64, + processed_height: u64, + delay_period_time: u64, + delay_period_blocks: u64, + ) -> Result<(), Error> { + let earliest_time = processed_time + delay_period_time; + // NOTE: delay time period is inclusive, so if current_time is earliest_time, then we + // return no error https://github.com/cosmos/ibc-go/blob/9ebc2f81049869bc40c443ffb72d9f3e47afb4fc/modules/light-clients/07-tendermint/client_state.go#L306 + if current_time.nanoseconds() < earliest_time { + return Err(Error::NotEnoughTimeElapsed { current_time, earliest_time }) + } + + let earliest_height = processed_height + delay_period_blocks; + if current_height.revision_height < earliest_height { + return Err(Error::NotEnoughBlocksElapsed { current_height, earliest_height }) + } + + Ok(()) + } + + pub fn verify_height(&self, client_id: &ClientId, height: ibc::Height) -> Result<(), Error> { + if self.0.latest_height < height.revision_height.into() { + return Err(Error::InsufficientHeight { + latest_height: Height::new(1, self.0.latest_height.into()), + target_height: height, + }) + } + + if self.0.is_frozen { + return Err(Error::ClientFrozen { client_id: client_id.clone() }) + } + Ok(()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct UpgradeOptions {} + +impl ibc::core::ics02_client::client_state::ClientState for ClientState +where + PK: guestchain::PubKey + Send + Sync, + PK::Signature: Send + Sync, +{ + type UpgradeOptions = UpgradeOptions; + + type ClientDef = GuestClient; + + fn chain_id(&self) -> ibc::core::ics24_host::identifier::ChainId { + ibc::core::ics24_host::identifier::ChainId::new(String::from("Solana"), 0) + } + + fn client_def(&self) -> Self::ClientDef { + GuestClient::default() + } + + fn client_type(&self) -> ibc::core::ics02_client::client_state::ClientType { + CLIENT_TYPE.to_string() + } + + fn latest_height(&self) -> ibc::Height { + Height::new(1, u64::from(self.0.latest_height)) + } + + fn frozen_height(&self) -> Option { + self.0.is_frozen.then(|| Height::new(1, u64::from(self.0.latest_height))) + } + + fn upgrade( + mut self, + upgrade_height: ibc::Height, + _upgrade_options: Self::UpgradeOptions, + _chain_id: ibc::core::ics24_host::identifier::ChainId, + ) -> Self { + self.0.latest_height = upgrade_height.revision_height.into(); + self + } + + fn expired(&self, elapsed: core::time::Duration) -> bool { + elapsed.as_nanos() as u64 > self.0.trusting_period_ns + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + Ok(self.0.encode()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use guestchain::validators::MockPubKey; + + const ANY_MESSAGE: [u8; 116] = [ + 10, 34, 47, 108, 105, 103, 104, 116, 99, 108, 105, 101, 110, 116, 115, 46, 103, 117, 101, + 115, 116, 46, 118, 49, 46, 67, 108, 105, 101, 110, 116, 83, 116, 97, 116, 101, 18, 78, 10, + 32, 243, 148, 241, 41, 122, 49, 51, 253, 97, 145, 113, 22, 234, 164, 193, 183, 185, 48, + 160, 186, 69, 72, 144, 156, 126, 229, 103, 131, 220, 174, 140, 165, 16, 5, 24, 128, 128, + 144, 202, 210, 198, 14, 34, 32, 86, 12, 131, 131, 127, 125, 82, 54, 32, 207, 121, 149, 204, + 11, 121, 102, 180, 211, 111, 54, 0, 207, 247, 125, 195, 57, 10, 10, 80, 84, 86, 152, + ]; + + fn message() -> &'static [u8] { + &ANY_MESSAGE[38..] + } + + const GENESIS_HASH: CryptoHash = CryptoHash([ + 243, 148, 241, 41, 122, 49, 51, 253, 97, 145, 113, 22, 234, 164, 193, 183, 185, 48, 160, + 186, 69, 72, 144, 156, 126, 229, 103, 131, 220, 174, 140, 165, + ]); + const EPOCH_COMMITMENT: CryptoHash = CryptoHash([ + 86, 12, 131, 131, 127, 125, 82, 54, 32, 207, 121, 149, 204, 11, 121, 102, 180, 211, 111, + 54, 0, 207, 247, 125, 195, 57, 10, 10, 80, 84, 86, 152, + ]); + + fn check(state: ClientState) { + let want = ClientState::::new( + GENESIS_HASH.clone(), + 5.into(), + 64000000000000, + EPOCH_COMMITMENT.clone(), + Some(EPOCH_COMMITMENT.clone()), + false, + ); + assert_eq!(want, state); + } + + #[test] + fn test_decode_vec() { + check(ibc::protobuf::Protobuf::decode_vec(message()).unwrap()); + } + + #[test] + fn test_from_any() { + use ibc_proto::google::protobuf::Any; + + let any: Any = prost::Message::decode(ANY_MESSAGE.as_ref()).unwrap(); + check(any.try_into().unwrap()); + } +} diff --git a/light-clients/cf-guest/src/client_def.rs b/light-clients/cf-guest/src/client_def.rs new file mode 100644 index 000000000..454a7d8ca --- /dev/null +++ b/light-clients/cf-guest/src/client_def.rs @@ -0,0 +1,561 @@ +use core::str::FromStr; + +use guestchain::Signature; + +use crate::alloc::string::ToString; +use alloc::vec::Vec; +use guestchain::{PubKey, Verifier}; +use ibc::{ + core::{ + ics02_client::{ + client_consensus::ConsensusState, + client_def::{ClientDef, ConsensusUpdateResult}, + client_state::ClientState as OtherClientState, + error::Error as Ics02ClientError, + }, + ics26_routing::context::ReaderContext, + }, + protobuf::Protobuf, +}; +use prost::Message; + +use crate::{error::Error, ClientMessage, ClientState, ConsensusState as ClientConsensusState}; + +type Result = ::core::result::Result; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct GuestClient(core::marker::PhantomData); + +impl Default for GuestClient { + fn default() -> Self { + Self(core::marker::PhantomData) + } +} + +impl ClientDef for GuestClient +where + PK: PubKey + Send + Sync, + PK::Signature: Send + Sync, +{ + type ClientMessage = ClientMessage; + type ClientState = ClientState; + type ConsensusState = ClientConsensusState; + + fn verify_client_message( + &self, + _ctx: &Ctx, + _client_id: ibc::core::ics24_host::identifier::ClientId, + client_state: Self::ClientState, + client_msg: Self::ClientMessage, + ) -> Result<(), Ics02ClientError> { + client_state.0.do_verify_client_message(self, client_msg.0).map_err(convert) + } + + fn update_state( + &self, + _ctx: &Ctx, + _client_id: ibc::core::ics24_host::identifier::ClientId, + client_state: Self::ClientState, + client_msg: Self::ClientMessage, + ) -> Result< + (Self::ClientState, ibc::core::ics02_client::client_def::ConsensusUpdateResult), + Ics02ClientError, + > { + let header = match client_msg.0 { + cf_guest_upstream::ClientMessage::Header(header) => header, + _ => unreachable!("02-client will check for Header before calling update_state; qed"), + }; + let header_consensus_state = ClientConsensusState::from(&header); + let cs = Ctx::AnyConsensusState::wrap(&header_consensus_state).ok_or_else(|| { + Error::UnknownConsensusStateType { description: "Ctx::AnyConsensusState".to_string() } + })?; + Ok((client_state.with_header(&header), ConsensusUpdateResult::Single(cs))) + } + + fn update_state_on_misbehaviour( + &self, + client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result { + Ok(client_state.frozen()) + } + + fn check_for_misbehaviour( + &self, + ctx: &Ctx, + client_id: ibc::core::ics24_host::identifier::ClientId, + client_state: Self::ClientState, + client_msg: Self::ClientMessage, + ) -> Result { + let client_id = convert(client_id); + let ctx = CommonContext::new(ctx); + client_state + .0 + .do_check_for_misbehaviour(ctx, &client_id, client_msg.0) + .map_err(convert) + } + + fn verify_upgrade_and_update_state( + &self, + _ctx: &Ctx, + _client_id: ibc::core::ics24_host::identifier::ClientId, + _old_client_state: &Self::ClientState, + _upgrade_client_state: &Self::ClientState, + _upgrade_consensus_state: &Self::ConsensusState, + _proof_upgrade_client: ibc::prelude::Vec, + _proof_upgrade_consensus_state: ibc::prelude::Vec, + ) -> Result< + (Self::ClientState, ibc::core::ics02_client::client_def::ConsensusUpdateResult), + Ics02ClientError, + > { + // TODO: tendermint verify_upgrade_and_update_state + Err(Ics02ClientError::implementation_specific("Not implemented".to_string())) + } + + fn check_substitute_and_update_state( + &self, + _ctx: &Ctx, + _subject_client_id: ibc::core::ics24_host::identifier::ClientId, + _substitute_client_id: ibc::core::ics24_host::identifier::ClientId, + _old_client_state: Self::ClientState, + _substitute_client_state: Self::ClientState, + ) -> Result< + (Self::ClientState, ibc::core::ics02_client::client_def::ConsensusUpdateResult), + Ics02ClientError, + > { + // TODO: tendermint check_substitute_and_update_state + Err(Ics02ClientError::implementation_specific("Not implemented".to_string())) + } + + fn verify_client_consensus_state( + &self, + _ctx: &Ctx, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + client_id: &ibc::core::ics24_host::identifier::ClientId, + consensus_height: ibc::Height, + expected_consensus_state: &Ctx::AnyConsensusState, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ClientConsensusStatePath { + client_id: convert(client_id), + revision_number: consensus_height.revision_number, + revision_height: consensus_height.revision_height, + }; + let value = expected_consensus_state.encode_to_vec().map_err(Ics02ClientError::encode)?; + verify(proof, root, path.into(), Some(value)) + } + + fn verify_connection_state( + &self, + _ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + connection_id: &ibc::core::ics24_host::identifier::ConnectionId, + expected_connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ConnectionPath(convert(connection_id)); + let value = expected_connection_end.clone().encode_vec(); + verify(proof, root, path.into(), Some(value)) + } + + fn verify_channel_state( + &self, + _ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + expected_channel_end: &ibc::core::ics04_channel::channel::ChannelEnd, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ChannelEndPath(convert(port_id), convert(channel_id)); + let value = expected_channel_end.clone().encode_vec(); + verify(proof, root, path.into(), Some(value)).map_err(|e| e.into()) + } + + fn verify_client_full_state( + &self, + _ctx: &Ctx, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + client_id: &ibc::core::ics24_host::identifier::ClientId, + expected_client_state: &Ctx::AnyClientState, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ClientStatePath(convert(client_id)); + let value = expected_client_state.encode_to_vec().map_err(Ics02ClientError::encode)?; + verify(proof, root, path.into(), Some(value)).map_err(|e| e.into()) + } + + fn verify_packet_data( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + commitment: ibc::core::ics04_channel::commitment::PacketCommitment, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::CommitmentPath { + port_id: convert(port_id), + channel_id: convert(channel_id), + sequence: sequence.0.into(), + }; + verify(proof, root, path.into(), Some(commitment.into_vec())) + } + + fn verify_packet_acknowledgement( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + ack: ibc::core::ics04_channel::commitment::AcknowledgementCommitment, + ) -> Result<(), Ics02ClientError> { + // client state height = consensus state height + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::AckPath { + port_id: convert(port_id), + channel_id: convert(channel_id), + sequence: sequence.0.into(), + }; + verify(proof, root, path.into(), Some(ack.into_vec())) + } + + fn verify_next_sequence_recv( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::SeqRecvPath(convert(port_id), convert(channel_id)); + let mut seq_bytes = Vec::new(); + u64::from(sequence).encode(&mut seq_bytes).expect("buffer size too small"); + verify(proof, root, path.into(), Some(seq_bytes)) + } + + fn verify_packet_receipt_absence( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::ReceiptPath { + port_id: convert(port_id), + channel_id: convert(channel_id), + sequence: sequence.0.into(), + }; + verify(proof, root, path.into(), None) + } +} + +fn verify_delay_passed( + ctx: &Ctx, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, +) -> Result<(), Ics02ClientError> { + let current_timestamp = ctx.host_timestamp(); + let current_height = ctx.host_height(); + + let client_id = connection_end.client_id(); + let processed_time = ctx + .client_update_time(client_id, height) + .map_err(|_| Error::ProcessedTimeNotFound { height })?; + let processed_height = ctx + .client_update_height(client_id, height) + .map_err(|_| Error::ProcessedHeightNotFound { height })?; + + let delay_period_time = connection_end.delay_period(); + let delay_period_height = ctx.block_delay(delay_period_time); + let delay_period_time_u64 = u64::try_from(delay_period_time.as_nanos()).unwrap(); + + ClientState::::verify_delay_passed( + current_timestamp, + current_height, + processed_time.nanoseconds(), + processed_height.revision_height, + delay_period_time_u64, + delay_period_height, + ) + .map_err(|e| e.into()) +} + +impl Verifier for GuestClient { + fn verify(&self, message: &[u8], pubkey: &PK, signature: &PK::Signature) -> bool { + (|| { + let pubkey = pubkey.as_bytes(); + let pubkey = ed25519_consensus::VerificationKey::try_from(&pubkey[..]).ok()?; + let signature = signature.as_bytes(); + let sig = ed25519_consensus::Signature::try_from(&signature[..]).ok()?; + pubkey.verify(&sig, message).ok()?; + Some(()) + })() + .is_some() + } +} + +#[derive(bytemuck::TransparentWrapper)] +#[repr(transparent)] +#[transparent(Ctx)] +struct CommonContext { + ctx: Ctx, + _ph: core::marker::PhantomData, +} + +impl CommonContext { + fn new(ctx: &Ctx) -> &Self { + bytemuck::TransparentWrapper::wrap_ref(ctx) + } +} + +type NewResult = Result; + +impl cf_guest_upstream::CommonContext + for CommonContext +{ + type ConversionError = core::convert::Infallible; + type AnyClientState = ClientState; + type AnyConsensusState = ClientConsensusState; + + fn host_metadata( + &self, + ) -> NewResult<(ibc_primitives::Timestamp, ibc_core_client_types::Height)> { + unimplemented!("host_metadata") + } + + fn set_client_state( + &mut self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _state: ClientState, + ) -> NewResult<()> { + unimplemented!("set_client_state") + } + + fn consensus_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: ibc_core_client_types::Height, + ) -> NewResult { + unimplemented!("consensus_state") + } + + fn consensus_state_neighbourhood( + &self, + client_id: &ibc_core_host_types::identifiers::ClientId, + height: ibc_core_client_types::Height, + ) -> NewResult> { + use cf_guest_upstream::Neighbourhood; + + let res: Result<_, Ics02ClientError> = (|| { + let client_id = convert(client_id); + let height = convert(height); + Ok(if let Some(state) = self.ctx.maybe_consensus_state(&client_id, height)? { + Neighbourhood::This(state) + } else { + let prev = self.ctx.prev_consensus_state(&client_id, height)?; + let next = self.ctx.next_consensus_state(&client_id, height)?; + Neighbourhood::Neighbours(prev, next) + }) + })(); + match res { + Ok(res) => Ok(res.map(|state: Ctx::AnyConsensusState| { + // TODO(mina86): propagate error rather than unwrapping + let state: Self::AnyConsensusState = state.downcast().unwrap(); + state + })), + Err(err) => Err(convert(err)), + } + } + + fn store_consensus_state_and_metadata( + &mut self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: ibc_core_client_types::Height, + _consensus: Self::AnyConsensusState, + _host_timestamp: ibc_primitives::Timestamp, + _host_height: ibc_core_client_types::Height, + ) -> NewResult { + unimplemented!("store_consensus_state_and_metadata") + } + + fn delete_consensus_state_and_metadata( + &mut self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: ibc_core_client_types::Height, + ) -> NewResult { + unimplemented!("delete_consensus_state_and_metadata") + } + + fn earliest_consensus_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + ) -> NewResult> { + unimplemented!("earliest_consensus_state") + } +} + +// Helper wrappers + +fn verify( + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + path: ibc_core_host_types::path::Path, + value: Option>, +) -> Result<(), Ics02ClientError> { + cf_guest_upstream::proof::verify( + &[], + proof.as_bytes(), + root.bytes.as_slice(), + path, + value.as_deref(), + ) + .map_err(|err| Ics02ClientError::implementation_specific(err.to_string())) +} + +// Conversion between old and new. + +fn convert>(value: F) -> T { + T::convert(value) +} + +trait ConvertFrom: Sized { + fn convert(value: From) -> Self; +} + +macro_rules! conv { + ($( $value:ident: $From:ty => $To:ty { $($body:tt)*} )*) => { + $( + impl ConvertFrom<$From> for $To { + fn convert($value: $From) -> Self { + Self::convert(&$value) + } + } + + impl ConvertFrom<&$From> for $To { + fn convert($value: &$From) -> Self { + $($body)* + } + } + )* + } +} + +conv! { + client_id: ibc::core::ics24_host::identifier::ClientId => + ibc_core_host_types::identifiers::ClientId { + FromStr::from_str(client_id.as_str()).unwrap() + } + client_id: ibc_core_host_types::identifiers::ClientId => ibc::core::ics24_host::identifier::ClientId { + FromStr::from_str(client_id.as_str()).unwrap() + } + + connection_id: ibc::core::ics24_host::identifier::ConnectionId => + ibc_core_host_types::identifiers::ConnectionId { + FromStr::from_str(connection_id.as_str()).unwrap() + } + + port_id: ibc::core::ics24_host::identifier::PortId => + ibc_core_host_types::identifiers::PortId { + FromStr::from_str(port_id.as_str()).unwrap() + } + + channel_id: ibc::core::ics24_host::identifier::ChannelId => + ibc_core_host_types::identifiers::ChannelId { + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()) + } + + + timestamp: ibc::timestamp::Timestamp => ibc_primitives::Timestamp { + Self::from_nanoseconds(timestamp.nanoseconds()).unwrap() + } + + height: ibc::core::ics02_client::height::Height => ibc_core_client_types::Height { + Self::new(height.revision_number, height.revision_height).unwrap() + } + + height: ibc_core_client_types::Height => ibc::core::ics02_client::height::Height { + Self::new(height.revision_number(), height.revision_height()) + } + + + err: ibc_core_client_context::types::error::ClientError => Ics02ClientError { + // TODO(mina86): Create better mapping. + Self::implementation_specific(err.to_string()) + } + err: Ics02ClientError => ibc_core_client_context::types::error::ClientError { + // TODO(mina86): Create better mapping. + Self::ClientSpecific { + description: err.to_string() + } + } +} + +impl> ConvertFrom> for Option { + fn convert(value: Option) -> Self { + value.map(convert) + } +} + +impl, TE: ConvertFrom> ConvertFrom> + for Result +{ + fn convert(value: Result) -> Self { + value.map(convert).map_err(convert) + } +} diff --git a/light-clients/cf-guest/src/client_impls.rs b/light-clients/cf-guest/src/client_impls.rs new file mode 100644 index 000000000..a1fe79326 --- /dev/null +++ b/light-clients/cf-guest/src/client_impls.rs @@ -0,0 +1,363 @@ +use alloc::{string::ToString, vec::Vec}; + +use guestchain::PubKey; +use prost::DecodeError; + +use super::{proof, Any, ClientMessage, ClientState, ConsensusState, Header, Misbehaviour}; + +mod ibc { + // pub use ibc::core::ics02_client::client_state::{ + // ClientStateCommon, ClientStateExecution, ClientStateValidation, + // }; + pub use ibc::core::ics02_client::{ + client_state::Status, error::Error as ClientError, height::Height, + }; + // pub use ibc::core::ics02_client::context::{ + // ClientExecutionContext, ClientValidationContext, + // }; + pub use ibc::core::{ + ics23_commitment::{ + commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}, + error::Error as CommitmentError, + }, + ics24_host::{identifier::ClientId, path, Path::ClientType}, + }; + // pub use ibc::core::ics24_host::{ExecutionContext, ValidationContext}; + pub use ibc::timestamp::Timestamp; +} + +type Result = ::core::result::Result; + +pub trait CommonContext { + type ConversionError: ToString; + type AnyConsensusState: TryInto + + From; + + fn host_metadata(&self) -> Result<(ibc::Timestamp, ibc::Height)>; + + fn consensus_state( + &self, + client_id: &ibc::ClientId, + height: ibc::Height, + ) -> Result; + + fn store_consensus_state_and_metadata( + &mut self, + client_id: &ibc::ClientId, + height: ibc::Height, + consensus: Self::AnyConsensusState, + host_timestamp: ibc::Timestamp, + host_height: ibc::Height, + ) -> Result; + + fn delete_consensus_state_and_metadata( + &mut self, + client_id: &ibc::ClientId, + height: ibc::Height, + ) -> Result; + + fn sorted_consensus_state_heights(&self, client_id: &ibc::ClientId) + -> Result>; +} + +// impl ibc::ClientStateCommon for ClientState { +// fn verify_consensus_state(&self, consensus_state: Any) -> Result { +// ConsensusState::try_from(consensus_state)?; +// Ok(()) +// } + +// fn client_type(&self) -> ibc::ClientType { +// ibc::ClientType::new(super::CLIENT_TYPE).unwrap() +// } + +// fn latest_height(&self) -> ibc::Height { +// ibc::Height::new(0, self.latest_height.into()).unwrap() +// } + +// fn validate_proof_height(&self, proof_height: ibc::Height) -> Result { +// let latest_height = self.latest_height(); +// if proof_height <= latest_height { +// Ok(()) +// } else { +// Err(ibc::ClientError::InvalidProofHeight { +// latest_height, +// proof_height, +// }) +// } +// } + +// /// Panics since client upgrades aren’t supported. +// fn verify_upgrade_client( +// &self, +// _upgraded_client_state: Any, +// _upgraded_consensus_state: Any, +// _proof_upgrade_client: ibc::CommitmentProofBytes, +// _proof_upgrade_consensus_state: ibc::CommitmentProofBytes, +// _root: &ibc::CommitmentRoot, +// ) -> Result { unimplemented!("IBC cilent upgrades are currently not supported") +// } + +// /// Verifies membership proof. +// /// +// /// See [`proof::verify`] for documentation of the proof format. +// fn verify_membership( +// &self, +// prefix: &ibc::CommitmentPrefix, +// proof: &ibc::CommitmentProofBytes, +// root: &ibc::CommitmentRoot, +// path: ibc::path::Path, +// value: Vec, +// ) -> Result { let value = Some(value.as_slice()); proof::verify(prefix, proof, root, path, +// value).map_err(Into::into) +// } + +// /// Verifies membership proof. +// /// +// /// See [`proof::verify`] for documentation of the proof format. +// fn verify_non_membership( +// &self, +// prefix: &ibc::CommitmentPrefix, +// proof: &ibc::CommitmentProofBytes, +// root: &ibc::CommitmentRoot, +// path: ibc::path::Path, +// ) -> Result { proof::verify(prefix, proof, root, path, None).map_err(Into::into) +// } +// } + +impl From for ibc::ClientError { + fn from(err: proof::VerifyError) -> Self { + use ::ibc::core::ics23_commitment::error::Error; + use proof::VerifyError::*; + + Self::invalid_commitment_proof(match err { + ProofDecodingFailure(msg) => + Error::commitment_proof_decoding_failed(DecodeError::new(msg)), + WrongSequenceNumber(err) => Error::commitment_proof_decoding_failed(err), + _ => ibc::CommitmentError::invalid_merkle_proof(), + }) + } +} + +// impl ibc::ClientStateExecution for ClientState +// where +// E: ibc::ExecutionContext + ibc::ClientExecutionContext + CommonContext, +// ::AnyClientState: From>, +// ::AnyConsensusState: From, +// { +// fn initialise( +// &self, +// ctx: &mut E, +// client_id: &ibc::ClientId, +// consensus_state: Any, +// ) -> Result { parse_client_id(client_id)?; let consensus_state = +// super::ConsensusState::try_from(consensus_state)?; + +// ctx.store_client_state( +// ibc::path::ClientStatePath::new(client_id.clone()), +// self.clone().into(), +// )?; +// ctx.store_consensus_state( +// ibc::path::ClientConsensusStatePath::new( +// client_id.clone(), +// 0, +// u64::from(self.latest_height), +// ), +// consensus_state.into(), +// )?; + +// Ok(()) +// } + +// fn update_state( +// &self, +// ctx: &mut E, +// client_id: &ibc::ClientId, +// header: Any, +// ) -> Result> { let header = crate::proto::Header::try_from(header)?; let +// header = crate::Header::::try_from(header)?; let header_height = ibc::Height::new(0, +// header.block_header.block_height.into())?; + +// let (host_timestamp, host_height) = CommonContext::host_metadata(ctx)?; +// self.prune_oldest_consensus_state(ctx, client_id, host_timestamp)?; + +// let maybe_existing_consensus = +// CommonContext::consensus_state(ctx, client_id, header_height).ok(); +// if maybe_existing_consensus.is_none() { +// let new_consensus_state = ConsensusState::from(&header); +// let new_client_state = self.with_header(&header); + +// ctx.store_client_state( +// ibc::path::ClientStatePath::new(client_id.clone()), +// new_client_state.into(), +// )?; +// ctx.store_consensus_state_and_metadata( +// client_id, +// header_height, +// new_consensus_state.into(), +// host_timestamp, +// host_height, +// )?; +// } + +// Ok(alloc::vec![header_height]) +// } + +// fn update_state_on_misbehaviour( +// &self, +// ctx: &mut E, +// client_id: &ibc::ClientId, +// _client_message: Any, +// ) -> Result { ctx.store_client_state( ibc::path::ClientStatePath::new(client_id.clone()), +// self.frozen().into(), )?; Ok(()) +// } + +// fn update_state_on_upgrade( +// &self, +// _ctx: &mut E, +// _client_id: &ibc::ClientId, +// _upgraded_client_state: Any, +// _upgraded_consensus_state: Any, +// ) -> Result { Err(ibc::UpgradeClientError::Other { reason: "upgrade not +// supported".into(), } .into()) +// } +// } + +// impl ibc::ClientStateValidation for ClientState +// where +// V: ibc::ValidationContext +// + ibc::ClientValidationContext +// + CommonContext +// + guestchain::Verifier, +// { +// fn verify_client_message( +// &self, +// ctx: &V, +// client_id: &ibc::ClientId, +// client_message: Any, +// ) -> Result { self.verify_client_message(ctx, client_id, client_message) +// } + +// fn check_for_misbehaviour( +// &self, +// ctx: &V, +// client_id: &ibc::ClientId, +// client_message: Any, +// ) -> Result { self.check_for_misbehaviour(ctx, client_id, client_message) +// } + +// fn status( +// &self, +// ctx: &V, +// client_id: &ibc::ClientId, +// ) -> Result { if self.is_frozen { return Ok(ibc::Status::Frozen); } + +// let height = ibc::Height::new(0, self.latest_height.into())?; +// let consensus = CommonContext::consensus_state(ctx, client_id, height) +// .and_then(|state| state.try_into().map_err(error)); +// let consensus = match consensus { +// Ok(consensus) => consensus, +// Err(ibc::ClientError::ConsensusStateNotFound { .. }) => { +// return Ok(ibc::Status::Expired) +// } +// Err(err) => return Err(err), +// }; + +// let (host_timestamp, _height) = CommonContext::host_metadata(ctx)?; +// Ok(if self.consensus_has_expired(&consensus, host_timestamp) { +// ibc::Status::Expired +// } else { +// ibc::Status::Active +// }) +// } +// } + +impl ClientState { + pub fn verify_client_message( + &self, + ctx: &impl guestchain::Verifier, + _client_id: &ibc::ClientId, + client_message: ClientMessage, + ) -> Result<()> { + match client_message { + ClientMessage::Header(header) => self.verify_header(ctx, header), + ClientMessage::Misbehaviour(misbehaviour) => + self.verify_misbehaviour(ctx, misbehaviour), + } + } + + pub fn check_for_misbehaviour( + &self, + ctx: &impl guestchain::Verifier, + _client_id: &ibc::ClientId, + client_message: Any, + ) -> Result { + match ClientMessage::::try_from(client_message)? { + ClientMessage::Header(header) => self.check_for_misbehaviour_header(ctx, header), + ClientMessage::Misbehaviour(misbehaviour) => + self.check_for_misbehaviour_misbehavior(ctx, misbehaviour), + } + } + + fn verify_header(&self, ctx: &impl guestchain::Verifier, header: Header) -> Result<()> { + (|| { + // panic!("header epoch {:?} and client epoch {:?}", header.epoch_commitment, + // self.epoch_commitment); + if header.epoch_commitment != self.epoch_commitment { + return Err("Unexpected epoch") + } + let fp = guestchain::block::Fingerprint::from_hash( + &header.genesis_hash, + header.block_header.block_height, + &header.block_hash, + ); + let mut quorum_left = header.epoch.quorum_stake().get(); + let mut validators = + header.epoch.validators().iter().map(Some).collect::>>(); + for (idx, sig) in header.signatures { + let validator = validators + .get_mut(usize::from(idx)) + .ok_or("Validator index out of bounds")? + .take() + .ok_or("Duplicate signature")?; + if !ctx.verify(fp.as_slice(), &validator.pubkey, &sig) { + return Err("Bad signature") + } + quorum_left = quorum_left.saturating_sub(validator.stake.get()); + if quorum_left == 0 { + break + } + } + Ok(()) + // Err("Quorum not reached") + })() + .map_err(error) + } + + fn verify_misbehaviour( + &self, + _ctx: &impl guestchain::Verifier, + _misbehaviour: Misbehaviour, + ) -> Result<()> { + todo!() + } + + fn check_for_misbehaviour_header( + &self, + _ctx: &impl guestchain::Verifier, + _header: Header, + ) -> Result { + Ok(false) + } + + fn check_for_misbehaviour_misbehavior( + &self, + _ctx: &impl guestchain::Verifier, + _misbehaviour: Misbehaviour, + ) -> Result { + todo!() + } +} + +fn error(msg: impl ToString) -> ibc::ClientError { + ibc::ClientError::implementation_specific(msg.to_string()) +} diff --git a/light-clients/cf-guest/src/consensus.rs b/light-clients/cf-guest/src/consensus.rs new file mode 100644 index 000000000..8d0c5a60f --- /dev/null +++ b/light-clients/cf-guest/src/consensus.rs @@ -0,0 +1,97 @@ +use core::{convert::Infallible, num::NonZeroU64}; + +use lib::hash::CryptoHash; +use prost::Message as _; + +use crate::proto; + +super::wrap!(cf_guest_upstream::ConsensusState as ConsensusState); +super::wrap!(impl Eq for ConsensusState); +super::wrap!(impl proto for ConsensusState); + +impl ConsensusState { + pub fn new(block_hash: &CryptoHash, timestamp_ns: NonZeroU64) -> Self { + Self(cf_guest_upstream::ConsensusState::new(block_hash, timestamp_ns)) + } +} + +impl ibc::core::ics02_client::client_consensus::ConsensusState for ConsensusState { + type Error = Infallible; + + fn root(&self) -> &ibc::core::ics23_commitment::commitment::CommitmentRoot { + // SAFETY: Both types are wrappers around Vec. + unsafe { core::mem::transmute(&self.0.block_hash) } + } + + fn timestamp(&self) -> ibc::timestamp::Timestamp { + ibc::timestamp::Timestamp::from_nanoseconds(self.0.timestamp_ns.get()).unwrap() + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + Ok(proto::ConsensusState::from(self).encode_to_vec()) + } +} + +impl From> for ConsensusState { + fn from(header: crate::Header) -> Self { + Self::from(&header.0) + } +} + +impl From<&crate::Header> for ConsensusState { + fn from(header: &crate::Header) -> Self { + Self::from(&header.0) + } +} + +impl From> for ConsensusState { + fn from(header: cf_guest_upstream::Header) -> Self { + Self::from(&header) + } +} + +impl From<&cf_guest_upstream::Header> for ConsensusState { + fn from(header: &cf_guest_upstream::Header) -> Self { + Self(header.into()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const ANY_MESSAGE: [u8; 85] = [ + 10, 37, 47, 108, 105, 103, 104, 116, 99, 108, 105, 101, 110, 116, 115, 46, 103, 117, 101, + 115, 116, 46, 118, 49, 46, 67, 111, 110, 115, 101, 110, 115, 117, 115, 83, 116, 97, 116, + 101, 18, 44, 10, 32, 74, 147, 61, 207, 26, 96, 73, 253, 54, 118, 91, 237, 36, 210, 58, 218, + 179, 236, 158, 187, 5, 231, 241, 133, 178, 150, 85, 151, 36, 160, 36, 105, 16, 128, 220, + 164, 128, 131, 220, 190, 228, 23, + ]; + + fn message() -> &'static [u8] { + &ANY_MESSAGE[41..] + } + + const BLOCK_HASH: CryptoHash = CryptoHash([ + 74, 147, 61, 207, 26, 96, 73, 253, 54, 118, 91, 237, 36, 210, 58, 218, 179, 236, 158, 187, + 5, 231, 241, 133, 178, 150, 85, 151, 36, 160, 36, 105, + ]); + + fn check(state: ConsensusState) { + let want = ConsensusState::new(&BLOCK_HASH, NonZeroU64::new(1713895499000000000).unwrap()); + assert_eq!(want, state); + } + + #[test] + fn test_decode_vec() { + check(ibc::protobuf::Protobuf::decode_vec(message()).unwrap()); + } + + #[test] + fn test_from_any() { + use ibc_proto::google::protobuf::Any; + + let any: Any = prost::Message::decode(ANY_MESSAGE.as_ref()).unwrap(); + check(any.try_into().unwrap()); + } +} diff --git a/light-clients/cf-guest/src/error.rs b/light-clients/cf-guest/src/error.rs new file mode 100644 index 000000000..7c6cee943 --- /dev/null +++ b/light-clients/cf-guest/src/error.rs @@ -0,0 +1,43 @@ +// Copyright 2022 ComposableFi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::CLIENT_TYPE; +use alloc::{ + fmt, + string::{String, ToString}, +}; +use ibc::{core::ics24_host::identifier::ClientId, timestamp::Timestamp, Height}; + +#[derive(Clone, Debug)] +pub enum Error { + ProcessedHeightNotFound { height: Height }, + ProcessedTimeNotFound { height: Height }, + NotEnoughTimeElapsed { current_time: Timestamp, earliest_time: u64 }, + NotEnoughBlocksElapsed { current_height: Height, earliest_height: u64 }, + InsufficientHeight { latest_height: Height, target_height: Height }, + ClientFrozen { client_id: ClientId }, + UnknownConsensusStateType { description: String }, +} + +impl fmt::Display for Error { + fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self, fmtr) + } +} + +impl From for ibc::core::ics02_client::error::Error { + fn from(err: Error) -> Self { + Self::client_error(CLIENT_TYPE.into(), err.to_string()) + } +} diff --git a/light-clients/cf-guest/src/header.rs b/light-clients/cf-guest/src/header.rs new file mode 100644 index 000000000..ae4ee2458 --- /dev/null +++ b/light-clients/cf-guest/src/header.rs @@ -0,0 +1,2 @@ +super::wrap!(cf_guest_upstream::Header as Header); +super::wrap!(impl proto for Header); diff --git a/light-clients/cf-guest/src/lib.rs b/light-clients/cf-guest/src/lib.rs new file mode 100644 index 000000000..56b4fc564 --- /dev/null +++ b/light-clients/cf-guest/src/lib.rs @@ -0,0 +1,243 @@ +#![allow(clippy::unit_arg, clippy::comparison_chain)] +#![no_std] +extern crate alloc; +// #[cfg(any(feature = "std", test))] +extern crate std; + +use alloc::string::ToString; + +pub mod client; +pub mod client_def; +mod consensus; +pub mod error; +mod header; +mod message; +mod misbehaviour; +pub mod proof; +pub mod proto; + +pub use client::ClientState; +pub use consensus::ConsensusState; +pub use header::Header; +pub use message::ClientMessage; +pub use misbehaviour::Misbehaviour; + +use ibc::core::ics02_client::error::Error as ClientError; + +/// Client type of the guest blockchain’s light client. +pub const CLIENT_TYPE: &str = "cf-guest"; + +pub use crate::proto::{BadMessage, DecodeError}; + +impl From for ClientError { + fn from(err: DecodeError) -> Self { + ClientError::implementation_specific(err.to_string()) + } +} + +impl From for ClientError { + fn from(_: BadMessage) -> Self { + ClientError::implementation_specific("BadMessage".to_string()) + } +} + +/// Returns digest of the value. +/// +/// This is used, among other places, as packet commitment. +#[inline] +pub fn digest(value: &[u8]) -> lib::hash::CryptoHash { + lib::hash::CryptoHash::digest(value) +} + +/// Returns digest of the value with client id mixed in. +/// +/// We don’t store full client id in the trie key for paths which include +/// client id. To avoid accepting malicious proofs, we must include it in +/// some other way. We do this by mixing in the client id into the hash of +/// the value stored at the path. +/// +/// Specifically, this calculates `digest(client_id || b'0' || serialised)`. +#[inline] +pub fn digest_with_client_id( + client_id: &ibc::core::ics24_host::identifier::ClientId, + value: &[u8], +) -> lib::hash::CryptoHash { + lib::hash::CryptoHash::digestv(&[client_id.as_bytes(), b"\0", value]) +} + +macro_rules! wrap { + ($($Inner:ident)::* as $Outer:ident) => { + #[derive(Clone, derive_more::From, derive_more::Into)] + #[repr(transparent)] + pub struct $Outer(pub $($Inner)::*); + + impl core::fmt::Debug for $Outer { + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(fmtr) + } + } + + impl From<$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: $Outer) -> Self { + Self::from(&msg) + } + } + + impl From<&$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: &$Outer) -> Self { + let any = cf_guest_upstream::proto::Any::from(&msg.0); + Self { + type_url: any.type_url, + value: any.value + } + } + } + + impl TryFrom for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: ibc_proto::google::protobuf::Any) -> Result { + Self::try_from(&any) + } + } + + impl TryFrom<&ibc_proto::google::protobuf::Any> for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: &ibc_proto::google::protobuf::Any) -> Result { + Ok(Self(cf_guest_upstream::proto::AnyConvert::try_from_any(&any.type_url, &any.value)?)) + } + } + }; + + ($($Inner:ident)::* as $Outer:ident) => { + #[derive(Clone, PartialEq, Eq, derive_more::From, derive_more::Into)] + #[repr(transparent)] + pub struct $Outer(pub $($Inner)::*); + + impl core::fmt::Debug for $Outer { + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(fmtr) + } + } + + impl From<$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: $Outer) -> Self { + Self::from(&msg) + } + } + + impl From<&$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: &$Outer) -> Self { + let any = cf_guest_upstream::proto::Any::from(&msg.0); + Self { + type_url: any.type_url, + value: any.value + } + } + } + + impl TryFrom for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: ibc_proto::google::protobuf::Any) -> Result { + Self::try_from(&any) + } + } + + impl TryFrom<&ibc_proto::google::protobuf::Any> for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: &ibc_proto::google::protobuf::Any) -> Result { + Ok(Self(cf_guest_upstream::proto::AnyConvert::try_from_any(&any.type_url, &any.value)?)) + } + } + }; + + (impl Default for $Outer:ident) => { + impl Default for $Outer { + fn default() -> Self { Self(Default::default()) } + } + }; + + (impl Default for $Outer:ident) => { + impl Default for $Outer { + fn default() -> Self { Self(Default::default()) } + } + }; + + (impl Eq for $Outer:ident) => { + impl core::cmp::PartialEq for $Outer { + fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) } + } + impl core::cmp::Eq for $Outer { } + }; + + (impl proto for $Type:ident) => { + impl $crate::proto::$Type { + pub const IBC_TYPE_URL: &'static str = + cf_guest_upstream::proto::$Type::IBC_TYPE_URL; + } + + impl From<$Type> for $crate::proto::$Type { + fn from(msg: $Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl From<&$Type> for $crate::proto::$Type { + fn from(msg: &$Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl TryFrom<$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: $crate::proto::$Type) -> Result { + Self::try_from(&msg) + } + } + + impl TryFrom<&$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: &$crate::proto::$Type) -> Result { + Ok(Self(cf_guest_upstream::$Type::try_from(&msg.0)?)) + } + } + + impl ibc::protobuf::Protobuf<$crate::proto::$Type> for $Type {} + }; + + (impl proto for $Type:ident) => { + impl $crate::proto::$Type { + pub const IBC_TYPE_URL: &'static str = + cf_guest_upstream::proto::$Type::IBC_TYPE_URL; + } + + impl From<$Type> for $crate::proto::$Type { + fn from(msg: $Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl From<&$Type> for $crate::proto::$Type { + fn from(msg: &$Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl TryFrom<$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: $crate::proto::$Type) -> Result { + Self::try_from(&msg) + } + } + + impl TryFrom<&$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: &$crate::proto::$Type) -> Result { + Ok(Self(cf_guest_upstream::$Type::try_from(&msg.0)?)) + } + } + + impl ibc::protobuf::Protobuf<$crate::proto::$Type> for $Type {} + }; +} + +use wrap; diff --git a/light-clients/cf-guest/src/message.rs b/light-clients/cf-guest/src/message.rs new file mode 100644 index 000000000..ad3a89487 --- /dev/null +++ b/light-clients/cf-guest/src/message.rs @@ -0,0 +1,52 @@ +use guestchain::PubKey; +use prost::Message as _; + +use crate::proto; + +super::wrap!(cf_guest_upstream::ClientMessage as ClientMessage); +super::wrap!(impl proto for ClientMessage); + +impl ClientMessage { + pub fn maybe_header_height(&self) -> Option { + if let cf_guest_upstream::ClientMessage::Header(hdr) = &self.0 { + let height = hdr.block_header.block_height; + Some(ibc::Height::new(1, height.into())) + } else { + None + } + } +} + +impl ibc::core::ics02_client::client_message::ClientMessage for ClientMessage +where + PK: PubKey + Send + Sync, + PK::Signature: Send + Sync, +{ + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + Ok(proto::ClientMessage::from(self).encode_to_vec()) + } +} + +impl From> for ClientMessage { + fn from(hdr: cf_guest_upstream::Header) -> Self { + Self(cf_guest_upstream::ClientMessage::Header(hdr)) + } +} + +impl From> for ClientMessage { + fn from(hdr: crate::Header) -> Self { + Self(cf_guest_upstream::ClientMessage::Header(hdr.0)) + } +} + +impl From> for ClientMessage { + fn from(msg: cf_guest_upstream::Misbehaviour) -> Self { + Self(cf_guest_upstream::ClientMessage::Misbehaviour(msg)) + } +} + +impl From> for ClientMessage { + fn from(msg: crate::Misbehaviour) -> Self { + Self(cf_guest_upstream::ClientMessage::Misbehaviour(msg.0)) + } +} diff --git a/light-clients/cf-guest/src/misbehaviour.rs b/light-clients/cf-guest/src/misbehaviour.rs new file mode 100644 index 000000000..af592f747 --- /dev/null +++ b/light-clients/cf-guest/src/misbehaviour.rs @@ -0,0 +1,2 @@ +super::wrap!(cf_guest_upstream::Misbehaviour as Misbehaviour); +super::wrap!(impl proto for Misbehaviour); diff --git a/light-clients/cf-guest/src/proof.rs b/light-clients/cf-guest/src/proof.rs new file mode 100644 index 000000000..4966ce4c6 --- /dev/null +++ b/light-clients/cf-guest/src/proof.rs @@ -0,0 +1,195 @@ +use core::str::FromStr; + +use guestchain::BlockHeader; +use ibc_core_host_types::path::{ + AckPath, ChannelEndPath, ClientConnectionPath, CommitmentPath, ConnectionPath, PortPath, + ReceiptPath, SeqAckPath, SeqRecvPath, SeqSendPath, +}; + +mod ibc { + pub use ibc::core::{ + ics02_client::error::Error as ClientError, + ics04_channel::packet::Sequence, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}, + ics24_host::{ + identifier, + identifier::{ChannelId, ClientId, ConnectionId, PortId}, + path, + }, + }; +} + +pub use cf_guest_upstream::proof::{GenerateError, IbcProof, VerifyError}; + +/// Generates a proof for given path. +/// +/// `block_header` is header whose hash will be the commitment root. It’s +/// state root must correspond to `trie`’s root. `path` specifies IBC path +/// of the value that needs proof. +/// +/// # Proof format +/// +/// In most cases, proof is Borsh-serialised `(guestchain::BlockHeader, +/// sealable_trie::proof::Proof)` pair. The header at the front is necessary to +/// determine state root (recall that `root` is the block hash and not state +/// root). +/// +/// However, if `path` is one of `SeqSend`, `SeqRecv` or `SeqAck` than proof +/// further contain two big-endian encoded `u64` numbers holding the other +/// two sequence numbers. +/// +/// For example, if `path` is `SeqRecv`, the `proof` must at the end include +/// send sequence number and ack sequence number. For example, if next send +/// sequence is `7`, next ack sequence is `5` and path is `SeqRecv` the +/// proof will end with `be(7) || be(5)` (where `be` denotes encoding 64-bit +/// number as big endian). +/// +/// This addition is necessary because sequence numbers are stored together +/// within a single trie value. For example, proving the next receive +/// sequence is `4` requires proving `be(7), be(4), be(5), be(0)]. For +/// verifier to know what value it checks, it needs to be provided all of +/// the sequence numbers. +/// +/// (Note that Borsh uses little endian to encode integers so the sequence +/// numbers cannot be simply borsh deserialised.) +pub fn generate( + block_header: &BlockHeader, + trie: &sealable_trie::Trie, + path: ibc::path::Path, +) -> Result { + let path = convert_old_path_to_new(path); + cf_guest_upstream::proof::generate(block_header, trie, path) +} + +/// Verifies a proof for given entry or lack of entry. +/// +/// `prefix` must be empty, `proof` and `root` must follow format described in +/// [`generate`] function. `path` indicates IBC path the proof is for and +/// `value` determines value or lack thereof expected at the path. +/// +/// # Value hash +/// +/// Since sealable trie doesn’t store values but only hashes, when verifying +/// membership proofs the value needs to be converted into a hash. There are +/// three cases: +/// +/// 1. If `path` includes client id, the hash of the value is calculated with the client id mixed +/// in; see [`super::digest_with_client_id`] function. +/// +/// 2. If `path` is `SeqSend`, `SeqRecv` or `SeqAck`, the `value` must be +/// `google.protobuf.UInt64Value` protobuf and hash is calculated as concatenation of the three +/// sequence numbers as described in [`generate`]. +/// +/// 3. Otherwise, the value is simply hashed. +pub fn verify( + prefix: &ibc::CommitmentPrefix, + proof: &ibc::CommitmentProofBytes, + root: &ibc::CommitmentRoot, + path: ibc::path::Path, + value: Option<&[u8]>, +) -> Result<(), VerifyError> { + verify_bytes(prefix.as_bytes(), proof.as_bytes(), root.as_bytes(), path, value) +} + +/// Verifies a proof for given entry or lack of entry. +/// +/// Like [`verify`] but takes slice arguments rather than IBC types. +pub fn verify_bytes( + prefix: &[u8], + proof: &[u8], + root: &[u8], + path: ibc::path::Path, + value: Option<&[u8]>, +) -> Result<(), VerifyError> { + cf_guest_upstream::proof::verify(prefix, proof, root, convert_old_path_to_new(path), value) +} + +fn convert_old_path_to_new(path: ibc::path::Path) -> ibc_core_host_types::path::Path { + match path { + ::ibc::core::ics24_host::Path::ClientType(_) => panic!("Not supported"), + ::ibc::core::ics24_host::Path::ClientState(e) => + ibc_core_host_types::path::Path::ClientState( + ibc_core_host_types::path::ClientStatePath( + ibc_core_host_types::identifiers::ClientId::from_str(e.0.as_str()).unwrap(), + ), + ), + ::ibc::core::ics24_host::Path::ClientConsensusState(e) => + ibc_core_host_types::path::Path::ClientConsensusState( + ibc_core_host_types::path::ClientConsensusStatePath { + client_id: ibc_core_host_types::identifiers::ClientId::from_str( + e.client_id.as_str(), + ) + .unwrap(), + revision_number: e.epoch, + revision_height: e.height, + }, + ), + ::ibc::core::ics24_host::Path::ClientConnections(e) => + ibc_core_host_types::path::Path::ClientConnection(ClientConnectionPath( + ibc_core_host_types::identifiers::ClientId::from_str(e.0.as_str()).unwrap(), + )), + ::ibc::core::ics24_host::Path::Connections(e) => + ibc_core_host_types::path::Path::Connection(ConnectionPath( + ibc_core_host_types::identifiers::ConnectionId::from_str(e.0.as_str()).unwrap(), + )), + ::ibc::core::ics24_host::Path::Ports(e) => ibc_core_host_types::path::Path::Ports( + PortPath(ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap()), + ), + ::ibc::core::ics24_host::Path::ChannelEnds(e) => + ibc_core_host_types::path::Path::ChannelEnd(ChannelEndPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::SeqSends(e) => + ibc_core_host_types::path::Path::SeqSend(SeqSendPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::SeqRecvs(e) => + ibc_core_host_types::path::Path::SeqRecv(SeqRecvPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::SeqAcks(e) => + ibc_core_host_types::path::Path::SeqAck(SeqAckPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::Commitments(e) => + ibc_core_host_types::path::Path::Commitment(CommitmentPath { + port_id: ibc_core_host_types::identifiers::PortId::from_str(e.port_id.as_str()) + .unwrap(), + channel_id: ibc_core_host_types::identifiers::ChannelId::new( + e.channel_id.sequence(), + ), + sequence: u64::from(e.sequence.0).into(), + }), + ::ibc::core::ics24_host::Path::Acks(e) => ibc_core_host_types::path::Path::Ack(AckPath { + port_id: ibc_core_host_types::identifiers::PortId::from_str(e.port_id.as_str()) + .unwrap(), + channel_id: ibc_core_host_types::identifiers::ChannelId::new(e.channel_id.sequence()), + sequence: u64::from(e.sequence.0).into(), + }), + ::ibc::core::ics24_host::Path::Receipts(e) => + ibc_core_host_types::path::Path::Receipt(ReceiptPath { + port_id: ibc_core_host_types::identifiers::PortId::from_str(e.port_id.as_str()) + .unwrap(), + channel_id: ibc_core_host_types::identifiers::ChannelId::new( + e.channel_id.sequence(), + ), + sequence: u64::from(e.sequence.0).into(), + }), + ::ibc::core::ics24_host::Path::Upgrade(path) => { + use ::ibc::core::ics24_host::ClientUpgradePath; + use ibc_core_host_types::path::UpgradeClientPath; + match path { + ClientUpgradePath::UpgradedClientState(height) => + UpgradeClientPath::UpgradedClientState(height), + ClientUpgradePath::UpgradedClientConsensusState(height) => + UpgradeClientPath::UpgradedClientConsensusState(height), + } + .into() + }, + ::ibc::core::ics24_host::Path::Outside(e) => panic!("Not supported {:?}", e), + } +} diff --git a/light-clients/cf-guest/src/proto.rs b/light-clients/cf-guest/src/proto.rs new file mode 100644 index 000000000..01e5cffca --- /dev/null +++ b/light-clients/cf-guest/src/proto.rs @@ -0,0 +1,136 @@ +use alloc::string::ToString; + +macro_rules! import_proto { + ($Msg:ident) => { + $crate::wrap!(cf_guest_upstream::proto::$Msg as $Msg); + $crate::wrap!(impl Default for $Msg); + + impl prost::Message for $Msg { + fn encode_raw(&self, buf: &mut B) { + prost_12::Message::encode_raw(&self.0, buf) + } + + fn merge_field( + &mut self, + tag: u32, + wire_type: prost::encoding::WireType, + buf: &mut B, + _ctx: prost::encoding::DecodeContext, + ) -> Result<(), prost::DecodeError> { + // SAFETY: The types are identical in prost 0.11 and prost.12. + let wire_type = unsafe { + core::mem::transmute(wire_type as u8) + }; + prost_12::Message::merge_field(&mut self.0, tag, wire_type, buf, Default::default()) + .map_err(|err| { + // SAFETY: The types are identical in prost 0.11 and prost.12. + unsafe { + core::mem::transmute(err) + } + }) + } + + fn encoded_len(&self) -> usize { + prost_12::Message::encoded_len(&self.0) + } + + fn clear(&mut self) { + prost_12::Message::clear(&mut self.0) + } + } + } +} + +import_proto!(ClientMessage); +import_proto!(ClientState); +import_proto!(ConsensusState); +import_proto!(Header); +import_proto!(Misbehaviour); +import_proto!(Signature); + +/// Error during decoding of a protocol message. +#[derive(Clone, PartialEq, Eq, derive_more::From)] +pub enum DecodeError { + /// Failed decoding the wire encoded protocol message. + /// + /// This means that the supplied bytes weren’t a valid protocol buffer or + /// they didn’t correspond to the expected message. + BadProto(alloc::string::String), + + /// Protocol message represents invalid state; see [`BadMessage`]. + #[from(ignore)] + BadMessage, + + /// When decoding an `Any` message, the type URL doesn’t equal the expected + /// one. + #[from(ignore)] + BadType, +} + +impl From for DecodeError { + fn from(err: cf_guest_upstream::DecodeError) -> Self { + match err { + cf_guest_upstream::DecodeError::BadProto(err) => Self::BadProto(err.to_string()), + cf_guest_upstream::DecodeError::BadMessage => Self::BadMessage, + cf_guest_upstream::DecodeError::BadType => Self::BadType, + } + } +} + +/// Error during validation of a protocol message. +/// +/// Typing in protocol messages is less descriptive than in Rust. It’s possible +/// to represent state in the protocol message which doesn’t correspond to +/// a valid state. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct BadMessage; + +impl From for BadMessage { + fn from(_: cf_guest_upstream::BadMessage) -> Self { + Self + } +} + +impl From for DecodeError { + fn from(_: BadMessage) -> Self { + Self::BadMessage + } +} + +impl core::fmt::Debug for DecodeError { + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + match self { + Self::BadProto(err) => err.fmt(fmtr), + Self::BadMessage => fmtr.write_str("BadMessage"), + Self::BadType => fmtr.write_str("BadType"), + } + } +} + +impl core::fmt::Display for DecodeError { + #[inline] + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Debug::fmt(self, fmtr) + } +} + +impl core::fmt::Display for BadMessage { + #[inline] + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Debug::fmt(self, fmtr) + } +} + +impl From
for ClientMessage { + #[inline] + fn from(msg: Header) -> Self { + Self(cf_guest_upstream::proto::ClientMessage::from(msg.0)) + } +} + +impl From for ClientMessage { + #[inline] + fn from(msg: Misbehaviour) -> Self { + Self(cf_guest_upstream::proto::ClientMessage::from(msg.0)) + } +} diff --git a/light-clients/cf-guest/src/snapshots/cf_guest__proto__client_state.snap b/light-clients/cf-guest/src/snapshots/cf_guest__proto__client_state.snap new file mode 100644 index 000000000..940735f51 --- /dev/null +++ b/light-clients/cf-guest/src/snapshots/cf_guest__proto__client_state.snap @@ -0,0 +1,85 @@ +--- +source: common/cf-guest/src/proto.rs +expression: any.value +--- +[ + 10, + 32, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 0, + 0, + 0, + 24, + 16, + 8, + 24, + 128, + 128, + 136, + 186, + 144, + 173, + 205, + 4, + 34, + 32, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, + 0, + 0, + 0, + 11, +] diff --git a/light-clients/cf-guest/src/snapshots/cf_guest__proto__consensus_state.snap b/light-clients/cf-guest/src/snapshots/cf_guest__proto__consensus_state.snap new file mode 100644 index 000000000..84dbb8b5a --- /dev/null +++ b/light-clients/cf-guest/src/snapshots/cf_guest__proto__consensus_state.snap @@ -0,0 +1,42 @@ +--- +source: common/cf-guest/src/proto.rs +expression: any.value +--- +[ + 10, + 32, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 0, + 0, + 0, + 42, + 16, + 1, +] diff --git a/light-clients/cf-guest/src/snapshots/cf_guest__proto__header.snap b/light-clients/cf-guest/src/snapshots/cf_guest__proto__header.snap new file mode 100644 index 000000000..c6cd140b2 --- /dev/null +++ b/light-clients/cf-guest/src/snapshots/cf_guest__proto__header.snap @@ -0,0 +1,64 @@ +--- +source: common/cf-guest/src/proto.rs +expression: any.value +--- +[ + 10, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + 10, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 26, + 10, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, +] diff --git a/light-clients/cf-guest/src/snapshots/cf_guest__proto__misbehaviour.snap b/light-clients/cf-guest/src/snapshots/cf_guest__proto__misbehaviour.snap new file mode 100644 index 000000000..21c3b91ba --- /dev/null +++ b/light-clients/cf-guest/src/snapshots/cf_guest__proto__misbehaviour.snap @@ -0,0 +1,126 @@ +--- +source: common/cf-guest/src/proto.rs +expression: any.value +--- +[ + 10, + 58, + 10, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + 10, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 26, + 10, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 18, + 58, + 10, + 32, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 18, + 10, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 26, + 10, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, +] diff --git a/light-clients/cf-guest/src/snapshots/cf_guest__proto__signature.snap b/light-clients/cf-guest/src/snapshots/cf_guest__proto__signature.snap new file mode 100644 index 000000000..175069b18 --- /dev/null +++ b/light-clients/cf-guest/src/snapshots/cf_guest__proto__signature.snap @@ -0,0 +1,74 @@ +--- +source: common/cf-guest/src/proto.rs +expression: any.value +--- +[ + 8, + 1, + 18, + 64, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, +] diff --git a/light-clients/ics07-guest-cw/Cargo.toml b/light-clients/ics07-guest-cw/Cargo.toml new file mode 100644 index 000000000..698be3483 --- /dev/null +++ b/light-clients/ics07-guest-cw/Cargo.toml @@ -0,0 +1,92 @@ +[package] +name = "ics07-guest-cw" +version = "0.1.0" +authors = ["Composable, Strangelove Developers"] +edition = "2021" + +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", +] + +[lib] +crate-type = ["cdylib", "rlib"] + +[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-schema = "1.1.3" +cosmwasm-std = "1.1.3" +schemars = "0.8.10" +serde = { version = "1.0.145", default-features = false, features = ["derive"] } +thiserror = { version = "1.0.31" } +sha2 = "0.10" +sha3 = "0.10" +derive_more = "0.99.17" + +# ed25519 = { version = "1.5", default-features = false } +# ed25519-consensus = { version = "2", optional = true, default-features = false } +ibc = { path = "../../ibc/modules", default-features = false } +ibc-derive = { path = "../../ibc/derive", default-features = false } +ibc-proto = { path = "../../ibc/proto", default-features = false, features = ["json-schema"] } +ics23 = { git = "https://github.com/cosmos/ics23", rev = "74ce807b7be39a7e0afb4e2efb8e28a57965f57b", default-features = false } +# ics07-tendermint = { path = "../ics07-tendermint", default-features = false } +cf-guest = { path = "../cf-guest", default-features = false } +ics08-wasm = { path = "../ics08-wasm", default-features = false, features = ["cosmwasm"] } +prost = { version = "0.11", default-features = false } +ed25519-dalek = { version = "2.1.1", default-features = false, features = ["pkcs8"] } +byteorder = { version = "1.3.2", default-features = false } +digest = { version = "0.10.3", default-features = false } +hex = "0.4.3" +guestchain = { git = "https://github.com/composableFi/emulated-light-client/" , default-features = false } +borsh = { version = "0.10.3", default-features = false } + + +#tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } # cannot be defined as optional in workspace +#tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +#tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } + +[dev-dependencies] +cw-multi-test = "0.15.1" +hex = "0.4.3" +hyperspace-primitives = { path = "../../hyperspace/primitives", features = ["testing"] } +pallet-ibc = { path = "../../contracts/pallet-ibc" } +serde-json-wasm = { version = "0.5.0", default-features = false } +serde_json = { version = "1.0.93", default-features = false } +# tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } + +[features] +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces"] +# use library feature to disable all instantiate/execute/query exports +library = [] +default = [] +# default = ["rust-crypto"] +# rust-crypto = ["ed25519-consensus"] +std = [ + "byteorder/std", + "digest/std", + "ed25519-dalek/std", + "hex/std", + "ibc/std", + "ibc-proto/std", + # "ics07-tendermint/std", + "ics08-wasm/std", + "ics23/std", + "pallet-ibc/std", + "prost/std", + "serde/std", + "serde_json/std", + "sha2/std", + "sha3/std", + # "tendermint/std" +] +test = [ + "std" +] diff --git a/light-clients/ics07-guest-cw/src/context.rs b/light-clients/ics07-guest-cw/src/context.rs new file mode 100644 index 000000000..b09159058 --- /dev/null +++ b/light-clients/ics07-guest-cw/src/context.rs @@ -0,0 +1,152 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + ics23::{ + ClientStates, ConsensusStates, ReadonlyClientStates, ReadonlyConsensusStates, + ReadonlyProcessedStates, + }, + ContractError, +}; +use cf_guest::{ClientState, ConsensusState}; +use cosmwasm_std::{DepsMut, Env, Storage}; +use ibc::{ + core::{ics02_client::error::Error, ics26_routing::context::ReaderContext}, + Height, +}; +use std::{fmt, fmt::Debug}; + +pub struct Context<'a> { + pub deps: DepsMut<'a>, + pub env: Env, +} + +impl<'a> PartialEq for Context<'a> { + fn eq(&self, _other: &Self) -> bool { + true + } +} + +impl<'a> Eq for Context<'a> {} + +impl<'a> Debug for Context<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Context {{ deps: DepsMut }}") + } +} + +impl<'a> Clone for Context<'a> { + fn clone(&self) -> Self { + panic!("Context is not cloneable") + } +} + +impl<'a> Context<'a> { + pub fn new(deps: DepsMut<'a>, env: Env) -> Self { + Self { deps, env } + } + + pub fn log(&self, msg: &str) { + self.deps.api.debug(msg) + } + + pub fn storage(&self) -> &dyn Storage { + self.deps.storage + } + + pub fn storage_mut(&mut self) -> &mut dyn Storage { + self.deps.storage + } +} + +impl<'a> Context<'a> { + pub fn processed_timestamp(&self, height: Height) -> Result { + let processed_state = ReadonlyProcessedStates::new(self.storage()); + match processed_state.get_processed_time(height, &mut Vec::new()) { + Some(time) => Ok(time), + None => Err(Error::implementation_specific( + "problem getting processed timestamp".to_string(), + )), + } + } + + pub fn processed_height(&self, height: Height) -> Result { + let processed_state = ReadonlyProcessedStates::new(self.storage()); + match processed_state.get_processed_height(height, &mut Vec::new()) { + Some(p_height) => Ok(p_height), + None => + Err(Error::implementation_specific("problem getting processed height".to_string())), + } + } + + pub fn consensus_state_prefixed( + &self, + height: Height, + prefix: &[u8], + ) -> Result { + let bytes = ReadonlyConsensusStates::new(self.storage()) + .get_prefixed(height, prefix) + .ok_or_else(|| { + ContractError::Tendermint(format!( + "no consensus state found for height {height} and prefix {prefix:?}", + )) + })?; + Context::decode_consensus_state(&bytes).map_err(|e| { + ContractError::Tendermint(format!("error decoding consensus state: {e:?}")) + }) + } + + pub fn store_consensus_state_prefixed( + &mut self, + height: Height, + consensus_state: ConsensusState, + prefix: &[u8], + ) { + let encoded = Context::encode_consensus_state(consensus_state); + let mut consensus_states = ConsensusStates::new(self.storage_mut()); + consensus_states.insert_prefixed(height, encoded, prefix); + } + + pub fn client_state_prefixed( + &self, + prefix: &[u8], + ) -> Result, ContractError> { + let bytes = + ReadonlyClientStates::new(self.storage()).get_prefixed(prefix).ok_or_else(|| { + ContractError::Tendermint(format!("no client state found for prefix {prefix:?}",)) + })?; + Context::decode_client_state(&bytes) + .map_err(|e| ContractError::Tendermint(format!("error decoding client state: {e:?}"))) + } + + pub fn store_client_state_prefixed( + &mut self, + client_state: ClientState, + prefix: &[u8], + ) -> Result<(), ContractError> { + let client_states = ReadonlyClientStates::new(self.storage()); + let data = client_states.get_prefixed(prefix).ok_or_else(|| { + ContractError::Tendermint("no client state found for prefix".to_string()) + })?; + let encoded = Context::encode_client_state(client_state, data).map_err(|e| { + ContractError::Tendermint(format!("error encoding client state: {e:?}")) + })?; + let mut client_states = ClientStates::new(self.storage_mut()); + client_states.insert_prefixed(encoded, prefix); + Ok(()) + } +} + +impl<'a> ReaderContext for Context<'a> {} diff --git a/light-clients/ics07-guest-cw/src/contract.rs b/light-clients/ics07-guest-cw/src/contract.rs new file mode 100644 index 000000000..f6c148964 --- /dev/null +++ b/light-clients/ics07-guest-cw/src/contract.rs @@ -0,0 +1,287 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ + context::Context, + error::ContractError, + helpers::prune_oldest_consensus_state, + ics23::ReadonlyProcessedStates, + msg::{ + CheckForMisbehaviourMsg, ContractResult, ExecuteMsg, ExportMetadataMsg, InstantiateMsg, + QueryMsg, QueryResponse, StatusMsg, UpdateStateMsg, UpdateStateOnMisbehaviourMsg, + VerifyClientMessage, VerifyMembershipMsg, VerifyNonMembershipMsg, + VerifyUpgradeAndUpdateStateMsg, + }, + state::{get_client_state, get_consensus_state}, +}; +use cf_guest::{client_def::GuestClient, proof::verify}; +#[cfg(not(feature = "library"))] +use cosmwasm_std::entry_point; +use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use ibc::core::{ + ics02_client::{ + client_consensus::ConsensusState as _, + client_def::{ClientDef, ConsensusUpdateResult}, + client_state::ClientState as _, + context::{ClientKeeper, ClientReader}, + }, + ics23_commitment::commitment::CommitmentPrefix, + ics24_host::identifier::ClientId, +}; +use ics08_wasm::SUBJECT_PREFIX; +use std::str::FromStr; + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn instantiate( + deps: DepsMut, + env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> Result { + let _client = GuestClient::::default(); + let mut ctx = Context::new(deps, env); + let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid"); + let client_state = ctx + .client_state(&client_id) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let latest_height = ibc::Height::new(1, client_state.latest_height.into()); + ctx.store_update_height(client_id.clone(), latest_height, ctx.host_height()) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + ctx.store_update_time(client_id, latest_height, ctx.host_timestamp()) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + + Ok(Response::default()) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn execute( + deps: DepsMut, + env: Env, + _info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + let client = GuestClient::::default(); + let mut ctx = Context::new(deps, env); + let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid"); + let data = process_message(msg, client, &mut ctx, client_id)?; + let mut response = Response::default(); + response.data = Some(data); + Ok(response) +} + +fn process_message( + msg: ExecuteMsg, + client: GuestClient, + ctx: &mut Context, + client_id: ClientId, +) -> Result { + //log!(ctx, "process_message: {:?}", msg); + let result = match msg { + ExecuteMsg::VerifyMembership(msg) => { + let client_state = ctx + .client_state(&client_id) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let msg = VerifyMembershipMsg::try_from(msg)?; + // crate::helpers::verify_delay_passed( + // ctx, + // msg.height, + // msg.delay_time_period, + // msg.delay_block_period, + // ) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let consensus_state = ctx + .consensus_state(&client_id, msg.height) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // TODO(blas) + verify( + &CommitmentPrefix::default(), + &msg.proof, + &consensus_state.root(), + msg.path, + Some(msg.value.as_ref()), + ) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + Ok(()).map(|_| to_binary(&ContractResult::success())) + }, + ExecuteMsg::VerifyNonMembership(msg) => { + let client_state = ctx + .client_state(&client_id) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let msg = VerifyNonMembershipMsg::try_from(msg)?; + // crate::helpers::verify_delay_passed( + // ctx, + // msg.height, + // msg.delay_time_period, + // msg.delay_block_period, + // ) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let consensus_state = ctx + .consensus_state(&client_id, msg.height) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + + verify( + &CommitmentPrefix::default(), + &msg.proof, + &consensus_state.root(), + msg.path, + None, + ) + .map_err(|e| ContractError::Tendermint(e.to_string())) + .map(|_| to_binary(&ContractResult::success())) + }, + ExecuteMsg::VerifyClientMessage(msg) => { + let client_state = ctx + .client_state(&client_id) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let msg = VerifyClientMessage::try_from(msg)?; + client + .verify_client_message(ctx, client_id, client_state, msg.client_message) + .map_err(|e| ContractError::Tendermint(format!("{e:?}"))) + .map(|_| to_binary(&ContractResult::success())) + }, + ExecuteMsg::CheckForMisbehaviour(msg) => { + let client_state = ctx + .client_state(&client_id) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let msg = CheckForMisbehaviourMsg::try_from(msg)?; + client + .check_for_misbehaviour(ctx, client_id, client_state, msg.client_message) + .map_err(|e| ContractError::Tendermint(e.to_string())) + .map(|result| to_binary(&ContractResult::success().misbehaviour(result))) + }, + // ExecuteMsg::UpdateStateOnMisbehaviour(msg_raw) => { + // let client_state = ctx + // .client_state(&client_id) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // let msg = UpdateStateOnMisbehaviourMsg::try_from(msg_raw)?; + // client + // .update_state_on_misbehaviour(client_state, msg.client_message) + // .map_err(|e| ContractError::Tendermint(e.to_string())) + // .and_then(|cs| { + // ctx.store_client_state(client_id, cs) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // Ok(to_binary(&ContractResult::success())) + // }) + // }, + ExecuteMsg::UpdateState(msg_raw) => { + let client_state = ctx + .client_state(&client_id) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + let msg = UpdateStateMsg::try_from(msg_raw)?; + let latest_revision_height = client_state.latest_height().revision_height; + prune_oldest_consensus_state(ctx, &client_state, ctx.host_timestamp().nanoseconds()); + client + .update_state(ctx, client_id.clone(), client_state, msg.client_message) + .map_err(|e| ContractError::Tendermint(e.to_string())) + .and_then(|(cs, cu)| { + let height = cs.latest_height(); + match cu { + ConsensusUpdateResult::Single(cs) => { + ctx.store_consensus_state(client_id.clone(), height, cs) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + }, + ConsensusUpdateResult::Batch(css) => + for (height, cs) in css { + ctx.store_consensus_state(client_id.clone(), height, cs) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + }, + } + if u64::from(cs.latest_height) > latest_revision_height { + ctx.store_client_state(client_id, cs) + .map_err(|e| ContractError::Tendermint(e.to_string()))?; + } + Ok(to_binary(&ContractResult::success())) + }) + }, + // ExecuteMsg::CheckSubstituteAndUpdateState(_msg) => + // check_substitute_and_update_state::(ctx) + // .map_err(|e| ContractError::Tendermint(e.to_string())) + // .and_then(|(cs, cu)| { + // let height = cs.latest_height(); + // ctx.store_consensus_state_prefixed(height, cu, SUBJECT_PREFIX); + // ctx.store_client_state_prefixed(cs, SUBJECT_PREFIX) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // Ok(to_binary(&ContractResult::success())) + // }), + // ExecuteMsg::VerifyUpgradeAndUpdateState(msg) => { + // let old_client_state = ctx + // .client_state(&client_id) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // let msg: VerifyUpgradeAndUpdateStateMsg = + // VerifyUpgradeAndUpdateStateMsg::try_from(msg)?; + // verify_upgrade_and_update_state::( + // ctx, + // client_id.clone(), + // old_client_state, + // msg.upgrade_client_state, + // msg.upgrade_consensus_state, + // msg.proof_upgrade_client, + // msg.proof_upgrade_consensus_state, + // ) + // .map_err(|e| ContractError::Tendermint(e.to_string())) + // .and_then(|(cs, cu)| { + // let height = cs.latest_height(); + // ctx.store_consensus_state(client_id.clone(), height, cu) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // ctx.store_client_state(client_id, cs) + // .map_err(|e| ContractError::Tendermint(e.to_string()))?; + // Ok(to_binary(&ContractResult::success())) + // }) + // }, + _ => unimplemented!("none of the other messages are implemented at the moment"), + }; + Ok(result??) +} + +#[cfg_attr(not(feature = "library"), entry_point)] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { + let client_id = ClientId::from_str("08-wasm-0").expect("client id is valid"); + //deps.api.debug("In query"); + match msg { + QueryMsg::ClientTypeMsg(_) => unimplemented!("ClientTypeMsg"), + QueryMsg::GetLatestHeightsMsg(_) => unimplemented!("GetLatestHeightsMsg"), + QueryMsg::ExportMetadata(ExportMetadataMsg {}) => { + let ro_proceeded_state = ReadonlyProcessedStates::new(deps.storage); + to_binary(&QueryResponse::genesis_metadata(ro_proceeded_state.get_metadata())) + }, + QueryMsg::Status(StatusMsg {}) => { + let client_state = match get_client_state::(deps) { + Ok(state) => state, + Err(_) => return to_binary(&QueryResponse::status("Unknown".to_string())), + }; + + if client_state.frozen_height().is_some() { + return to_binary(&QueryResponse::status("Frozen".to_string())); + } + + let height = client_state.latest_height; + let height = ibc::Height::new(1, height.into()); + let consensus_state = match get_consensus_state(deps, &client_id, height) { + Ok(state) => state, + Err(e) => panic!("This is error {:?}", e), /* return to_binary(& + * QueryResponse::status("Expired". + * to_string())), */ + }; + + let last_update = consensus_state.timestamp_ns.get(); + let trusting_period = client_state.trusting_period_ns; + let now = env.block.time.nanos(); + if last_update + trusting_period < now { + return to_binary(&QueryResponse::status("Expired".to_string())) + } + to_binary(&QueryResponse::status("Active".to_string())) + }, + } +} diff --git a/light-clients/ics07-guest-cw/src/crypto.rs b/light-clients/ics07-guest-cw/src/crypto.rs new file mode 100644 index 000000000..99e3098f0 --- /dev/null +++ b/light-clients/ics07-guest-cw/src/crypto.rs @@ -0,0 +1,115 @@ +use borsh::maybestd::io; + +/// Ed25519 public key (a.k.a. verifying key). +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct PubKey(ed25519_dalek::VerifyingKey); + +impl guestchain::PubKey for PubKey { + type Signature = Signature; + + fn to_vec(&self) -> Vec { + self.0.as_bytes().to_vec() + } + fn from_bytes(bytes: &[u8]) -> Result { + bytes.try_into().map(Self).map_err(|_| guestchain::BadFormat) + } + + fn as_bytes(&self) -> alloc::borrow::Cow<'_, [u8]> { + todo!() + } +} + +impl borsh::BorshSerialize for PubKey { + fn serialize(&self, wr: &mut W) -> io::Result<()> { + wr.write_all(self.0.as_bytes()) + } +} + +impl borsh::BorshDeserialize for PubKey { + fn deserialize_reader(rd: &mut R) -> io::Result { + let mut bytes = ed25519_dalek::pkcs8::PublicKeyBytes([0; 32]); + rd.read_exact(&mut bytes.0[..])?; + ed25519_dalek::VerifyingKey::try_from(bytes) + .map(Self) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "malformed Ed25519 public key")) + } +} + +impl PartialOrd for PubKey { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for PubKey { + fn cmp(&self, rhs: &Self) -> core::cmp::Ordering { + self.0.as_bytes().cmp(rhs.0.as_bytes()) + } +} + +/// Ed25519 signature. +#[derive(Clone, PartialEq, Eq, Debug)] +#[repr(transparent)] +pub struct Signature(ed25519_dalek::Signature); + +impl guestchain::Signature for Signature { + fn to_vec(&self) -> Vec { + self.0.to_vec() + } + fn from_bytes(bytes: &[u8]) -> Result { + ed25519_dalek::Signature::from_slice(bytes) + .map(Self) + .map_err(|_| guestchain::BadFormat) + } + + fn as_bytes(&self) -> alloc::borrow::Cow<'_, [u8]> { + todo!() + } +} + +impl borsh::BorshSerialize for Signature { + fn serialize(&self, wr: &mut W) -> io::Result<()> { + wr.write_all(self.0.r_bytes())?; + wr.write_all(self.0.s_bytes())?; + Ok(()) + } +} + +impl borsh::BorshDeserialize for Signature { + fn deserialize_reader(rd: &mut R) -> io::Result { + let mut buf = [0; 64]; + rd.read_exact(&mut buf[..])?; + Ok(Self(ed25519_dalek::Signature::from_bytes(&buf))) + } +} + +impl core::hash::Hash for Signature { + fn hash(&self, hasher: &mut H) { + hasher.write(self.0.r_bytes()); + hasher.write(self.0.s_bytes()); + } +} + +impl PartialOrd for Signature { + fn partial_cmp(&self, rhs: &Self) -> Option { + Some(self.cmp(rhs)) + } +} + +impl Ord for Signature { + fn cmp(&self, rhs: &Self) -> core::cmp::Ordering { + let lhs = (self.0.r_bytes(), self.0.s_bytes()); + let rhs = (rhs.0.r_bytes(), rhs.0.s_bytes()); + lhs.cmp(&rhs) + } +} + +/// Verifier for Ed25519 signatures using ed25519-dalek implementation. +pub(crate) struct Verifier; + +impl guestchain::Verifier for Verifier { + fn verify(&self, message: &[u8], pubkey: &PubKey, signature: &Signature) -> bool { + pubkey.0.verify_strict(message, &signature.0).is_ok() + } +} diff --git a/light-clients/ics07-guest-cw/src/msg.rs b/light-clients/ics07-guest-cw/src/msg.rs new file mode 100644 index 000000000..3421d426e --- /dev/null +++ b/light-clients/ics07-guest-cw/src/msg.rs @@ -0,0 +1,375 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{ics23::FakeInner, Bytes, ContractError}; +use core::{str::FromStr, time::Duration}; +use cosmwasm_schema::cw_serde; +use ibc::{ + core::{ + ics02_client::trust_threshold::TrustThreshold, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes}, + ics24_host::Path, + }, + protobuf::Protobuf, + Height, +}; +use ibc_proto::{google::protobuf::Any, ibc::core::client::v1::Height as HeightRaw}; + +use cf_guest::{ClientMessage, ClientState, Header, Misbehaviour}; + +use ics08_wasm::{ + client_message::Header as WasmHeader, client_state::ClientState as WasmClientState, + consensus_state::ConsensusState as WasmConsensusState, +}; +use prost::Message; +use serde::{Deserializer, Serializer}; + +struct Base64; + +impl Base64 { + pub fn serialize(v: &[u8], serializer: S) -> Result { + ibc_proto::base64::serialize(v, serializer) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { + ibc_proto::base64::deserialize(deserializer) + } +} + +#[cw_serde] +pub struct GenesisMetadata { + pub key: Vec, + pub value: Vec, +} + +#[cw_serde] +pub struct QueryResponse { + pub status: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub genesis_metadata: Option>, +} + +impl QueryResponse { + pub fn status(status: String) -> Self { + Self { status, genesis_metadata: None } + } + + pub fn genesis_metadata(genesis_metadata: Option>) -> Self { + Self { status: "".to_string(), genesis_metadata } + } +} + +#[cw_serde] +pub struct ContractResult { + pub is_valid: bool, + pub error_msg: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub data: Option>, + pub found_misbehaviour: bool, +} + +impl ContractResult { + pub fn success() -> Self { + Self { is_valid: true, error_msg: "".to_string(), data: None, found_misbehaviour: false } + } + + pub fn error(msg: String) -> Self { + Self { is_valid: false, error_msg: msg, data: None, found_misbehaviour: false } + } + + pub fn misbehaviour(mut self, found: bool) -> Self { + self.found_misbehaviour = found; + self + } + + pub fn data(mut self, data: Vec) -> Self { + self.data = Some(data); + self + } +} + +#[cw_serde] +pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + VerifyMembership(VerifyMembershipMsgRaw), + VerifyNonMembership(VerifyNonMembershipMsgRaw), + VerifyClientMessage(VerifyClientMessageRaw), + CheckForMisbehaviour(CheckForMisbehaviourMsgRaw), + UpdateStateOnMisbehaviour(UpdateStateOnMisbehaviourMsgRaw), + UpdateState(UpdateStateMsgRaw), + CheckSubstituteAndUpdateState(CheckSubstituteAndUpdateStateMsg), + VerifyUpgradeAndUpdateState(VerifyUpgradeAndUpdateStateMsgRaw), +} + +#[cw_serde] +pub enum QueryMsg { + ClientTypeMsg(ClientTypeMsg), + GetLatestHeightsMsg(GetLatestHeightsMsg), + ExportMetadata(ExportMetadataMsg), + Status(StatusMsg), +} + +#[cw_serde] +pub struct ClientTypeMsg {} + +#[cw_serde] +pub struct GetLatestHeightsMsg {} + +#[cw_serde] +pub struct StatusMsg {} + +#[cw_serde] +pub struct ExportMetadataMsg {} + +#[cw_serde] +pub struct MerklePath { + pub key_path: Vec, +} + +#[cw_serde] +pub struct VerifyMembershipMsgRaw { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof: Bytes, + pub path: MerklePath, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub value: Bytes, + pub height: HeightRaw, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +pub struct VerifyMembershipMsg { + pub prefix: CommitmentPrefix, + pub proof: CommitmentProofBytes, + pub path: Path, + pub value: Vec, + pub height: Height, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +impl TryFrom for VerifyMembershipMsg { + type Error = ContractError; + + fn try_from(mut raw: VerifyMembershipMsgRaw) -> Result { + let proof = CommitmentProofBytes::try_from(raw.proof)?; + let prefix = raw.path.key_path.remove(0).into_bytes(); + let path_str = raw.path.key_path.join(""); + let path = Path::from_str(&path_str)?; + let height = Height::from(raw.height); + Ok(Self { + proof, + path, + value: raw.value, + height, + prefix: CommitmentPrefix::try_from(prefix)?, + delay_block_period: raw.delay_block_period, + delay_time_period: raw.delay_time_period, + }) + } +} + +#[cw_serde] +pub struct VerifyNonMembershipMsgRaw { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof: Bytes, + pub path: MerklePath, + pub height: HeightRaw, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +pub struct VerifyNonMembershipMsg { + pub prefix: CommitmentPrefix, + pub proof: CommitmentProofBytes, + pub path: Path, + pub height: Height, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +impl TryFrom for VerifyNonMembershipMsg { + type Error = ContractError; + + fn try_from(mut raw: VerifyNonMembershipMsgRaw) -> Result { + let proof = CommitmentProofBytes::try_from(raw.proof)?; + let prefix = raw.path.key_path.remove(0).into_bytes(); + let path_str = raw.path.key_path.join(""); + let path = Path::from_str(&path_str)?; + let height = Height::from(raw.height); + Ok(Self { + proof, + path, + height, + prefix: CommitmentPrefix::try_from(prefix)?, + delay_block_period: raw.delay_block_period, + delay_time_period: raw.delay_time_period, + }) + } +} + +#[cw_serde] +pub struct WasmMisbehaviour { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub data: Bytes, +} + +#[cw_serde] +pub enum ClientMessageRaw { + Header(WasmHeader), + Misbehaviour(WasmMisbehaviour), +} + +#[cw_serde] +pub struct VerifyClientMessageRaw { + pub client_message: ClientMessageRaw, +} + +pub struct VerifyClientMessage { + pub client_message: ClientMessage, +} + +impl TryFrom for VerifyClientMessage { + type Error = ContractError; + + fn try_from(raw: VerifyClientMessageRaw) -> Result { + let client_message = Self::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +impl VerifyClientMessage { + fn decode_client_message( + raw: ClientMessageRaw, + ) -> Result, ContractError> { + let client_message = match raw { + ClientMessageRaw::Header(header) => { + let any = Any::decode(&mut header.data.as_slice())?; + ClientMessage::decode_vec(&any.value)? + }, + ClientMessageRaw::Misbehaviour(misbehaviour) => { + let any = Any::decode(&mut misbehaviour.data.as_slice())?; + ClientMessage::decode_vec(&any.value)? + }, + }; + Ok(client_message) + } +} + +#[cw_serde] +pub struct CheckForMisbehaviourMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct CheckForMisbehaviourMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for CheckForMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: CheckForMisbehaviourMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct UpdateStateOnMisbehaviourMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct UpdateStateOnMisbehaviourMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for UpdateStateOnMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateOnMisbehaviourMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct UpdateStateMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct UpdateStateMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for UpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct CheckSubstituteAndUpdateStateMsg {} + +#[cw_serde] +pub struct VerifyUpgradeAndUpdateStateMsgRaw { + pub upgrade_client_state: WasmClientState, + pub upgrade_consensus_state: WasmConsensusState, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof_upgrade_client: Bytes, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof_upgrade_consensus_state: Bytes, +} + +pub struct VerifyUpgradeAndUpdateStateMsg { + pub upgrade_client_state: WasmClientState, + pub upgrade_consensus_state: WasmConsensusState, + pub proof_upgrade_client: CommitmentProofBytes, + pub proof_upgrade_consensus_state: CommitmentProofBytes, +} + +impl TryFrom for VerifyUpgradeAndUpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: VerifyUpgradeAndUpdateStateMsgRaw) -> Result { + let any = Any::decode(&mut raw.upgrade_client_state.data.as_slice())?; + let upgrade_client_state: ClientState = + ClientState::decode_vec(&any.value)?; + if upgrade_client_state.is_frozen { + return ibc::prelude::Err(ContractError::Tendermint( + "Upgrade client state not zeroed".to_string(), + )) + } + + Ok(VerifyUpgradeAndUpdateStateMsg { + upgrade_client_state: raw.upgrade_client_state, + upgrade_consensus_state: raw.upgrade_consensus_state, + proof_upgrade_client: CommitmentProofBytes::try_from(raw.proof_upgrade_client)?, + proof_upgrade_consensus_state: CommitmentProofBytes::try_from( + raw.proof_upgrade_consensus_state, + )?, + }) + } +} diff --git a/light-clients/ics07-tendermint-cw/Cargo.toml b/light-clients/ics07-tendermint-cw/Cargo.toml index a5af32089..8414903db 100644 --- a/light-clients/ics07-tendermint-cw/Cargo.toml +++ b/light-clients/ics07-tendermint-cw/Cargo.toml @@ -43,9 +43,9 @@ ed25519-zebra = { version = "3.1.0", default-features = false } byteorder = { version = "1.3.2", default-features = false } digest = { version = "0.10.3", default-features = false } hex = "0.4.3" -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } # cannot be defined as optional in workspace -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } # cannot be defined as optional in workspace +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [dev-dependencies] cw-multi-test = "0.15.1" @@ -54,7 +54,7 @@ hyperspace-primitives = { path = "../../hyperspace/primitives", features = ["tes pallet-ibc = { path = "../../contracts/pallet-ibc" } serde-json-wasm = { version = "0.5.0", default-features = false } serde_json = { version = "1.0.93", default-features = false } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [features] # for more explicit tests, cargo test --features=backtraces diff --git a/light-clients/ics07-tendermint-cw/src/client.rs b/light-clients/ics07-tendermint-cw/src/client.rs index c5d192107..4dde0d591 100644 --- a/light-clients/ics07-tendermint-cw/src/client.rs +++ b/light-clients/ics07-tendermint-cw/src/client.rs @@ -239,7 +239,7 @@ impl<'a, H: HostFunctionsProvider + 'static> ClientKeeper for Context<'a, H> { timestamp: Timestamp, ) -> Result<(), Error> { let mut processed_state = ProcessedStates::new(self.storage_mut()); - processed_state.set_processed_time(height, timestamp.nanoseconds(), &mut Vec::new()); + processed_state.set_processed_time(height, timestamp.nanoseconds(), ""); Ok(()) } @@ -251,8 +251,8 @@ impl<'a, H: HostFunctionsProvider + 'static> ClientKeeper for Context<'a, H> { host_height: Height, ) -> Result<(), Error> { let mut processed_state = ProcessedStates::new(self.storage_mut()); - processed_state.set_processed_height(height, host_height.revision_height, &mut Vec::new()); - processed_state.set_iteration_key(height, &mut Vec::new()); + processed_state.set_processed_height(height, host_height.revision_height, ""); + processed_state.set_iteration_key(height, ""); Ok(()) } diff --git a/light-clients/ics07-tendermint-cw/src/context.rs b/light-clients/ics07-tendermint-cw/src/context.rs index 7fecd9ba1..4e53bfb56 100644 --- a/light-clients/ics07-tendermint-cw/src/context.rs +++ b/light-clients/ics07-tendermint-cw/src/context.rs @@ -103,7 +103,7 @@ where { pub fn processed_timestamp(&self, height: Height) -> Result { let processed_state = ReadonlyProcessedStates::new(self.storage()); - match processed_state.get_processed_time(height, &mut Vec::new()) { + match processed_state.get_processed_time(height, "") { Some(time) => Ok(time), None => Err(Error::implementation_specific( "problem getting processed timestamp".to_string(), @@ -113,7 +113,7 @@ where pub fn processed_height(&self, height: Height) -> Result { let processed_state = ReadonlyProcessedStates::new(self.storage()); - match processed_state.get_processed_height(height, &mut Vec::new()) { + match processed_state.get_processed_height(height, "") { Some(p_height) => Ok(p_height), None => Err(Error::implementation_specific("problem getting processed height".to_string())), diff --git a/light-clients/ics07-tendermint-cw/src/helpers.rs b/light-clients/ics07-tendermint-cw/src/helpers.rs index ae353146a..375c7bcc9 100644 --- a/light-clients/ics07-tendermint-cw/src/helpers.rs +++ b/light-clients/ics07-tendermint-cw/src/helpers.rs @@ -42,7 +42,7 @@ use ics07_tendermint::{ HostFunctionsProvider, }; -use ics08_wasm::{SUBJECT_PREFIX, SUBSTITUTE_PREFIX}; +use ics08_wasm::{SUBJECT_PREFIX, SUBJECT_PREFIX_STR, SUBSTITUTE_PREFIX, SUBSTITUTE_PREFIX_STR}; /// CwTemplateContract is a wrapper around Addr that provides a lot of helpers /// for working with this. @@ -194,26 +194,15 @@ pub fn check_substitute_and_update_state( })?; let mut process_states = ProcessedStates::new(ctx.storage_mut()); - let substitute_processed_time = process_states - .get_processed_time(height, &mut SUBSTITUTE_PREFIX.to_vec()) - .unwrap(); - let substitute_processed_height = process_states - .get_processed_height(height, &mut SUBSTITUTE_PREFIX.to_vec()) - .unwrap(); - let substitute_iteration_key = process_states - .get_iteration_key(height, &mut SUBSTITUTE_PREFIX.to_vec()) - .unwrap(); - process_states.set_processed_time( - height, - substitute_processed_time, - &mut SUBJECT_PREFIX.to_vec(), - ); - process_states.set_processed_height( - height, - substitute_processed_height, - &mut SUBJECT_PREFIX.to_vec(), - ); - process_states.set_iteration_key(substitute_iteration_key, &mut SUBJECT_PREFIX.to_vec()); + let substitute_processed_time = + process_states.get_processed_time(height, SUBSTITUTE_PREFIX_STR).unwrap(); + let substitute_processed_height = + process_states.get_processed_height(height, SUBSTITUTE_PREFIX_STR).unwrap(); + let substitute_iteration_key = + process_states.get_iteration_key(height, SUBSTITUTE_PREFIX_STR).unwrap(); + process_states.set_processed_time(height, substitute_processed_time, SUBJECT_PREFIX_STR); + process_states.set_processed_height(height, substitute_processed_height, SUBJECT_PREFIX_STR); + process_states.set_iteration_key(substitute_iteration_key, SUBJECT_PREFIX_STR); subject_client_state.latest_height = substitute_client_state.latest_height; subject_client_state.chain_id = substitute_client_state.chain_id; @@ -231,8 +220,7 @@ pub fn prune_oldest_consensus_state( let mut processed_states = ProcessedStates::new(ctx.storage_mut()); if let Some(earliest_height) = processed_states.get_earliest_height(client_state.latest_height) { - let processed_time = - processed_states.get_processed_time(earliest_height, &mut Vec::new()).unwrap(); + let processed_time = processed_states.get_processed_time(earliest_height, "").unwrap(); let elapsed = Duration::from_nanos(current_time - processed_time); if client_state.expired(elapsed) { processed_states.remove_states_at_height(earliest_height); diff --git a/light-clients/ics07-tendermint-cw/src/ics23/consensus_states.rs b/light-clients/ics07-tendermint-cw/src/ics23/consensus_states.rs index fa2f0a78c..8137f0db3 100644 --- a/light-clients/ics07-tendermint-cw/src/ics23/consensus_states.rs +++ b/light-clients/ics07-tendermint-cw/src/ics23/consensus_states.rs @@ -50,7 +50,7 @@ impl<'a> ConsensusStates<'a> { } pub fn consensus_state_client_key() -> Vec { - "consensusStates/".to_string().into_bytes() + b"consensusStates/".to_vec() } pub fn consensus_state_height_key(height: Height) -> Vec { diff --git a/light-clients/ics07-tendermint-cw/src/ics23/processed_states.rs b/light-clients/ics07-tendermint-cw/src/ics23/processed_states.rs index 0474c4925..9a5b47409 100644 --- a/light-clients/ics07-tendermint-cw/src/ics23/processed_states.rs +++ b/light-clients/ics07-tendermint-cw/src/ics23/processed_states.rs @@ -25,59 +25,51 @@ impl<'a> ProcessedStates<'a> { ProcessedStates(storage) } - pub fn processed_time_key(height: Height, prefix: &mut Vec) -> Vec { - prefix.append(&mut "consensusStates/".to_string().into_bytes()); - prefix.append(&mut format!("{height}").into_bytes()); - prefix.append(&mut "/processedTime".to_string().into_bytes()); - prefix.clone() + pub fn processed_time_key(height: Height, prefix: &str) -> Vec { + format!("{prefix}consensusStates/{height}/processedTime").into_bytes() } - pub fn processed_height_key(height: Height, prefix: &mut Vec) -> Vec { - prefix.append(&mut "consensusStates/".to_string().into_bytes()); - prefix.append(&mut format!("{height}").into_bytes()); - prefix.append(&mut "/processedHeight".to_string().into_bytes()); - prefix.clone() + pub fn processed_height_key(height: Height, prefix: &str) -> Vec { + format!("{prefix}consensusStates/{height}/processedHeight").into_bytes() } - pub fn iteration_key(height: Height, prefix: &mut Vec) -> Vec { - prefix.append(&mut "iterateConsensusStates".to_string().into_bytes()); - prefix.append(&mut height.revision_number.to_be_bytes().to_vec()); - prefix.append(&mut height.revision_height.to_be_bytes().to_vec()); - prefix.clone() + pub fn iteration_key(height: Height, prefix: &str) -> Vec { + [ + prefix.as_bytes(), + &b"iterateConsensusStates"[..], + &height.revision_number.to_be_bytes()[..], + &height.revision_height.to_be_bytes()[..], + ] + .concat() } - pub fn get_processed_time(&self, height: Height, prefix: &mut Vec) -> Option { + pub fn get_processed_time(&self, height: Height, prefix: &str) -> Option { let full_key = Self::processed_time_key(height, prefix); self.0 .get(&full_key) .map(|timestamp| u64::from_be_bytes(timestamp.try_into().unwrap())) } - pub fn set_processed_time(&mut self, height: Height, timestamp: u64, prefix: &mut Vec) { + pub fn set_processed_time(&mut self, height: Height, timestamp: u64, prefix: &str) { let full_key = Self::processed_time_key(height, prefix); let time_vec: [u8; 8] = timestamp.to_be_bytes(); self.0.set(&full_key, &time_vec); } - pub fn get_processed_height(&self, height: Height, prefix: &mut Vec) -> Option { + pub fn get_processed_height(&self, height: Height, prefix: &str) -> Option { let full_key = Self::processed_height_key(height, prefix); self.0 .get(&full_key) .map(|height| u64::from_be_bytes(height.try_into().unwrap())) } - pub fn set_processed_height( - &mut self, - height: Height, - processed_height: u64, - prefix: &mut Vec, - ) { + pub fn set_processed_height(&mut self, height: Height, processed_height: u64, prefix: &str) { let full_key = Self::processed_height_key(height, prefix); let height_vec: [u8; 8] = processed_height.to_be_bytes(); self.0.set(&full_key, &height_vec); } - pub fn get_iteration_key(&self, height: Height, prefix: &mut Vec) -> Option { + pub fn get_iteration_key(&self, height: Height, prefix: &str) -> Option { let full_key = Self::iteration_key(height, prefix); match self.0.get(&full_key) { Some(height) => match std::str::from_utf8(height.as_slice()) { @@ -88,16 +80,16 @@ impl<'a> ProcessedStates<'a> { } } - pub fn set_iteration_key(&mut self, height: Height, prefix: &mut Vec) { + pub fn set_iteration_key(&mut self, height: Height, prefix: &str) { let full_key = Self::iteration_key(height, prefix); let height_vec = format!("{height}").into_bytes(); self.0.set(&full_key, &height_vec); } pub fn get_earliest_height(&mut self, current_height: Height) -> Option { - let full_key = Self::iteration_key(current_height, &mut Vec::new()); - let start_key = "iterateConsensusStates".to_string().into_bytes(); - let mut iterator = self.0.range(Some(&start_key), Some(&full_key), Order::Ascending); + let full_key = Self::iteration_key(current_height, ""); + let start_key = &b"iterateConsensusStates"[..]; + let mut iterator = self.0.range(Some(start_key), Some(&full_key), Order::Ascending); match iterator.next() { Some((_, height)) => match std::str::from_utf8(height.as_slice()) { Ok(height_str) => Some(Height::try_from(height_str).unwrap()), @@ -108,9 +100,9 @@ impl<'a> ProcessedStates<'a> { } pub fn remove_states_at_height(&mut self, height: Height) { - let processed_time_key = Self::processed_time_key(height, &mut Vec::new()); - let processed_height_key = Self::processed_height_key(height, &mut Vec::new()); - let iteration_key = Self::iteration_key(height, &mut Vec::new()); + let processed_time_key = Self::processed_time_key(height, ""); + let processed_height_key = Self::processed_height_key(height, ""); + let iteration_key = Self::iteration_key(height, ""); self.0.remove(&processed_time_key); self.0.remove(&processed_height_key); @@ -125,21 +117,21 @@ impl<'a> ReadonlyProcessedStates<'a> { ReadonlyProcessedStates(storage) } - pub fn get_processed_time(&self, height: Height, prefix: &mut Vec) -> Option { + pub fn get_processed_time(&self, height: Height, prefix: &str) -> Option { let full_key = ProcessedStates::processed_time_key(height, prefix); self.0 .get(&full_key) .map(|timestamp| u64::from_be_bytes(timestamp.try_into().unwrap())) } - pub fn get_processed_height(&self, height: Height, prefix: &mut Vec) -> Option { + pub fn get_processed_height(&self, height: Height, prefix: &str) -> Option { let full_key = ProcessedStates::processed_height_key(height, prefix); self.0 .get(&full_key) .map(|height| u64::from_be_bytes(height.try_into().unwrap())) } - pub fn get_iteration_key(&self, height: Height, prefix: &mut Vec) -> Option { + pub fn get_iteration_key(&self, height: Height, prefix: &str) -> Option { let full_key = ProcessedStates::iteration_key(height, prefix); match self.0.get(&full_key) { Some(height) => match std::str::from_utf8(height.as_slice()) { @@ -151,7 +143,7 @@ impl<'a> ReadonlyProcessedStates<'a> { } pub fn get_next_height(&self, height: Height) -> Option { - let full_key = ProcessedStates::iteration_key(height, &mut Vec::new()); + let full_key = ProcessedStates::iteration_key(height, ""); let mut iterator = self.0.range(Some(&full_key), None, Order::Ascending); match iterator.next() { Some((_, height)) => match std::str::from_utf8(height.as_slice()) { @@ -163,7 +155,7 @@ impl<'a> ReadonlyProcessedStates<'a> { } pub fn get_prev_height(&self, height: Height) -> Option { - let full_key = ProcessedStates::iteration_key(height, &mut Vec::new()); + let full_key = ProcessedStates::iteration_key(height, ""); let mut iterator = self.0.range(None, Some(&full_key), Order::Descending); match iterator.next() { Some((_, height)) => match std::str::from_utf8(height.as_slice()) { @@ -177,20 +169,18 @@ impl<'a> ReadonlyProcessedStates<'a> { pub fn get_metadata(&self) -> Option> { let mut gm: Vec = Vec::::new(); - let start_key = "iterateConsensusStates".to_string().into_bytes(); - let iterator = self.0.range(Some(&start_key), None, Order::Ascending); + let start_key = &b"iterateConsensusStates"[..]; + let iterator = self.0.range(Some(start_key), None, Order::Ascending); for (_, height) in iterator { match std::str::from_utf8(height.as_slice()) { Ok(height_str) => { let height = Height::try_from(height_str).unwrap(); - let processed_height_key = - ProcessedStates::processed_height_key(height, &mut Vec::new()); + let processed_height_key = ProcessedStates::processed_height_key(height, ""); gm.push(GenesisMetadata { key: processed_height_key.clone(), value: self.0.get(&processed_height_key).unwrap(), }); - let processed_time_key = - ProcessedStates::processed_time_key(height, &mut Vec::new()); + let processed_time_key = ProcessedStates::processed_time_key(height, ""); gm.push(GenesisMetadata { key: processed_time_key.clone(), value: self.0.get(&processed_time_key).unwrap(), @@ -200,7 +190,7 @@ impl<'a> ReadonlyProcessedStates<'a> { } } - let iterator = self.0.range(Some(&start_key), None, Order::Ascending); + let iterator = self.0.range(Some(start_key), None, Order::Ascending); for (key, height) in iterator { gm.push(GenesisMetadata { key, value: height }); } diff --git a/light-clients/ics07-tendermint-cw/src/state.rs b/light-clients/ics07-tendermint-cw/src/state.rs index 057892a82..a9ebea116 100644 --- a/light-clients/ics07-tendermint-cw/src/state.rs +++ b/light-clients/ics07-tendermint-cw/src/state.rs @@ -30,7 +30,7 @@ pub fn get_client_state( client_id: ClientId, ) -> Result, Error> { deps.storage - .get(&"clientState".to_string().into_bytes()) + .get(b"clientState") .ok_or_else(|| Error::unknown_client_state_type(client_id.to_string())) .and_then(|client_state| deserialize_client_state(client_state, deps)) } @@ -84,5 +84,5 @@ fn deserialize_consensus_state(consensus_state: Vec) -> Result Vec { - ["consensusStates/".to_string().into_bytes(), format!("{height}").into_bytes()].concat() + format!("consensusStates/{height}").into_bytes() } diff --git a/light-clients/ics07-tendermint/Cargo.toml b/light-clients/ics07-tendermint/Cargo.toml index 9b81bbccc..a4602a3b2 100644 --- a/light-clients/ics07-tendermint/Cargo.toml +++ b/light-clients/ics07-tendermint/Cargo.toml @@ -8,6 +8,7 @@ all-features = true [features] default = ["std", "rust-crypto"] +dummy = ["default"] rust-crypto = ["sha2"] std = [ "bytes/std", @@ -40,9 +41,9 @@ prost = { version = "0.11", default-features = false } bytes = { version = "1.1.0", default-features = false } subtle-encoding = { version = "0.5", default-features = false } flex-error = { version = "0.4.4", default-features = false } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-light-client-verifier = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } sha2 = { version = "0.10", optional = true, default-features = false } hex = { version = "0.4.3", default-features = false } log = { version = "0.4", default-features = false } @@ -55,7 +56,7 @@ tracing-subscriber = { version = "0.3.11", features = ["fmt", "env-filter", "jso test-log = { version = "0.2.10", features = ["trace"] } modelator = "0.4.2" sha2 = { version = "0.10.2" } -tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", features = ["http-client", "websocket-client"] } -tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" } # Needed for generating (synthetic) light blocks. +tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", features = ["http-client", "websocket-client"] } +tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" } # Needed for generating (synthetic) light blocks. log = "0.4.17" tracing = "0.1.36" diff --git a/light-clients/ics07-tendermint/src/client_def.rs b/light-clients/ics07-tendermint/src/client_def.rs index 4dbd5ebbc..5b859bacf 100644 --- a/light-clients/ics07-tendermint/src/client_def.rs +++ b/light-clients/ics07-tendermint/src/client_def.rs @@ -167,11 +167,12 @@ where let options = client_state.as_light_client_options()?; let verifier = ProdVerifier::::default(); - let verdict = verifier.verify( + let time = ctx.host_timestamp().into_tm_time().unwrap(); + let verdict = verifier.verify_misbehaviour_header( untrusted_state, trusted_state, &options, - ctx.host_timestamp().into_tm_time().unwrap(), + time, ); match verdict { @@ -385,7 +386,7 @@ where client_state.verify_height(height)?; let path = ConnectionsPath(connection_id.clone()); - let value = expected_connection_end.encode_vec().map_err(Ics02Error::encode)?; + let value = expected_connection_end.clone().encode_vec(); verify_membership::(client_state, prefix, proof, root, path, value) } @@ -405,7 +406,7 @@ where client_state.verify_height(height)?; let path = ChannelEndsPath(port_id.clone(), *channel_id); - let value = expected_channel_end.encode_vec().map_err(Ics02Error::encode)?; + let value = expected_channel_end.clone().encode_vec(); verify_membership::(client_state, prefix, proof, root, path, value) } diff --git a/light-clients/ics07-tendermint/src/client_message.rs b/light-clients/ics07-tendermint/src/client_message.rs index a4377010d..420ebc771 100644 --- a/light-clients/ics07-tendermint/src/client_message.rs +++ b/light-clients/ics07-tendermint/src/client_message.rs @@ -33,7 +33,13 @@ use ibc_proto::{ }; use prost::Message; use serde::{Deserialize, Serialize}; -use tendermint::{block::signed_header::SignedHeader, validator::Set as ValidatorSet}; +use tendermint::{ + block::{signed_header::SignedHeader, Commit, CommitSig}, + crypto::signature::Verifier, + validator::Set as ValidatorSet, + vote::{SignedVote, ValidatorIndex}, + PublicKey, Vote, +}; use tendermint_proto::Protobuf; pub const TENDERMINT_HEADER_TYPE_URL: &str = "/ibc.lightclients.tendermint.v1.Header"; @@ -56,7 +62,7 @@ pub enum ClientMessage { impl ics02_client::client_message::ClientMessage for ClientMessage { fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } @@ -84,14 +90,10 @@ impl TryFrom for ClientMessage { impl From for Any { fn from(msg: ClientMessage) -> Self { match msg { - ClientMessage::Header(header) => Any { - value: header.encode_vec().expect("failed to encode ClientMessage.header"), - type_url: TENDERMINT_HEADER_TYPE_URL.to_string(), - }, + ClientMessage::Header(header) => + Any { value: header.encode_vec(), type_url: TENDERMINT_HEADER_TYPE_URL.to_string() }, ClientMessage::Misbehaviour(misbheaviour) => Any { - value: misbheaviour - .encode_vec() - .expect("failed to encode ClientMessage.misbehaviour"), + value: misbheaviour.encode_vec(), type_url: TENDERMINT_MISBEHAVIOUR_TYPE_URL.to_string(), }, } @@ -242,7 +244,7 @@ impl From
for RawHeader { } } -#[cfg(test)] +#[cfg(any(test, feature = "dummy"))] pub mod test_util { use alloc::vec; @@ -299,7 +301,7 @@ pub mod test_util { Header { signed_header: shdr, validator_set: vs.clone(), - trusted_height: Height::new(0, 1), + trusted_height: Height::new(1, 1), trusted_validator_set: vs, } } diff --git a/light-clients/ics07-tendermint/src/client_state.rs b/light-clients/ics07-tendermint/src/client_state.rs index 17ca88e49..c1d80ccc7 100644 --- a/light-clients/ics07-tendermint/src/client_state.rs +++ b/light-clients/ics07-tendermint/src/client_state.rs @@ -64,7 +64,7 @@ impl ClientState { pub fn to_any(&self) -> Any { Any { type_url: TENDERMINT_CLIENT_STATE_TYPE_URL.to_string(), - value: self.encode_vec().unwrap(), + value: self.clone().encode_vec(), } } } @@ -296,7 +296,7 @@ where } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics07-tendermint/src/consensus_state.rs b/light-clients/ics07-tendermint/src/consensus_state.rs index 476359188..05c0fb629 100644 --- a/light-clients/ics07-tendermint/src/consensus_state.rs +++ b/light-clients/ics07-tendermint/src/consensus_state.rs @@ -45,7 +45,7 @@ impl ConsensusState { pub fn to_any(&self) -> Any { Any { type_url: TENDERMINT_CONSENSUS_STATE_TYPE_URL.to_string(), - value: self.encode_vec().expect("encode ConsensusState"), + value: self.clone().encode_vec(), } } } @@ -62,7 +62,7 @@ impl ibc::core::ics02_client::client_consensus::ConsensusState for ConsensusStat } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics07-tendermint/src/mock/mod.rs b/light-clients/ics07-tendermint/src/mock/mod.rs index 65d955953..0cef2794c 100644 --- a/light-clients/ics07-tendermint/src/mock/mod.rs +++ b/light-clients/ics07-tendermint/src/mock/mod.rs @@ -117,7 +117,7 @@ impl From for Any { }, AnyClientMessage::Tendermint(msg) => Any { type_url: TENDERMINT_CLIENT_MESSAGE_TYPE_URL.to_string(), - value: msg.encode_vec().unwrap(), + value: msg.encode_vec(), }, } } diff --git a/light-clients/ics07-tendermint/src/mock/signed_header.json b/light-clients/ics07-tendermint/src/mock/signed_header.json index 9416df80c..6fde1bc8a 100644 --- a/light-clients/ics07-tendermint/src/mock/signed_header.json +++ b/light-clients/ics07-tendermint/src/mock/signed_header.json @@ -4,7 +4,7 @@ "block": "0", "app": "0" }, - "chain_id": "test-chain-01", + "chain_id": "test-1", "height": "20", "time": "2019-11-02T15:04:10Z", "last_block_id": { diff --git a/light-clients/ics08-wasm/Cargo.toml b/light-clients/ics08-wasm/Cargo.toml index 7333568e4..c8fb03584 100644 --- a/light-clients/ics08-wasm/Cargo.toml +++ b/light-clients/ics08-wasm/Cargo.toml @@ -5,12 +5,12 @@ edition = "2021" [dependencies] prost = { version = "0.11", default-features = false } -ibc = { path = "../../ibc/modules", default-features = false } +ibc = { path = "../../ibc/modules",default-features = false } ibc-proto = { path = "../../ibc/proto", default-features = false } hex = { version = "0.4.3", default-features = false } cosmwasm-schema = { version = "1.1.3", default-features = false, optional = true } serde = { version = "1.0.145", default-features = false, features = ["derive"], optional = true } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [features] default = [] diff --git a/light-clients/ics08-wasm/src/client_message.rs b/light-clients/ics08-wasm/src/client_message.rs index 42799f821..77176cba7 100644 --- a/light-clients/ics08-wasm/src/client_message.rs +++ b/light-clients/ics08-wasm/src/client_message.rs @@ -53,7 +53,7 @@ where >::Error: Display, { fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } @@ -64,10 +64,7 @@ where >::Error: Display, { pub fn to_any(&self) -> Any { - Any { - value: self.encode_vec().expect("encode client message"), - type_url: WASM_CLIENT_MESSAGE_TYPE_URL.to_string(), - } + Any { value: self.clone().encode_vec(), type_url: WASM_CLIENT_MESSAGE_TYPE_URL.to_string() } } } diff --git a/light-clients/ics08-wasm/src/client_state.rs b/light-clients/ics08-wasm/src/client_state.rs index b386cc1ba..8f1d331f0 100644 --- a/light-clients/ics08-wasm/src/client_state.rs +++ b/light-clients/ics08-wasm/src/client_state.rs @@ -122,7 +122,7 @@ where } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics08-wasm/src/consensus_state.rs b/light-clients/ics08-wasm/src/consensus_state.rs index 33dab6555..e2689fc9a 100644 --- a/light-clients/ics08-wasm/src/consensus_state.rs +++ b/light-clients/ics08-wasm/src/consensus_state.rs @@ -73,7 +73,7 @@ where } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics08-wasm/src/lib.rs b/light-clients/ics08-wasm/src/lib.rs index 9cc2b5a1d..c16547e80 100644 --- a/light-clients/ics08-wasm/src/lib.rs +++ b/light-clients/ics08-wasm/src/lib.rs @@ -28,5 +28,8 @@ pub mod instantiate; pub mod msg; pub type Bytes = Vec; -pub static SUBJECT_PREFIX: &[u8] = "subject/".as_bytes(); -pub static SUBSTITUTE_PREFIX: &[u8] = "substitute/".as_bytes(); +pub static SUBJECT_PREFIX: &[u8] = b"subject/"; +pub static SUBSTITUTE_PREFIX: &[u8] = b"substitute/"; + +pub static SUBJECT_PREFIX_STR: &str = "subject/"; +pub static SUBSTITUTE_PREFIX_STR: &str = "substitute/"; diff --git a/light-clients/ics08-wasm/src/msg.rs b/light-clients/ics08-wasm/src/msg.rs index 68d6ede39..dda637d26 100644 --- a/light-clients/ics08-wasm/src/msg.rs +++ b/light-clients/ics08-wasm/src/msg.rs @@ -26,7 +26,7 @@ use ibc_proto::{ #[cfg(feature = "cosmwasm")] use serde::{Deserializer, Serializer}; -pub const WASM_PUSH_WASM_CODE_TYPE_URL: &str = "/ibc.lightclients.wasm.v1.MsgPushNewWasmCode"; +pub const WASM_PUSH_WASM_CODE_TYPE_URL: &str = "/ibc.lightclients.wasm.v1.MsgStoreCode"; #[derive(Clone, PartialEq, Debug, Eq)] pub struct MsgPushNewWasmCode { @@ -52,10 +52,7 @@ impl TryFrom for MsgPushNewWasmCode { impl From for Any { fn from(value: MsgPushNewWasmCode) -> Self { - Any { - type_url: WASM_PUSH_WASM_CODE_TYPE_URL.to_string(), - value: value.encode_vec().expect("MsgPushNewWasmCode encoding should always succeed"), - } + Any { type_url: WASM_PUSH_WASM_CODE_TYPE_URL.to_string(), value: value.encode_vec() } } } diff --git a/light-clients/ics10-grandpa-cw/Cargo.toml b/light-clients/ics10-grandpa-cw/Cargo.toml index 43a87a451..ba1b1dabb 100644 --- a/light-clients/ics10-grandpa-cw/Cargo.toml +++ b/light-clients/ics10-grandpa-cw/Cargo.toml @@ -51,7 +51,7 @@ twox-hash = { version = "1.6.3", default-features = false, features = ["digest_0 byteorder = { version = "1.3.2", default-features = false } digest = { version = "0.10.3", default-features = false } hex = "0.4.3" -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } finality-grandpa = { version = "0.16.2", default-features = false } [dev-dependencies] @@ -61,7 +61,7 @@ hyperspace-primitives = { path = "../../hyperspace/primitives", features = ["tes pallet-ibc = { path = "../../contracts/pallet-ibc" } serde-json-wasm = { version = "0.5.0", default-features = false } serde_json = { version = "1.0.93", default-features = false } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [features] diff --git a/light-clients/ics10-grandpa-cw/src/contract.rs b/light-clients/ics10-grandpa-cw/src/contract.rs index 8503bc5aa..4589e6400 100644 --- a/light-clients/ics10-grandpa-cw/src/contract.rs +++ b/light-clients/ics10-grandpa-cw/src/contract.rs @@ -220,7 +220,7 @@ fn process_message( // load the substitute client state from the combined storage using the appropriate // prefix let substitute_client_state = ctx - .client_state_prefixed(SUBSTITUTE_PREFIX) + .client_state_prefixed(SUBSTITUTE_PREFIX.as_bytes()) .map_err(|e| ContractError::Grandpa(e.to_string()))?; // No items for the grandpa client state are required to be the same @@ -228,10 +228,18 @@ fn process_message( let height = substitute_client_state.latest_height(); // consensus state should be replaced as well let substitute_consensus_state = - ctx.consensus_state_prefixed(height, SUBSTITUTE_PREFIX)?; - ctx.store_consensus_state_prefixed(height, substitute_consensus_state, SUBJECT_PREFIX); - ctx.store_client_state_prefixed(substitute_client_state, SUBJECT_PREFIX, client_id) - .map_err(|e| ContractError::Grandpa(e.to_string()))?; + ctx.consensus_state_prefixed(height, SUBSTITUTE_PREFIX.as_bytes())?; + ctx.store_consensus_state_prefixed( + height, + substitute_consensus_state, + SUBJECT_PREFIX.as_bytes(), + ); + ctx.store_client_state_prefixed( + substitute_client_state, + SUBJECT_PREFIX.as_bytes(), + client_id, + ) + .map_err(|e| ContractError::Grandpa(e.to_string()))?; Ok(()).map(|_| to_binary(&ContractResult::success())) }, diff --git a/light-clients/ics10-grandpa-cw/src/ics23/consensus_states.rs b/light-clients/ics10-grandpa-cw/src/ics23/consensus_states.rs index f443129af..98fd0b471 100644 --- a/light-clients/ics10-grandpa-cw/src/ics23/consensus_states.rs +++ b/light-clients/ics10-grandpa-cw/src/ics23/consensus_states.rs @@ -51,7 +51,7 @@ impl<'a> ConsensusStates<'a> { } pub fn consensus_state_client_key() -> Vec { - "consensusStates/".to_string().into_bytes() + b"consensusStates/".to_vec() } pub fn consensus_state_height_key(height: Height) -> Vec { diff --git a/light-clients/ics10-grandpa-cw/src/state.rs b/light-clients/ics10-grandpa-cw/src/state.rs index 23b9813f4..6647e98f6 100644 --- a/light-clients/ics10-grandpa-cw/src/state.rs +++ b/light-clients/ics10-grandpa-cw/src/state.rs @@ -30,7 +30,7 @@ pub fn get_client_state( client_id: ClientId, ) -> Result, Error> { deps.storage - .get(&"clientState".to_string().into_bytes()) + .get(b"clientState") .ok_or_else(|| Error::unknown_client_state_type(client_id.to_string())) .and_then(deserialize_client_state) } @@ -63,5 +63,5 @@ pub fn get_consensus_state( } pub fn get_consensus_state_key(height: Height) -> Vec { - ["consensusStates/".to_string().into_bytes(), format!("{height}").into_bytes()].concat() + format!("consensusStates/{height}").into_bytes() } diff --git a/light-clients/ics10-grandpa/Cargo.toml b/light-clients/ics10-grandpa/Cargo.toml index b398c07bd..eb41db01f 100644 --- a/light-clients/ics10-grandpa/Cargo.toml +++ b/light-clients/ics10-grandpa/Cargo.toml @@ -60,8 +60,8 @@ sp-trie = { git = "https://github.com/paritytech/substrate", branch = "polkadot- sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } finality-grandpa = { version = "0.16.2", default-features = false } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [dev-dependencies] hex = "0.4.3" diff --git a/light-clients/ics10-grandpa/src/client_def.rs b/light-clients/ics10-grandpa/src/client_def.rs index f72ae3d7b..c4edc4e83 100644 --- a/light-clients/ics10-grandpa/src/client_def.rs +++ b/light-clients/ics10-grandpa/src/client_def.rs @@ -509,7 +509,7 @@ where ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; let path = ConnectionsPath(connection_id.clone()); - let value = expected_connection_end.encode_vec().map_err(Ics02Error::encode)?; + let value = expected_connection_end.clone().encode_vec(); verify_membership::(prefix, proof, root, path, value) .map_err(Error::Anyhow)?; Ok(()) @@ -530,7 +530,7 @@ where ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; let path = ChannelEndsPath(port_id.clone(), *channel_id); - let value = expected_channel_end.encode_vec().map_err(Ics02Error::encode)?; + let value = expected_channel_end.clone().encode_vec(); verify_membership::(prefix, proof, root, path, value) .map_err(Error::Anyhow)?; Ok(()) diff --git a/light-clients/ics10-grandpa/src/client_message.rs b/light-clients/ics10-grandpa/src/client_message.rs index 960a94722..c1b0e9e0b 100644 --- a/light-clients/ics10-grandpa/src/client_message.rs +++ b/light-clients/ics10-grandpa/src/client_message.rs @@ -79,7 +79,7 @@ pub enum ClientMessage { impl ibc::core::ics02_client::client_message::ClientMessage for ClientMessage { fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics10-grandpa/src/client_state.rs b/light-clients/ics10-grandpa/src/client_state.rs index 941f7eb89..3e671ba5a 100644 --- a/light-clients/ics10-grandpa/src/client_state.rs +++ b/light-clients/ics10-grandpa/src/client_state.rs @@ -105,7 +105,7 @@ impl ClientState { pub fn to_any(&self) -> Any { Any { type_url: GRANDPA_CLIENT_STATE_TYPE_URL.to_string(), - value: self.encode_vec().unwrap(), + value: self.clone().encode_vec(), } } } @@ -224,7 +224,7 @@ where } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics10-grandpa/src/consensus_state.rs b/light-clients/ics10-grandpa/src/consensus_state.rs index 6c16785ee..a056afe79 100644 --- a/light-clients/ics10-grandpa/src/consensus_state.rs +++ b/light-clients/ics10-grandpa/src/consensus_state.rs @@ -49,7 +49,7 @@ impl ConsensusState { pub fn to_any(&self) -> Any { Any { type_url: GRANDPA_CONSENSUS_STATE_TYPE_URL.to_string(), - value: self.encode_vec().expect("encode ConsensusState"), + value: self.clone().encode_vec(), } } @@ -102,7 +102,7 @@ impl ibc::core::ics02_client::client_consensus::ConsensusState for ConsensusStat } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics11-beefy/Cargo.toml b/light-clients/ics11-beefy/Cargo.toml index 5304c93cc..39176a150 100644 --- a/light-clients/ics11-beefy/Cargo.toml +++ b/light-clients/ics11-beefy/Cargo.toml @@ -62,8 +62,8 @@ prost-types = { version = "0.11", default-features = false } serde = { version = "1.0", default-features = false } bytes = { version = "1.1.0", default-features = false } derive_more = { version = "0.99.17", default-features = false, features = ["from"] } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } #substrate sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } diff --git a/light-clients/ics11-beefy/src/client_def.rs b/light-clients/ics11-beefy/src/client_def.rs index 71111ab52..e6cd0bcae 100644 --- a/light-clients/ics11-beefy/src/client_def.rs +++ b/light-clients/ics11-beefy/src/client_def.rs @@ -300,7 +300,7 @@ where ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; let path = ConnectionsPath(connection_id.clone()); - let value = expected_connection_end.encode_vec().map_err(Ics02Error::encode)?; + let value = expected_connection_end.clone().encode_vec(); verify_membership::(prefix, proof, root, path, value) .map_err(Error::Anyhow)?; Ok(()) @@ -321,7 +321,7 @@ where ) -> Result<(), Ics02Error> { client_state.verify_height(height)?; let path = ChannelEndsPath(port_id.clone(), *channel_id); - let value = expected_channel_end.encode_vec().map_err(Ics02Error::encode)?; + let value = expected_channel_end.clone().encode_vec(); verify_membership::(prefix, proof, root, path, value) .map_err(Error::Anyhow)?; Ok(()) diff --git a/light-clients/ics11-beefy/src/client_message.rs b/light-clients/ics11-beefy/src/client_message.rs index 6424e8b5d..d36ede4e5 100644 --- a/light-clients/ics11-beefy/src/client_message.rs +++ b/light-clients/ics11-beefy/src/client_message.rs @@ -74,7 +74,7 @@ pub struct ParachainHeadersWithProof { impl ibc::core::ics02_client::client_message::ClientMessage for ClientMessage { fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics11-beefy/src/client_state.rs b/light-clients/ics11-beefy/src/client_state.rs index ce88cfa04..b0455d3b8 100644 --- a/light-clients/ics11-beefy/src/client_state.rs +++ b/light-clients/ics11-beefy/src/client_state.rs @@ -262,7 +262,7 @@ where } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics11-beefy/src/consensus_state.rs b/light-clients/ics11-beefy/src/consensus_state.rs index e087a5599..c4e4d2b1b 100644 --- a/light-clients/ics11-beefy/src/consensus_state.rs +++ b/light-clients/ics11-beefy/src/consensus_state.rs @@ -68,7 +68,7 @@ impl ibc::core::ics02_client::client_consensus::ConsensusState for ConsensusStat } fn encode_to_vec(&self) -> Result, tendermint_proto::Error> { - self.encode_vec() + Ok(self.clone().encode_vec()) } } diff --git a/light-clients/ics13-near/Cargo.toml b/light-clients/ics13-near/Cargo.toml index b989f40ba..d1b3d4f28 100644 --- a/light-clients/ics13-near/Cargo.toml +++ b/light-clients/ics13-near/Cargo.toml @@ -64,8 +64,8 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.43", default-features = false } sha3 = { version = "0.10.1", optional = true } ripemd = { version = "0.1.1", optional = true } -tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } -tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", default-features = false } +tendermint = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } +tendermint-proto = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", default-features = false } [dev-dependencies] ibc = { path = "../../ibc/modules", features = ['mocks'] } @@ -74,8 +74,8 @@ tracing-subscriber = { version = "0.3.11", features = ["fmt", "env-filter", "jso test-log = { version = "0.2.10", features = ["trace"] } modelator = "0.4.2" sha2 = { version = "0.10.2" } -tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1", features = ["http-client", "websocket-client"] } -tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", rev = "e81f7bf23d63ffbcd242381d1ce5e35da3515ff1" } # Needed for generating (synthetic) light blocks. +tendermint-rpc = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141", features = ["http-client", "websocket-client"] } +tendermint-testgen = { git = "https://github.com/informalsystems/tendermint-rs", rev = "4d81b67c28510db7d2d99ed62ebfa9fdf0e02141" } # Needed for generating (synthetic) light blocks. tokio = { version = "1.32.0", features = ["full"] } serde_json = "1.0.74" sha3 = { version = "0.10.1" } diff --git a/light-clients/icsxx-cf-solana/Cargo.toml b/light-clients/icsxx-cf-solana/Cargo.toml new file mode 100644 index 000000000..030d74129 --- /dev/null +++ b/light-clients/icsxx-cf-solana/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "icsxx-cf-solana" +authors = ["Michal Nazarewicz "] +version = "0.0.1" +edition = "2021" + +[dependencies] +borsh = "0.10" +bytemuck = { version = "1.14", default-features = false, features = ["must_cast"] } +derive_more = { version = "0.99", features = ["from"], default-features = false } +prost = { version = "0.11", features = ["prost-derive"], default-features = false } +prost-12 = { package = "prost", version = "0.12", default-features = false } +ed25519-consensus = { version = "2", default-features = false } +serde = { version = "1.0", default-features = false, features = ["derive"] } + +# New IBC +ibc-core-client-context = { git = "https://github.com/mina86/ibc-rs", rev = "6015aea441d4660f7f7ecd89b5e770a993448089", default-features = false } +ibc-core-client-types = { git = "https://github.com/mina86/ibc-rs", rev = "6015aea441d4660f7f7ecd89b5e770a993448089", default-features = false } +ibc-core-handler-types = { git = "https://github.com/mina86/ibc-rs", rev = "6015aea441d4660f7f7ecd89b5e770a993448089", default-features = false } +ibc-core-host-types = { git = "https://github.com/mina86/ibc-rs", rev = "6015aea441d4660f7f7ecd89b5e770a993448089", default-features = false } +ibc-primitives = { git = "https://github.com/mina86/ibc-rs", rev = "6015aea441d4660f7f7ecd89b5e770a993448089", default-features = false } + +# Old IBC +ibc = { path = "../../ibc/modules", default-features = false } +ibc-proto = { path = "../../ibc/proto", default-features = false } +ibc-derive = { path = "../../ibc/derive", default-features = false } + +tendermint-proto = { git = "https://github.com/mina86/tendermint-rs", rev = "45fbd500d731effb95a98257630feb46f6c41d06", default-features = false } + +guestchain = { git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false } +lib = { git = "https://github.com/ComposableFi/emulated-light-client/", features = ["borsh"], default-features = false } +trie-ids = { git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false } +sealable-trie = { git = "https://github.com/ComposableFi/emulated-light-client/", features = ["borsh"], default-features = false } +stdx = { git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false } +cf-guest-upstream = { package = "cf-guest", git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false } + +[build-dependencies] +prost-build = { version = "0.11", default-features = false } + +[dev-dependencies] +insta = { version = "1.34.0" } +rand = { version = "0.8.5" } + +guestchain = { git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false, features = ["test_utils"] } +lib = { git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false, features = ["test_utils"] } +memory = { git = "https://github.com/ComposableFi/emulated-light-client/", default-features = false, features = ["test_utils"] } + +[features] +std = [] \ No newline at end of file diff --git a/light-clients/icsxx-cf-solana/src/client.rs b/light-clients/icsxx-cf-solana/src/client.rs new file mode 100644 index 000000000..6b3a6e35e --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/client.rs @@ -0,0 +1,184 @@ +use alloc::string::{String, ToString}; + +use ibc::{ + core::{ics02_client::height::Height, ics24_host::identifier::ClientId}, + timestamp::Timestamp, +}; +use lib::hash::CryptoHash; +use serde::{Deserialize, Serialize}; + +use crate::{client_def::GuestClient, error::Error, CLIENT_TYPE}; + +super::wrap!(cf_guest_upstream::ClientState as ClientState); +super::wrap!(impl proto for ClientState); + +impl ClientState { + pub fn new( + genesis_hash: CryptoHash, + latest_height: guestchain::BlockHeight, + trusting_period_ns: u64, + epoch_commitment: CryptoHash, + prev_epoch_commitment: Option, + is_frozen: bool, + ) -> Self { + Self(cf_guest_upstream::ClientState::new( + genesis_hash, + latest_height, + trusting_period_ns, + epoch_commitment, + prev_epoch_commitment, + is_frozen, + )) + } + + pub fn with_header(&self, header: &cf_guest_upstream::Header) -> Self { + Self(self.0.with_header(&header)) + } + + pub fn frozen(&self) -> Self { + Self(self.0.frozen()) + } + + /// Verify the time and height delays + pub fn verify_delay_passed( + current_time: Timestamp, + current_height: Height, + processed_time: u64, + processed_height: u64, + delay_period_time: u64, + delay_period_blocks: u64, + ) -> Result<(), Error> { + let earliest_time = processed_time + delay_period_time; + // NOTE: delay time period is inclusive, so if current_time is earliest_time, then we + // return no error https://github.com/cosmos/ibc-go/blob/9ebc2f81049869bc40c443ffb72d9f3e47afb4fc/modules/light-clients/07-tendermint/client_state.go#L306 + if current_time.nanoseconds() < earliest_time { + return Err(Error::NotEnoughTimeElapsed { current_time, earliest_time }) + } + + let earliest_height = processed_height + delay_period_blocks; + if current_height.revision_height < earliest_height { + return Err(Error::NotEnoughBlocksElapsed { current_height, earliest_height }) + } + + Ok(()) + } + + pub fn verify_height(&self, client_id: &ClientId, height: ibc::Height) -> Result<(), Error> { + if self.0.latest_height < height.revision_height.into() { + return Err(Error::InsufficientHeight { + latest_height: Height::new(1, self.0.latest_height.into()), + target_height: height, + }) + } + + if self.0.is_frozen { + return Err(Error::ClientFrozen { client_id: client_id.clone() }) + } + Ok(()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct UpgradeOptions {} + +impl ibc::core::ics02_client::client_state::ClientState for ClientState +where + PK: guestchain::PubKey + Send + Sync, + PK::Signature: Send + Sync, +{ + type UpgradeOptions = UpgradeOptions; + + type ClientDef = GuestClient; + + fn chain_id(&self) -> ibc::core::ics24_host::identifier::ChainId { + ibc::core::ics24_host::identifier::ChainId::new(String::from("Solana"), 0) + } + + fn client_def(&self) -> Self::ClientDef { + GuestClient::default() + } + + fn client_type(&self) -> ibc::core::ics02_client::client_state::ClientType { + CLIENT_TYPE.to_string() + } + + fn latest_height(&self) -> ibc::Height { + Height::new(1, u64::from(self.0.latest_height)) + } + + fn frozen_height(&self) -> Option { + self.0.is_frozen.then(|| Height::new(1, u64::from(self.0.latest_height))) + } + + fn upgrade( + mut self, + upgrade_height: ibc::Height, + _upgrade_options: Self::UpgradeOptions, + _chain_id: ibc::core::ics24_host::identifier::ChainId, + ) -> Self { + self.0.latest_height = upgrade_height.revision_height.into(); + self + } + + fn expired(&self, elapsed: core::time::Duration) -> bool { + elapsed.as_nanos() as u64 > self.0.trusting_period_ns + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + Ok(self.0.encode()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + use guestchain::validators::MockPubKey; + + const ANY_MESSAGE: [u8; 116] = [ + 10, 34, 47, 108, 105, 103, 104, 116, 99, 108, 105, 101, 110, 116, 115, 46, 103, 117, 101, + 115, 116, 46, 118, 49, 46, 67, 108, 105, 101, 110, 116, 83, 116, 97, 116, 101, 18, 78, 10, + 32, 243, 148, 241, 41, 122, 49, 51, 253, 97, 145, 113, 22, 234, 164, 193, 183, 185, 48, + 160, 186, 69, 72, 144, 156, 126, 229, 103, 131, 220, 174, 140, 165, 16, 5, 24, 128, 128, + 144, 202, 210, 198, 14, 34, 32, 86, 12, 131, 131, 127, 125, 82, 54, 32, 207, 121, 149, 204, + 11, 121, 102, 180, 211, 111, 54, 0, 207, 247, 125, 195, 57, 10, 10, 80, 84, 86, 152, + ]; + + fn message() -> &'static [u8] { + &ANY_MESSAGE[38..] + } + + const GENESIS_HASH: CryptoHash = CryptoHash([ + 243, 148, 241, 41, 122, 49, 51, 253, 97, 145, 113, 22, 234, 164, 193, 183, 185, 48, 160, + 186, 69, 72, 144, 156, 126, 229, 103, 131, 220, 174, 140, 165, + ]); + const EPOCH_COMMITMENT: CryptoHash = CryptoHash([ + 86, 12, 131, 131, 127, 125, 82, 54, 32, 207, 121, 149, 204, 11, 121, 102, 180, 211, 111, + 54, 0, 207, 247, 125, 195, 57, 10, 10, 80, 84, 86, 152, + ]); + + fn check(state: ClientState) { + let want = ClientState::::new( + GENESIS_HASH.clone(), + 5.into(), + 64000000000000, + EPOCH_COMMITMENT.clone(), + Some(EPOCH_COMMITMENT.clone()), + false, + ); + assert_eq!(want, state); + } + + #[test] + fn test_decode_vec() { + check(ibc::protobuf::Protobuf::decode_vec(message()).unwrap()); + } + + #[test] + fn test_from_any() { + use ibc_proto::google::protobuf::Any; + + let any: Any = prost::Message::decode(ANY_MESSAGE.as_ref()).unwrap(); + check(any.try_into().unwrap()); + } +} diff --git a/light-clients/icsxx-cf-solana/src/client_def.rs b/light-clients/icsxx-cf-solana/src/client_def.rs new file mode 100644 index 000000000..b4030bc2b --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/client_def.rs @@ -0,0 +1,561 @@ +use core::str::FromStr; + +use guestchain::Signature; + +use crate::alloc::string::ToString; +use alloc::vec::Vec; +use guestchain::{PubKey, Verifier}; +use ibc::{ + core::{ + ics02_client::{ + client_consensus::ConsensusState, + client_def::{ClientDef, ConsensusUpdateResult}, + client_state::ClientState as OtherClientState, + error::Error as Ics02ClientError, + }, + ics26_routing::context::ReaderContext, + }, + protobuf::Protobuf, +}; +use prost::Message; + +use crate::{error::Error, ClientMessage, ClientState, ConsensusState as ClientConsensusState}; + +type Result = ::core::result::Result; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct GuestClient(core::marker::PhantomData); + +impl Default for GuestClient { + fn default() -> Self { + Self(core::marker::PhantomData) + } +} + +impl ClientDef for GuestClient +where + PK: PubKey + Send + Sync, + PK::Signature: Send + Sync, +{ + type ClientMessage = ClientMessage; + type ClientState = ClientState; + type ConsensusState = ClientConsensusState; + + fn verify_client_message( + &self, + _ctx: &Ctx, + _client_id: ibc::core::ics24_host::identifier::ClientId, + client_state: Self::ClientState, + client_msg: Self::ClientMessage, + ) -> Result<(), Ics02ClientError> { + client_state.0.do_verify_client_message(self, client_msg.0).map_err(convert) + } + + fn update_state( + &self, + _ctx: &Ctx, + _client_id: ibc::core::ics24_host::identifier::ClientId, + client_state: Self::ClientState, + client_msg: Self::ClientMessage, + ) -> Result< + (Self::ClientState, ibc::core::ics02_client::client_def::ConsensusUpdateResult), + Ics02ClientError, + > { + let header = match client_msg.0 { + cf_guest_upstream::ClientMessage::Header(header) => header, + _ => unreachable!("02-client will check for Header before calling update_state; qed"), + }; + let header_consensus_state = ClientConsensusState::from(&header); + let cs = Ctx::AnyConsensusState::wrap(&header_consensus_state).ok_or_else(|| { + Error::UnknownConsensusStateType { description: "Ctx::AnyConsensusState".to_string() } + })?; + Ok((client_state.with_header(&header), ConsensusUpdateResult::Single(cs))) + } + + fn update_state_on_misbehaviour( + &self, + client_state: Self::ClientState, + _client_msg: Self::ClientMessage, + ) -> Result { + Ok(client_state.frozen()) + } + + fn check_for_misbehaviour( + &self, + ctx: &Ctx, + client_id: ibc::core::ics24_host::identifier::ClientId, + client_state: Self::ClientState, + client_msg: Self::ClientMessage, + ) -> Result { + let client_id = convert(client_id); + let ctx = CommonContext::new(ctx); + client_state + .0 + .do_check_for_misbehaviour(ctx, &client_id, client_msg.0) + .map_err(convert) + } + + fn verify_upgrade_and_update_state( + &self, + _ctx: &Ctx, + _client_id: ibc::core::ics24_host::identifier::ClientId, + _old_client_state: &Self::ClientState, + _upgrade_client_state: &Self::ClientState, + _upgrade_consensus_state: &Self::ConsensusState, + _proof_upgrade_client: ibc::prelude::Vec, + _proof_upgrade_consensus_state: ibc::prelude::Vec, + ) -> Result< + (Self::ClientState, ibc::core::ics02_client::client_def::ConsensusUpdateResult), + Ics02ClientError, + > { + // TODO: tendermint verify_upgrade_and_update_state + Err(Ics02ClientError::implementation_specific("Not implemented".to_string())) + } + + fn check_substitute_and_update_state( + &self, + _ctx: &Ctx, + _subject_client_id: ibc::core::ics24_host::identifier::ClientId, + _substitute_client_id: ibc::core::ics24_host::identifier::ClientId, + _old_client_state: Self::ClientState, + _substitute_client_state: Self::ClientState, + ) -> Result< + (Self::ClientState, ibc::core::ics02_client::client_def::ConsensusUpdateResult), + Ics02ClientError, + > { + // TODO: tendermint check_substitute_and_update_state + Err(Ics02ClientError::implementation_specific("Not implemented".to_string())) + } + + fn verify_client_consensus_state( + &self, + _ctx: &Ctx, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + client_id: &ibc::core::ics24_host::identifier::ClientId, + consensus_height: ibc::Height, + expected_consensus_state: &Ctx::AnyConsensusState, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ClientConsensusStatePath { + client_id: convert(client_id), + revision_number: consensus_height.revision_number, + revision_height: consensus_height.revision_height, + }; + let value = expected_consensus_state.encode_to_vec().map_err(Ics02ClientError::encode)?; + verify(proof, root, path.into(), Some(value)) + } + + fn verify_connection_state( + &self, + _ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + connection_id: &ibc::core::ics24_host::identifier::ConnectionId, + expected_connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ConnectionPath(convert(connection_id)); + let value = expected_connection_end.encode_vec().map_err(Ics02ClientError::encode)?; + verify(proof, root, path.into(), Some(value)) + } + + fn verify_channel_state( + &self, + _ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + expected_channel_end: &ibc::core::ics04_channel::channel::ChannelEnd, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ChannelEndPath(convert(port_id), convert(channel_id)); + let value = expected_channel_end.encode_vec().map_err(Ics02ClientError::encode)?; + verify(proof, root, path.into(), Some(value)).map_err(|e| e.into()) + } + + fn verify_client_full_state( + &self, + _ctx: &Ctx, + client_state: &Self::ClientState, + height: ibc::Height, + _prefix: &ibc::core::ics23_commitment::commitment::CommitmentPrefix, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + client_id: &ibc::core::ics24_host::identifier::ClientId, + expected_client_state: &Ctx::AnyClientState, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + + let path = ibc_core_host_types::path::ClientStatePath(convert(client_id)); + let value = expected_client_state.encode_to_vec().map_err(Ics02ClientError::encode)?; + verify(proof, root, path.into(), Some(value)).map_err(|e| e.into()) + } + + fn verify_packet_data( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + commitment: ibc::core::ics04_channel::commitment::PacketCommitment, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::CommitmentPath { + port_id: convert(port_id), + channel_id: convert(channel_id), + sequence: sequence.0.into(), + }; + verify(proof, root, path.into(), Some(commitment.into_vec())) + } + + fn verify_packet_acknowledgement( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + ack: ibc::core::ics04_channel::commitment::AcknowledgementCommitment, + ) -> Result<(), Ics02ClientError> { + // client state height = consensus state height + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::AckPath { + port_id: convert(port_id), + channel_id: convert(channel_id), + sequence: sequence.0.into(), + }; + verify(proof, root, path.into(), Some(ack.into_vec())) + } + + fn verify_next_sequence_recv( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::SeqRecvPath(convert(port_id), convert(channel_id)); + let mut seq_bytes = Vec::new(); + u64::from(sequence).encode(&mut seq_bytes).expect("buffer size too small"); + verify(proof, root, path.into(), Some(seq_bytes)) + } + + fn verify_packet_receipt_absence( + &self, + ctx: &Ctx, + client_id: &ibc::core::ics24_host::identifier::ClientId, + client_state: &Self::ClientState, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + port_id: &ibc::core::ics24_host::identifier::PortId, + channel_id: &ibc::core::ics24_host::identifier::ChannelId, + sequence: ibc::core::ics04_channel::packet::Sequence, + ) -> Result<(), Ics02ClientError> { + client_state.verify_height(client_id, height)?; + verify_delay_passed::(ctx, height, connection_end)?; + + let path = ibc_core_host_types::path::ReceiptPath { + port_id: convert(port_id), + channel_id: convert(channel_id), + sequence: sequence.0.into(), + }; + verify(proof, root, path.into(), None) + } +} + +fn verify_delay_passed( + ctx: &Ctx, + height: ibc::Height, + connection_end: &ibc::core::ics03_connection::connection::ConnectionEnd, +) -> Result<(), Ics02ClientError> { + let current_timestamp = ctx.host_timestamp(); + let current_height = ctx.host_height(); + + let client_id = connection_end.client_id(); + let processed_time = ctx + .client_update_time(client_id, height) + .map_err(|_| Error::ProcessedTimeNotFound { height })?; + let processed_height = ctx + .client_update_height(client_id, height) + .map_err(|_| Error::ProcessedHeightNotFound { height })?; + + let delay_period_time = connection_end.delay_period(); + let delay_period_height = ctx.block_delay(delay_period_time); + let delay_period_time_u64 = u64::try_from(delay_period_time.as_nanos()).unwrap(); + + ClientState::::verify_delay_passed( + current_timestamp, + current_height, + processed_time.nanoseconds(), + processed_height.revision_height, + delay_period_time_u64, + delay_period_height, + ) + .map_err(|e| e.into()) +} + +impl Verifier for GuestClient { + fn verify(&self, message: &[u8], pubkey: &PK, signature: &PK::Signature) -> bool { + (|| { + let pubkey = pubkey.as_bytes(); + let pubkey = ed25519_consensus::VerificationKey::try_from(&pubkey[..]).ok()?; + let signature = signature.as_bytes(); + let sig = ed25519_consensus::Signature::try_from(&signature[..]).ok()?; + pubkey.verify(&sig, message).ok()?; + Some(()) + })() + .is_some() + } +} + +#[derive(bytemuck::TransparentWrapper)] +#[repr(transparent)] +#[transparent(Ctx)] +struct CommonContext { + ctx: Ctx, + _ph: core::marker::PhantomData, +} + +impl CommonContext { + fn new(ctx: &Ctx) -> &Self { + bytemuck::TransparentWrapper::wrap_ref(ctx) + } +} + +type NewResult = Result; + +impl cf_guest_upstream::CommonContext + for CommonContext +{ + type ConversionError = core::convert::Infallible; + type AnyClientState = ClientState; + type AnyConsensusState = ClientConsensusState; + + fn host_metadata( + &self, + ) -> NewResult<(ibc_primitives::Timestamp, ibc_core_client_types::Height)> { + unimplemented!("host_metadata") + } + + fn set_client_state( + &mut self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _state: ClientState, + ) -> NewResult<()> { + unimplemented!("set_client_state") + } + + fn consensus_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: ibc_core_client_types::Height, + ) -> NewResult { + unimplemented!("consensus_state") + } + + fn consensus_state_neighbourhood( + &self, + client_id: &ibc_core_host_types::identifiers::ClientId, + height: ibc_core_client_types::Height, + ) -> NewResult> { + use cf_guest_upstream::Neighbourhood; + + let res: Result<_, Ics02ClientError> = (|| { + let client_id = convert(client_id); + let height = convert(height); + Ok(if let Some(state) = self.ctx.maybe_consensus_state(&client_id, height)? { + Neighbourhood::This(state) + } else { + let prev = self.ctx.prev_consensus_state(&client_id, height)?; + let next = self.ctx.next_consensus_state(&client_id, height)?; + Neighbourhood::Neighbours(prev, next) + }) + })(); + match res { + Ok(res) => Ok(res.map(|state: Ctx::AnyConsensusState| { + // TODO(mina86): propagate error rather than unwrapping + let state: Self::AnyConsensusState = state.downcast().unwrap(); + state + })), + Err(err) => Err(convert(err)), + } + } + + fn store_consensus_state_and_metadata( + &mut self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: ibc_core_client_types::Height, + _consensus: Self::AnyConsensusState, + _host_timestamp: ibc_primitives::Timestamp, + _host_height: ibc_core_client_types::Height, + ) -> NewResult { + unimplemented!("store_consensus_state_and_metadata") + } + + fn delete_consensus_state_and_metadata( + &mut self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + _height: ibc_core_client_types::Height, + ) -> NewResult { + unimplemented!("delete_consensus_state_and_metadata") + } + + fn earliest_consensus_state( + &self, + _client_id: &ibc_core_host_types::identifiers::ClientId, + ) -> NewResult> { + unimplemented!("earliest_consensus_state") + } +} + +// Helper wrappers + +fn verify( + proof: &ibc::core::ics23_commitment::commitment::CommitmentProofBytes, + root: &ibc::core::ics23_commitment::commitment::CommitmentRoot, + path: ibc_core_host_types::path::Path, + value: Option>, +) -> Result<(), Ics02ClientError> { + cf_guest_upstream::proof::verify( + &[], + proof.as_bytes(), + root.bytes.as_slice(), + path, + value.as_deref(), + ) + .map_err(|err| Ics02ClientError::implementation_specific(err.to_string())) +} + +// Conversion between old and new. + +fn convert>(value: F) -> T { + T::convert(value) +} + +trait ConvertFrom: Sized { + fn convert(value: From) -> Self; +} + +macro_rules! conv { + ($( $value:ident: $From:ty => $To:ty { $($body:tt)*} )*) => { + $( + impl ConvertFrom<$From> for $To { + fn convert($value: $From) -> Self { + Self::convert(&$value) + } + } + + impl ConvertFrom<&$From> for $To { + fn convert($value: &$From) -> Self { + $($body)* + } + } + )* + } +} + +conv! { + client_id: ibc::core::ics24_host::identifier::ClientId => + ibc_core_host_types::identifiers::ClientId { + FromStr::from_str(client_id.as_str()).unwrap() + } + client_id: ibc_core_host_types::identifiers::ClientId => ibc::core::ics24_host::identifier::ClientId { + FromStr::from_str(client_id.as_str()).unwrap() + } + + connection_id: ibc::core::ics24_host::identifier::ConnectionId => + ibc_core_host_types::identifiers::ConnectionId { + FromStr::from_str(connection_id.as_str()).unwrap() + } + + port_id: ibc::core::ics24_host::identifier::PortId => + ibc_core_host_types::identifiers::PortId { + FromStr::from_str(port_id.as_str()).unwrap() + } + + channel_id: ibc::core::ics24_host::identifier::ChannelId => + ibc_core_host_types::identifiers::ChannelId { + ibc_core_host_types::identifiers::ChannelId::new(channel_id.sequence()) + } + + + timestamp: ibc::timestamp::Timestamp => ibc_primitives::Timestamp { + Self::from_nanoseconds(timestamp.nanoseconds()).unwrap() + } + + height: ibc::core::ics02_client::height::Height => ibc_core_client_types::Height { + Self::new(height.revision_number, height.revision_height).unwrap() + } + + height: ibc_core_client_types::Height => ibc::core::ics02_client::height::Height { + Self::new(height.revision_number(), height.revision_height()) + } + + + err: ibc_core_client_context::types::error::ClientError => Ics02ClientError { + // TODO(mina86): Create better mapping. + Self::implementation_specific(err.to_string()) + } + err: Ics02ClientError => ibc_core_client_context::types::error::ClientError { + // TODO(mina86): Create better mapping. + Self::ClientSpecific { + description: err.to_string() + } + } +} + +impl> ConvertFrom> for Option { + fn convert(value: Option) -> Self { + value.map(convert) + } +} + +impl, TE: ConvertFrom> ConvertFrom> + for Result +{ + fn convert(value: Result) -> Self { + value.map(convert).map_err(convert) + } +} diff --git a/light-clients/icsxx-cf-solana/src/client_impls.rs b/light-clients/icsxx-cf-solana/src/client_impls.rs new file mode 100644 index 000000000..a1fe79326 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/client_impls.rs @@ -0,0 +1,363 @@ +use alloc::{string::ToString, vec::Vec}; + +use guestchain::PubKey; +use prost::DecodeError; + +use super::{proof, Any, ClientMessage, ClientState, ConsensusState, Header, Misbehaviour}; + +mod ibc { + // pub use ibc::core::ics02_client::client_state::{ + // ClientStateCommon, ClientStateExecution, ClientStateValidation, + // }; + pub use ibc::core::ics02_client::{ + client_state::Status, error::Error as ClientError, height::Height, + }; + // pub use ibc::core::ics02_client::context::{ + // ClientExecutionContext, ClientValidationContext, + // }; + pub use ibc::core::{ + ics23_commitment::{ + commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}, + error::Error as CommitmentError, + }, + ics24_host::{identifier::ClientId, path, Path::ClientType}, + }; + // pub use ibc::core::ics24_host::{ExecutionContext, ValidationContext}; + pub use ibc::timestamp::Timestamp; +} + +type Result = ::core::result::Result; + +pub trait CommonContext { + type ConversionError: ToString; + type AnyConsensusState: TryInto + + From; + + fn host_metadata(&self) -> Result<(ibc::Timestamp, ibc::Height)>; + + fn consensus_state( + &self, + client_id: &ibc::ClientId, + height: ibc::Height, + ) -> Result; + + fn store_consensus_state_and_metadata( + &mut self, + client_id: &ibc::ClientId, + height: ibc::Height, + consensus: Self::AnyConsensusState, + host_timestamp: ibc::Timestamp, + host_height: ibc::Height, + ) -> Result; + + fn delete_consensus_state_and_metadata( + &mut self, + client_id: &ibc::ClientId, + height: ibc::Height, + ) -> Result; + + fn sorted_consensus_state_heights(&self, client_id: &ibc::ClientId) + -> Result>; +} + +// impl ibc::ClientStateCommon for ClientState { +// fn verify_consensus_state(&self, consensus_state: Any) -> Result { +// ConsensusState::try_from(consensus_state)?; +// Ok(()) +// } + +// fn client_type(&self) -> ibc::ClientType { +// ibc::ClientType::new(super::CLIENT_TYPE).unwrap() +// } + +// fn latest_height(&self) -> ibc::Height { +// ibc::Height::new(0, self.latest_height.into()).unwrap() +// } + +// fn validate_proof_height(&self, proof_height: ibc::Height) -> Result { +// let latest_height = self.latest_height(); +// if proof_height <= latest_height { +// Ok(()) +// } else { +// Err(ibc::ClientError::InvalidProofHeight { +// latest_height, +// proof_height, +// }) +// } +// } + +// /// Panics since client upgrades aren’t supported. +// fn verify_upgrade_client( +// &self, +// _upgraded_client_state: Any, +// _upgraded_consensus_state: Any, +// _proof_upgrade_client: ibc::CommitmentProofBytes, +// _proof_upgrade_consensus_state: ibc::CommitmentProofBytes, +// _root: &ibc::CommitmentRoot, +// ) -> Result { unimplemented!("IBC cilent upgrades are currently not supported") +// } + +// /// Verifies membership proof. +// /// +// /// See [`proof::verify`] for documentation of the proof format. +// fn verify_membership( +// &self, +// prefix: &ibc::CommitmentPrefix, +// proof: &ibc::CommitmentProofBytes, +// root: &ibc::CommitmentRoot, +// path: ibc::path::Path, +// value: Vec, +// ) -> Result { let value = Some(value.as_slice()); proof::verify(prefix, proof, root, path, +// value).map_err(Into::into) +// } + +// /// Verifies membership proof. +// /// +// /// See [`proof::verify`] for documentation of the proof format. +// fn verify_non_membership( +// &self, +// prefix: &ibc::CommitmentPrefix, +// proof: &ibc::CommitmentProofBytes, +// root: &ibc::CommitmentRoot, +// path: ibc::path::Path, +// ) -> Result { proof::verify(prefix, proof, root, path, None).map_err(Into::into) +// } +// } + +impl From for ibc::ClientError { + fn from(err: proof::VerifyError) -> Self { + use ::ibc::core::ics23_commitment::error::Error; + use proof::VerifyError::*; + + Self::invalid_commitment_proof(match err { + ProofDecodingFailure(msg) => + Error::commitment_proof_decoding_failed(DecodeError::new(msg)), + WrongSequenceNumber(err) => Error::commitment_proof_decoding_failed(err), + _ => ibc::CommitmentError::invalid_merkle_proof(), + }) + } +} + +// impl ibc::ClientStateExecution for ClientState +// where +// E: ibc::ExecutionContext + ibc::ClientExecutionContext + CommonContext, +// ::AnyClientState: From>, +// ::AnyConsensusState: From, +// { +// fn initialise( +// &self, +// ctx: &mut E, +// client_id: &ibc::ClientId, +// consensus_state: Any, +// ) -> Result { parse_client_id(client_id)?; let consensus_state = +// super::ConsensusState::try_from(consensus_state)?; + +// ctx.store_client_state( +// ibc::path::ClientStatePath::new(client_id.clone()), +// self.clone().into(), +// )?; +// ctx.store_consensus_state( +// ibc::path::ClientConsensusStatePath::new( +// client_id.clone(), +// 0, +// u64::from(self.latest_height), +// ), +// consensus_state.into(), +// )?; + +// Ok(()) +// } + +// fn update_state( +// &self, +// ctx: &mut E, +// client_id: &ibc::ClientId, +// header: Any, +// ) -> Result> { let header = crate::proto::Header::try_from(header)?; let +// header = crate::Header::::try_from(header)?; let header_height = ibc::Height::new(0, +// header.block_header.block_height.into())?; + +// let (host_timestamp, host_height) = CommonContext::host_metadata(ctx)?; +// self.prune_oldest_consensus_state(ctx, client_id, host_timestamp)?; + +// let maybe_existing_consensus = +// CommonContext::consensus_state(ctx, client_id, header_height).ok(); +// if maybe_existing_consensus.is_none() { +// let new_consensus_state = ConsensusState::from(&header); +// let new_client_state = self.with_header(&header); + +// ctx.store_client_state( +// ibc::path::ClientStatePath::new(client_id.clone()), +// new_client_state.into(), +// )?; +// ctx.store_consensus_state_and_metadata( +// client_id, +// header_height, +// new_consensus_state.into(), +// host_timestamp, +// host_height, +// )?; +// } + +// Ok(alloc::vec![header_height]) +// } + +// fn update_state_on_misbehaviour( +// &self, +// ctx: &mut E, +// client_id: &ibc::ClientId, +// _client_message: Any, +// ) -> Result { ctx.store_client_state( ibc::path::ClientStatePath::new(client_id.clone()), +// self.frozen().into(), )?; Ok(()) +// } + +// fn update_state_on_upgrade( +// &self, +// _ctx: &mut E, +// _client_id: &ibc::ClientId, +// _upgraded_client_state: Any, +// _upgraded_consensus_state: Any, +// ) -> Result { Err(ibc::UpgradeClientError::Other { reason: "upgrade not +// supported".into(), } .into()) +// } +// } + +// impl ibc::ClientStateValidation for ClientState +// where +// V: ibc::ValidationContext +// + ibc::ClientValidationContext +// + CommonContext +// + guestchain::Verifier, +// { +// fn verify_client_message( +// &self, +// ctx: &V, +// client_id: &ibc::ClientId, +// client_message: Any, +// ) -> Result { self.verify_client_message(ctx, client_id, client_message) +// } + +// fn check_for_misbehaviour( +// &self, +// ctx: &V, +// client_id: &ibc::ClientId, +// client_message: Any, +// ) -> Result { self.check_for_misbehaviour(ctx, client_id, client_message) +// } + +// fn status( +// &self, +// ctx: &V, +// client_id: &ibc::ClientId, +// ) -> Result { if self.is_frozen { return Ok(ibc::Status::Frozen); } + +// let height = ibc::Height::new(0, self.latest_height.into())?; +// let consensus = CommonContext::consensus_state(ctx, client_id, height) +// .and_then(|state| state.try_into().map_err(error)); +// let consensus = match consensus { +// Ok(consensus) => consensus, +// Err(ibc::ClientError::ConsensusStateNotFound { .. }) => { +// return Ok(ibc::Status::Expired) +// } +// Err(err) => return Err(err), +// }; + +// let (host_timestamp, _height) = CommonContext::host_metadata(ctx)?; +// Ok(if self.consensus_has_expired(&consensus, host_timestamp) { +// ibc::Status::Expired +// } else { +// ibc::Status::Active +// }) +// } +// } + +impl ClientState { + pub fn verify_client_message( + &self, + ctx: &impl guestchain::Verifier, + _client_id: &ibc::ClientId, + client_message: ClientMessage, + ) -> Result<()> { + match client_message { + ClientMessage::Header(header) => self.verify_header(ctx, header), + ClientMessage::Misbehaviour(misbehaviour) => + self.verify_misbehaviour(ctx, misbehaviour), + } + } + + pub fn check_for_misbehaviour( + &self, + ctx: &impl guestchain::Verifier, + _client_id: &ibc::ClientId, + client_message: Any, + ) -> Result { + match ClientMessage::::try_from(client_message)? { + ClientMessage::Header(header) => self.check_for_misbehaviour_header(ctx, header), + ClientMessage::Misbehaviour(misbehaviour) => + self.check_for_misbehaviour_misbehavior(ctx, misbehaviour), + } + } + + fn verify_header(&self, ctx: &impl guestchain::Verifier, header: Header) -> Result<()> { + (|| { + // panic!("header epoch {:?} and client epoch {:?}", header.epoch_commitment, + // self.epoch_commitment); + if header.epoch_commitment != self.epoch_commitment { + return Err("Unexpected epoch") + } + let fp = guestchain::block::Fingerprint::from_hash( + &header.genesis_hash, + header.block_header.block_height, + &header.block_hash, + ); + let mut quorum_left = header.epoch.quorum_stake().get(); + let mut validators = + header.epoch.validators().iter().map(Some).collect::>>(); + for (idx, sig) in header.signatures { + let validator = validators + .get_mut(usize::from(idx)) + .ok_or("Validator index out of bounds")? + .take() + .ok_or("Duplicate signature")?; + if !ctx.verify(fp.as_slice(), &validator.pubkey, &sig) { + return Err("Bad signature") + } + quorum_left = quorum_left.saturating_sub(validator.stake.get()); + if quorum_left == 0 { + break + } + } + Ok(()) + // Err("Quorum not reached") + })() + .map_err(error) + } + + fn verify_misbehaviour( + &self, + _ctx: &impl guestchain::Verifier, + _misbehaviour: Misbehaviour, + ) -> Result<()> { + todo!() + } + + fn check_for_misbehaviour_header( + &self, + _ctx: &impl guestchain::Verifier, + _header: Header, + ) -> Result { + Ok(false) + } + + fn check_for_misbehaviour_misbehavior( + &self, + _ctx: &impl guestchain::Verifier, + _misbehaviour: Misbehaviour, + ) -> Result { + todo!() + } +} + +fn error(msg: impl ToString) -> ibc::ClientError { + ibc::ClientError::implementation_specific(msg.to_string()) +} diff --git a/light-clients/icsxx-cf-solana/src/consensus.rs b/light-clients/icsxx-cf-solana/src/consensus.rs new file mode 100644 index 000000000..8d0c5a60f --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/consensus.rs @@ -0,0 +1,97 @@ +use core::{convert::Infallible, num::NonZeroU64}; + +use lib::hash::CryptoHash; +use prost::Message as _; + +use crate::proto; + +super::wrap!(cf_guest_upstream::ConsensusState as ConsensusState); +super::wrap!(impl Eq for ConsensusState); +super::wrap!(impl proto for ConsensusState); + +impl ConsensusState { + pub fn new(block_hash: &CryptoHash, timestamp_ns: NonZeroU64) -> Self { + Self(cf_guest_upstream::ConsensusState::new(block_hash, timestamp_ns)) + } +} + +impl ibc::core::ics02_client::client_consensus::ConsensusState for ConsensusState { + type Error = Infallible; + + fn root(&self) -> &ibc::core::ics23_commitment::commitment::CommitmentRoot { + // SAFETY: Both types are wrappers around Vec. + unsafe { core::mem::transmute(&self.0.block_hash) } + } + + fn timestamp(&self) -> ibc::timestamp::Timestamp { + ibc::timestamp::Timestamp::from_nanoseconds(self.0.timestamp_ns.get()).unwrap() + } + + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + Ok(proto::ConsensusState::from(self).encode_to_vec()) + } +} + +impl From> for ConsensusState { + fn from(header: crate::Header) -> Self { + Self::from(&header.0) + } +} + +impl From<&crate::Header> for ConsensusState { + fn from(header: &crate::Header) -> Self { + Self::from(&header.0) + } +} + +impl From> for ConsensusState { + fn from(header: cf_guest_upstream::Header) -> Self { + Self::from(&header) + } +} + +impl From<&cf_guest_upstream::Header> for ConsensusState { + fn from(header: &cf_guest_upstream::Header) -> Self { + Self(header.into()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + const ANY_MESSAGE: [u8; 85] = [ + 10, 37, 47, 108, 105, 103, 104, 116, 99, 108, 105, 101, 110, 116, 115, 46, 103, 117, 101, + 115, 116, 46, 118, 49, 46, 67, 111, 110, 115, 101, 110, 115, 117, 115, 83, 116, 97, 116, + 101, 18, 44, 10, 32, 74, 147, 61, 207, 26, 96, 73, 253, 54, 118, 91, 237, 36, 210, 58, 218, + 179, 236, 158, 187, 5, 231, 241, 133, 178, 150, 85, 151, 36, 160, 36, 105, 16, 128, 220, + 164, 128, 131, 220, 190, 228, 23, + ]; + + fn message() -> &'static [u8] { + &ANY_MESSAGE[41..] + } + + const BLOCK_HASH: CryptoHash = CryptoHash([ + 74, 147, 61, 207, 26, 96, 73, 253, 54, 118, 91, 237, 36, 210, 58, 218, 179, 236, 158, 187, + 5, 231, 241, 133, 178, 150, 85, 151, 36, 160, 36, 105, + ]); + + fn check(state: ConsensusState) { + let want = ConsensusState::new(&BLOCK_HASH, NonZeroU64::new(1713895499000000000).unwrap()); + assert_eq!(want, state); + } + + #[test] + fn test_decode_vec() { + check(ibc::protobuf::Protobuf::decode_vec(message()).unwrap()); + } + + #[test] + fn test_from_any() { + use ibc_proto::google::protobuf::Any; + + let any: Any = prost::Message::decode(ANY_MESSAGE.as_ref()).unwrap(); + check(any.try_into().unwrap()); + } +} diff --git a/light-clients/icsxx-cf-solana/src/error.rs b/light-clients/icsxx-cf-solana/src/error.rs new file mode 100644 index 000000000..7c6cee943 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/error.rs @@ -0,0 +1,43 @@ +// Copyright 2022 ComposableFi +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::CLIENT_TYPE; +use alloc::{ + fmt, + string::{String, ToString}, +}; +use ibc::{core::ics24_host::identifier::ClientId, timestamp::Timestamp, Height}; + +#[derive(Clone, Debug)] +pub enum Error { + ProcessedHeightNotFound { height: Height }, + ProcessedTimeNotFound { height: Height }, + NotEnoughTimeElapsed { current_time: Timestamp, earliest_time: u64 }, + NotEnoughBlocksElapsed { current_height: Height, earliest_height: u64 }, + InsufficientHeight { latest_height: Height, target_height: Height }, + ClientFrozen { client_id: ClientId }, + UnknownConsensusStateType { description: String }, +} + +impl fmt::Display for Error { + fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(self, fmtr) + } +} + +impl From for ibc::core::ics02_client::error::Error { + fn from(err: Error) -> Self { + Self::client_error(CLIENT_TYPE.into(), err.to_string()) + } +} diff --git a/light-clients/icsxx-cf-solana/src/header.rs b/light-clients/icsxx-cf-solana/src/header.rs new file mode 100644 index 000000000..ae4ee2458 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/header.rs @@ -0,0 +1,2 @@ +super::wrap!(cf_guest_upstream::Header as Header); +super::wrap!(impl proto for Header); diff --git a/light-clients/icsxx-cf-solana/src/lib.rs b/light-clients/icsxx-cf-solana/src/lib.rs new file mode 100644 index 000000000..56b4fc564 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/lib.rs @@ -0,0 +1,243 @@ +#![allow(clippy::unit_arg, clippy::comparison_chain)] +#![no_std] +extern crate alloc; +// #[cfg(any(feature = "std", test))] +extern crate std; + +use alloc::string::ToString; + +pub mod client; +pub mod client_def; +mod consensus; +pub mod error; +mod header; +mod message; +mod misbehaviour; +pub mod proof; +pub mod proto; + +pub use client::ClientState; +pub use consensus::ConsensusState; +pub use header::Header; +pub use message::ClientMessage; +pub use misbehaviour::Misbehaviour; + +use ibc::core::ics02_client::error::Error as ClientError; + +/// Client type of the guest blockchain’s light client. +pub const CLIENT_TYPE: &str = "cf-guest"; + +pub use crate::proto::{BadMessage, DecodeError}; + +impl From for ClientError { + fn from(err: DecodeError) -> Self { + ClientError::implementation_specific(err.to_string()) + } +} + +impl From for ClientError { + fn from(_: BadMessage) -> Self { + ClientError::implementation_specific("BadMessage".to_string()) + } +} + +/// Returns digest of the value. +/// +/// This is used, among other places, as packet commitment. +#[inline] +pub fn digest(value: &[u8]) -> lib::hash::CryptoHash { + lib::hash::CryptoHash::digest(value) +} + +/// Returns digest of the value with client id mixed in. +/// +/// We don’t store full client id in the trie key for paths which include +/// client id. To avoid accepting malicious proofs, we must include it in +/// some other way. We do this by mixing in the client id into the hash of +/// the value stored at the path. +/// +/// Specifically, this calculates `digest(client_id || b'0' || serialised)`. +#[inline] +pub fn digest_with_client_id( + client_id: &ibc::core::ics24_host::identifier::ClientId, + value: &[u8], +) -> lib::hash::CryptoHash { + lib::hash::CryptoHash::digestv(&[client_id.as_bytes(), b"\0", value]) +} + +macro_rules! wrap { + ($($Inner:ident)::* as $Outer:ident) => { + #[derive(Clone, derive_more::From, derive_more::Into)] + #[repr(transparent)] + pub struct $Outer(pub $($Inner)::*); + + impl core::fmt::Debug for $Outer { + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(fmtr) + } + } + + impl From<$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: $Outer) -> Self { + Self::from(&msg) + } + } + + impl From<&$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: &$Outer) -> Self { + let any = cf_guest_upstream::proto::Any::from(&msg.0); + Self { + type_url: any.type_url, + value: any.value + } + } + } + + impl TryFrom for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: ibc_proto::google::protobuf::Any) -> Result { + Self::try_from(&any) + } + } + + impl TryFrom<&ibc_proto::google::protobuf::Any> for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: &ibc_proto::google::protobuf::Any) -> Result { + Ok(Self(cf_guest_upstream::proto::AnyConvert::try_from_any(&any.type_url, &any.value)?)) + } + } + }; + + ($($Inner:ident)::* as $Outer:ident) => { + #[derive(Clone, PartialEq, Eq, derive_more::From, derive_more::Into)] + #[repr(transparent)] + pub struct $Outer(pub $($Inner)::*); + + impl core::fmt::Debug for $Outer { + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + self.0.fmt(fmtr) + } + } + + impl From<$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: $Outer) -> Self { + Self::from(&msg) + } + } + + impl From<&$Outer> for ibc_proto::google::protobuf::Any { + fn from(msg: &$Outer) -> Self { + let any = cf_guest_upstream::proto::Any::from(&msg.0); + Self { + type_url: any.type_url, + value: any.value + } + } + } + + impl TryFrom for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: ibc_proto::google::protobuf::Any) -> Result { + Self::try_from(&any) + } + } + + impl TryFrom<&ibc_proto::google::protobuf::Any> for $Outer { + type Error = $crate::DecodeError; + fn try_from(any: &ibc_proto::google::protobuf::Any) -> Result { + Ok(Self(cf_guest_upstream::proto::AnyConvert::try_from_any(&any.type_url, &any.value)?)) + } + } + }; + + (impl Default for $Outer:ident) => { + impl Default for $Outer { + fn default() -> Self { Self(Default::default()) } + } + }; + + (impl Default for $Outer:ident) => { + impl Default for $Outer { + fn default() -> Self { Self(Default::default()) } + } + }; + + (impl Eq for $Outer:ident) => { + impl core::cmp::PartialEq for $Outer { + fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) } + } + impl core::cmp::Eq for $Outer { } + }; + + (impl proto for $Type:ident) => { + impl $crate::proto::$Type { + pub const IBC_TYPE_URL: &'static str = + cf_guest_upstream::proto::$Type::IBC_TYPE_URL; + } + + impl From<$Type> for $crate::proto::$Type { + fn from(msg: $Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl From<&$Type> for $crate::proto::$Type { + fn from(msg: &$Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl TryFrom<$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: $crate::proto::$Type) -> Result { + Self::try_from(&msg) + } + } + + impl TryFrom<&$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: &$crate::proto::$Type) -> Result { + Ok(Self(cf_guest_upstream::$Type::try_from(&msg.0)?)) + } + } + + impl ibc::protobuf::Protobuf<$crate::proto::$Type> for $Type {} + }; + + (impl proto for $Type:ident) => { + impl $crate::proto::$Type { + pub const IBC_TYPE_URL: &'static str = + cf_guest_upstream::proto::$Type::IBC_TYPE_URL; + } + + impl From<$Type> for $crate::proto::$Type { + fn from(msg: $Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl From<&$Type> for $crate::proto::$Type { + fn from(msg: &$Type) -> Self { + Self(cf_guest_upstream::proto::$Type::from(&msg.0)) + } + } + + impl TryFrom<$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: $crate::proto::$Type) -> Result { + Self::try_from(&msg) + } + } + + impl TryFrom<&$crate::proto::$Type> for $Type { + type Error = $crate::proto::BadMessage; + fn try_from(msg: &$crate::proto::$Type) -> Result { + Ok(Self(cf_guest_upstream::$Type::try_from(&msg.0)?)) + } + } + + impl ibc::protobuf::Protobuf<$crate::proto::$Type> for $Type {} + }; +} + +use wrap; diff --git a/light-clients/icsxx-cf-solana/src/message.rs b/light-clients/icsxx-cf-solana/src/message.rs new file mode 100644 index 000000000..ad3a89487 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/message.rs @@ -0,0 +1,52 @@ +use guestchain::PubKey; +use prost::Message as _; + +use crate::proto; + +super::wrap!(cf_guest_upstream::ClientMessage as ClientMessage); +super::wrap!(impl proto for ClientMessage); + +impl ClientMessage { + pub fn maybe_header_height(&self) -> Option { + if let cf_guest_upstream::ClientMessage::Header(hdr) = &self.0 { + let height = hdr.block_header.block_height; + Some(ibc::Height::new(1, height.into())) + } else { + None + } + } +} + +impl ibc::core::ics02_client::client_message::ClientMessage for ClientMessage +where + PK: PubKey + Send + Sync, + PK::Signature: Send + Sync, +{ + fn encode_to_vec(&self) -> Result, ibc::protobuf::Error> { + Ok(proto::ClientMessage::from(self).encode_to_vec()) + } +} + +impl From> for ClientMessage { + fn from(hdr: cf_guest_upstream::Header) -> Self { + Self(cf_guest_upstream::ClientMessage::Header(hdr)) + } +} + +impl From> for ClientMessage { + fn from(hdr: crate::Header) -> Self { + Self(cf_guest_upstream::ClientMessage::Header(hdr.0)) + } +} + +impl From> for ClientMessage { + fn from(msg: cf_guest_upstream::Misbehaviour) -> Self { + Self(cf_guest_upstream::ClientMessage::Misbehaviour(msg)) + } +} + +impl From> for ClientMessage { + fn from(msg: crate::Misbehaviour) -> Self { + Self(cf_guest_upstream::ClientMessage::Misbehaviour(msg.0)) + } +} diff --git a/light-clients/icsxx-cf-solana/src/misbehaviour.rs b/light-clients/icsxx-cf-solana/src/misbehaviour.rs new file mode 100644 index 000000000..af592f747 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/misbehaviour.rs @@ -0,0 +1,2 @@ +super::wrap!(cf_guest_upstream::Misbehaviour as Misbehaviour); +super::wrap!(impl proto for Misbehaviour); diff --git a/light-clients/icsxx-cf-solana/src/proof.rs b/light-clients/icsxx-cf-solana/src/proof.rs new file mode 100644 index 000000000..4966ce4c6 --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/proof.rs @@ -0,0 +1,195 @@ +use core::str::FromStr; + +use guestchain::BlockHeader; +use ibc_core_host_types::path::{ + AckPath, ChannelEndPath, ClientConnectionPath, CommitmentPath, ConnectionPath, PortPath, + ReceiptPath, SeqAckPath, SeqRecvPath, SeqSendPath, +}; + +mod ibc { + pub use ibc::core::{ + ics02_client::error::Error as ClientError, + ics04_channel::packet::Sequence, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot}, + ics24_host::{ + identifier, + identifier::{ChannelId, ClientId, ConnectionId, PortId}, + path, + }, + }; +} + +pub use cf_guest_upstream::proof::{GenerateError, IbcProof, VerifyError}; + +/// Generates a proof for given path. +/// +/// `block_header` is header whose hash will be the commitment root. It’s +/// state root must correspond to `trie`’s root. `path` specifies IBC path +/// of the value that needs proof. +/// +/// # Proof format +/// +/// In most cases, proof is Borsh-serialised `(guestchain::BlockHeader, +/// sealable_trie::proof::Proof)` pair. The header at the front is necessary to +/// determine state root (recall that `root` is the block hash and not state +/// root). +/// +/// However, if `path` is one of `SeqSend`, `SeqRecv` or `SeqAck` than proof +/// further contain two big-endian encoded `u64` numbers holding the other +/// two sequence numbers. +/// +/// For example, if `path` is `SeqRecv`, the `proof` must at the end include +/// send sequence number and ack sequence number. For example, if next send +/// sequence is `7`, next ack sequence is `5` and path is `SeqRecv` the +/// proof will end with `be(7) || be(5)` (where `be` denotes encoding 64-bit +/// number as big endian). +/// +/// This addition is necessary because sequence numbers are stored together +/// within a single trie value. For example, proving the next receive +/// sequence is `4` requires proving `be(7), be(4), be(5), be(0)]. For +/// verifier to know what value it checks, it needs to be provided all of +/// the sequence numbers. +/// +/// (Note that Borsh uses little endian to encode integers so the sequence +/// numbers cannot be simply borsh deserialised.) +pub fn generate( + block_header: &BlockHeader, + trie: &sealable_trie::Trie, + path: ibc::path::Path, +) -> Result { + let path = convert_old_path_to_new(path); + cf_guest_upstream::proof::generate(block_header, trie, path) +} + +/// Verifies a proof for given entry or lack of entry. +/// +/// `prefix` must be empty, `proof` and `root` must follow format described in +/// [`generate`] function. `path` indicates IBC path the proof is for and +/// `value` determines value or lack thereof expected at the path. +/// +/// # Value hash +/// +/// Since sealable trie doesn’t store values but only hashes, when verifying +/// membership proofs the value needs to be converted into a hash. There are +/// three cases: +/// +/// 1. If `path` includes client id, the hash of the value is calculated with the client id mixed +/// in; see [`super::digest_with_client_id`] function. +/// +/// 2. If `path` is `SeqSend`, `SeqRecv` or `SeqAck`, the `value` must be +/// `google.protobuf.UInt64Value` protobuf and hash is calculated as concatenation of the three +/// sequence numbers as described in [`generate`]. +/// +/// 3. Otherwise, the value is simply hashed. +pub fn verify( + prefix: &ibc::CommitmentPrefix, + proof: &ibc::CommitmentProofBytes, + root: &ibc::CommitmentRoot, + path: ibc::path::Path, + value: Option<&[u8]>, +) -> Result<(), VerifyError> { + verify_bytes(prefix.as_bytes(), proof.as_bytes(), root.as_bytes(), path, value) +} + +/// Verifies a proof for given entry or lack of entry. +/// +/// Like [`verify`] but takes slice arguments rather than IBC types. +pub fn verify_bytes( + prefix: &[u8], + proof: &[u8], + root: &[u8], + path: ibc::path::Path, + value: Option<&[u8]>, +) -> Result<(), VerifyError> { + cf_guest_upstream::proof::verify(prefix, proof, root, convert_old_path_to_new(path), value) +} + +fn convert_old_path_to_new(path: ibc::path::Path) -> ibc_core_host_types::path::Path { + match path { + ::ibc::core::ics24_host::Path::ClientType(_) => panic!("Not supported"), + ::ibc::core::ics24_host::Path::ClientState(e) => + ibc_core_host_types::path::Path::ClientState( + ibc_core_host_types::path::ClientStatePath( + ibc_core_host_types::identifiers::ClientId::from_str(e.0.as_str()).unwrap(), + ), + ), + ::ibc::core::ics24_host::Path::ClientConsensusState(e) => + ibc_core_host_types::path::Path::ClientConsensusState( + ibc_core_host_types::path::ClientConsensusStatePath { + client_id: ibc_core_host_types::identifiers::ClientId::from_str( + e.client_id.as_str(), + ) + .unwrap(), + revision_number: e.epoch, + revision_height: e.height, + }, + ), + ::ibc::core::ics24_host::Path::ClientConnections(e) => + ibc_core_host_types::path::Path::ClientConnection(ClientConnectionPath( + ibc_core_host_types::identifiers::ClientId::from_str(e.0.as_str()).unwrap(), + )), + ::ibc::core::ics24_host::Path::Connections(e) => + ibc_core_host_types::path::Path::Connection(ConnectionPath( + ibc_core_host_types::identifiers::ConnectionId::from_str(e.0.as_str()).unwrap(), + )), + ::ibc::core::ics24_host::Path::Ports(e) => ibc_core_host_types::path::Path::Ports( + PortPath(ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap()), + ), + ::ibc::core::ics24_host::Path::ChannelEnds(e) => + ibc_core_host_types::path::Path::ChannelEnd(ChannelEndPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::SeqSends(e) => + ibc_core_host_types::path::Path::SeqSend(SeqSendPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::SeqRecvs(e) => + ibc_core_host_types::path::Path::SeqRecv(SeqRecvPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::SeqAcks(e) => + ibc_core_host_types::path::Path::SeqAck(SeqAckPath( + ibc_core_host_types::identifiers::PortId::from_str(e.0.as_str()).unwrap(), + ibc_core_host_types::identifiers::ChannelId::new(e.1.sequence()), + )), + ::ibc::core::ics24_host::Path::Commitments(e) => + ibc_core_host_types::path::Path::Commitment(CommitmentPath { + port_id: ibc_core_host_types::identifiers::PortId::from_str(e.port_id.as_str()) + .unwrap(), + channel_id: ibc_core_host_types::identifiers::ChannelId::new( + e.channel_id.sequence(), + ), + sequence: u64::from(e.sequence.0).into(), + }), + ::ibc::core::ics24_host::Path::Acks(e) => ibc_core_host_types::path::Path::Ack(AckPath { + port_id: ibc_core_host_types::identifiers::PortId::from_str(e.port_id.as_str()) + .unwrap(), + channel_id: ibc_core_host_types::identifiers::ChannelId::new(e.channel_id.sequence()), + sequence: u64::from(e.sequence.0).into(), + }), + ::ibc::core::ics24_host::Path::Receipts(e) => + ibc_core_host_types::path::Path::Receipt(ReceiptPath { + port_id: ibc_core_host_types::identifiers::PortId::from_str(e.port_id.as_str()) + .unwrap(), + channel_id: ibc_core_host_types::identifiers::ChannelId::new( + e.channel_id.sequence(), + ), + sequence: u64::from(e.sequence.0).into(), + }), + ::ibc::core::ics24_host::Path::Upgrade(path) => { + use ::ibc::core::ics24_host::ClientUpgradePath; + use ibc_core_host_types::path::UpgradeClientPath; + match path { + ClientUpgradePath::UpgradedClientState(height) => + UpgradeClientPath::UpgradedClientState(height), + ClientUpgradePath::UpgradedClientConsensusState(height) => + UpgradeClientPath::UpgradedClientConsensusState(height), + } + .into() + }, + ::ibc::core::ics24_host::Path::Outside(e) => panic!("Not supported {:?}", e), + } +} diff --git a/light-clients/icsxx-cf-solana/src/proto.rs b/light-clients/icsxx-cf-solana/src/proto.rs new file mode 100644 index 000000000..01e5cffca --- /dev/null +++ b/light-clients/icsxx-cf-solana/src/proto.rs @@ -0,0 +1,136 @@ +use alloc::string::ToString; + +macro_rules! import_proto { + ($Msg:ident) => { + $crate::wrap!(cf_guest_upstream::proto::$Msg as $Msg); + $crate::wrap!(impl Default for $Msg); + + impl prost::Message for $Msg { + fn encode_raw(&self, buf: &mut B) { + prost_12::Message::encode_raw(&self.0, buf) + } + + fn merge_field( + &mut self, + tag: u32, + wire_type: prost::encoding::WireType, + buf: &mut B, + _ctx: prost::encoding::DecodeContext, + ) -> Result<(), prost::DecodeError> { + // SAFETY: The types are identical in prost 0.11 and prost.12. + let wire_type = unsafe { + core::mem::transmute(wire_type as u8) + }; + prost_12::Message::merge_field(&mut self.0, tag, wire_type, buf, Default::default()) + .map_err(|err| { + // SAFETY: The types are identical in prost 0.11 and prost.12. + unsafe { + core::mem::transmute(err) + } + }) + } + + fn encoded_len(&self) -> usize { + prost_12::Message::encoded_len(&self.0) + } + + fn clear(&mut self) { + prost_12::Message::clear(&mut self.0) + } + } + } +} + +import_proto!(ClientMessage); +import_proto!(ClientState); +import_proto!(ConsensusState); +import_proto!(Header); +import_proto!(Misbehaviour); +import_proto!(Signature); + +/// Error during decoding of a protocol message. +#[derive(Clone, PartialEq, Eq, derive_more::From)] +pub enum DecodeError { + /// Failed decoding the wire encoded protocol message. + /// + /// This means that the supplied bytes weren’t a valid protocol buffer or + /// they didn’t correspond to the expected message. + BadProto(alloc::string::String), + + /// Protocol message represents invalid state; see [`BadMessage`]. + #[from(ignore)] + BadMessage, + + /// When decoding an `Any` message, the type URL doesn’t equal the expected + /// one. + #[from(ignore)] + BadType, +} + +impl From for DecodeError { + fn from(err: cf_guest_upstream::DecodeError) -> Self { + match err { + cf_guest_upstream::DecodeError::BadProto(err) => Self::BadProto(err.to_string()), + cf_guest_upstream::DecodeError::BadMessage => Self::BadMessage, + cf_guest_upstream::DecodeError::BadType => Self::BadType, + } + } +} + +/// Error during validation of a protocol message. +/// +/// Typing in protocol messages is less descriptive than in Rust. It’s possible +/// to represent state in the protocol message which doesn’t correspond to +/// a valid state. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub struct BadMessage; + +impl From for BadMessage { + fn from(_: cf_guest_upstream::BadMessage) -> Self { + Self + } +} + +impl From for DecodeError { + fn from(_: BadMessage) -> Self { + Self::BadMessage + } +} + +impl core::fmt::Debug for DecodeError { + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + match self { + Self::BadProto(err) => err.fmt(fmtr), + Self::BadMessage => fmtr.write_str("BadMessage"), + Self::BadType => fmtr.write_str("BadType"), + } + } +} + +impl core::fmt::Display for DecodeError { + #[inline] + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Debug::fmt(self, fmtr) + } +} + +impl core::fmt::Display for BadMessage { + #[inline] + fn fmt(&self, fmtr: &mut core::fmt::Formatter) -> core::fmt::Result { + core::fmt::Debug::fmt(self, fmtr) + } +} + +impl From
for ClientMessage { + #[inline] + fn from(msg: Header) -> Self { + Self(cf_guest_upstream::proto::ClientMessage::from(msg.0)) + } +} + +impl From for ClientMessage { + #[inline] + fn from(msg: Misbehaviour) -> Self { + Self(cf_guest_upstream::proto::ClientMessage::from(msg.0)) + } +} diff --git a/light-clients/icsxx-solana-cw/src/msg.rs b/light-clients/icsxx-solana-cw/src/msg.rs new file mode 100644 index 000000000..fe5dcc814 --- /dev/null +++ b/light-clients/icsxx-solana-cw/src/msg.rs @@ -0,0 +1,387 @@ +// Copyright (C) 2022 ComposableFi. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::{contract::HostFunctions, ics23::FakeInner, Bytes, ContractError}; +use core::{str::FromStr, time::Duration}; +use cosmwasm_schema::cw_serde; +use ibc::{ + core::{ + ics02_client::trust_threshold::TrustThreshold, + ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes}, + ics24_host::Path, + }, + protobuf::Protobuf, + Height, +}; +use ibc_proto::{google::protobuf::Any, ibc::core::client::v1::Height as HeightRaw}; +use ics07_tendermint::{ + client_message::{ClientMessage, Header, Misbehaviour}, + client_state::ClientState, +}; +use ics08_wasm::{ + client_state::ClientState as WasmClientState, + consensus_state::ConsensusState as WasmConsensusState, +}; +use prost::Message; +use serde::{Deserializer, Serializer}; + +struct Base64; + +impl Base64 { + pub fn serialize(v: &[u8], serializer: S) -> Result { + ibc_proto::base64::serialize(v, serializer) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result, D::Error> { + ibc_proto::base64::deserialize(deserializer) + } +} + +#[cw_serde] +pub struct GenesisMetadata { + pub key: Vec, + pub value: Vec, +} + +#[cw_serde] +pub struct QueryResponse { + pub status: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub genesis_metadata: Option>, +} + +impl QueryResponse { + pub fn status(status: String) -> Self { + Self { status, genesis_metadata: None } + } + + pub fn genesis_metadata(genesis_metadata: Option>) -> Self { + Self { status: "".to_string(), genesis_metadata } + } +} + +#[cw_serde] +pub struct ContractResult { + pub is_valid: bool, + pub error_msg: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub data: Option>, + pub found_misbehaviour: bool, +} + +impl ContractResult { + pub fn success() -> Self { + Self { is_valid: true, error_msg: "".to_string(), data: None, found_misbehaviour: false } + } + + pub fn error(msg: String) -> Self { + Self { is_valid: false, error_msg: msg, data: None, found_misbehaviour: false } + } + + pub fn misbehaviour(mut self, found: bool) -> Self { + self.found_misbehaviour = found; + self + } + + pub fn data(mut self, data: Vec) -> Self { + self.data = Some(data); + self + } +} + +#[cw_serde] +pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + VerifyMembership(VerifyMembershipMsgRaw), + VerifyNonMembership(VerifyNonMembershipMsgRaw), + VerifyClientMessage(VerifyClientMessageRaw), + CheckForMisbehaviour(CheckForMisbehaviourMsgRaw), + UpdateStateOnMisbehaviour(UpdateStateOnMisbehaviourMsgRaw), + UpdateState(UpdateStateMsgRaw), + CheckSubstituteAndUpdateState(CheckSubstituteAndUpdateStateMsg), + VerifyUpgradeAndUpdateState(VerifyUpgradeAndUpdateStateMsgRaw), +} + +#[cw_serde] +pub enum QueryMsg { + ClientTypeMsg(ClientTypeMsg), + GetLatestHeightsMsg(GetLatestHeightsMsg), + ExportMetadata(ExportMetadataMsg), + Status(StatusMsg), +} + +#[cw_serde] +pub struct ClientTypeMsg {} + +#[cw_serde] +pub struct GetLatestHeightsMsg {} + +#[cw_serde] +pub struct StatusMsg {} + +#[cw_serde] +pub struct ExportMetadataMsg {} + +#[cw_serde] +pub struct MerklePath { + pub key_path: Vec, +} + +#[cw_serde] +pub struct VerifyMembershipMsgRaw { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof: Bytes, + pub path: MerklePath, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub value: Bytes, + pub height: HeightRaw, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +pub struct VerifyMembershipMsg { + pub prefix: CommitmentPrefix, + pub proof: CommitmentProofBytes, + pub path: Path, + pub value: Vec, + pub height: Height, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +impl TryFrom for VerifyMembershipMsg { + type Error = ContractError; + + fn try_from(mut raw: VerifyMembershipMsgRaw) -> Result { + let proof = CommitmentProofBytes::try_from(raw.proof)?; + let prefix = raw.path.key_path.remove(0).into_bytes(); + let path_str = raw.path.key_path.join(""); + let path = Path::from_str(&path_str)?; + let height = Height::from(raw.height); + Ok(Self { + proof, + path, + value: raw.value, + height, + prefix: CommitmentPrefix::try_from(prefix)?, + delay_block_period: raw.delay_block_period, + delay_time_period: raw.delay_time_period, + }) + } +} + +#[cw_serde] +pub struct VerifyNonMembershipMsgRaw { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof: Bytes, + pub path: MerklePath, + pub height: HeightRaw, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +pub struct VerifyNonMembershipMsg { + pub prefix: CommitmentPrefix, + pub proof: CommitmentProofBytes, + pub path: Path, + pub height: Height, + pub delay_block_period: u64, + pub delay_time_period: u64, +} + +impl TryFrom for VerifyNonMembershipMsg { + type Error = ContractError; + + fn try_from(mut raw: VerifyNonMembershipMsgRaw) -> Result { + let proof = CommitmentProofBytes::try_from(raw.proof)?; + let prefix = raw.path.key_path.remove(0).into_bytes(); + let path_str = raw.path.key_path.join(""); + let path = Path::from_str(&path_str)?; + let height = Height::from(raw.height); + Ok(Self { + proof, + path, + height, + prefix: CommitmentPrefix::try_from(prefix)?, + delay_block_period: raw.delay_block_period, + delay_time_period: raw.delay_time_period, + }) + } +} + +#[cw_serde] +pub struct WasmMisbehaviour { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub data: Bytes, +} + +#[cw_serde] +pub struct WasmHeader { + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub data: Bytes, +} + +#[cw_serde] +pub enum ClientMessageRaw { + Header(WasmHeader), + Misbehaviour(WasmMisbehaviour), +} + +#[cw_serde] +pub struct VerifyClientMessageRaw { + pub client_message: ClientMessageRaw, +} + +pub struct VerifyClientMessage { + pub client_message: ClientMessage, +} + +impl TryFrom for VerifyClientMessage { + type Error = ContractError; + + fn try_from(raw: VerifyClientMessageRaw) -> Result { + let client_message = Self::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +impl VerifyClientMessage { + fn decode_client_message(raw: ClientMessageRaw) -> Result { + let client_message = match raw { + ClientMessageRaw::Header(header) => { + let any = Any::decode(&mut header.data.as_slice())?; + // panic!("This is any {:?}\n {:?}", any.type_url, any.value); + // ClientMessage::Header(Header::decode_vec(&any.value)?) + ClientMessage::decode_vec(&any.value)? + }, + ClientMessageRaw::Misbehaviour(misbehaviour) => { + let any = Any::decode(&mut misbehaviour.data.as_slice())?; + ClientMessage::Misbehaviour(Misbehaviour::decode_vec(&any.value)?) + }, + }; + Ok(client_message) + } +} + +#[cw_serde] +pub struct CheckForMisbehaviourMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct CheckForMisbehaviourMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for CheckForMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: CheckForMisbehaviourMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct UpdateStateOnMisbehaviourMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct UpdateStateOnMisbehaviourMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for UpdateStateOnMisbehaviourMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateOnMisbehaviourMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct UpdateStateMsgRaw { + pub client_message: ClientMessageRaw, +} + +pub struct UpdateStateMsg { + pub client_message: ClientMessage, +} + +impl TryFrom for UpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: UpdateStateMsgRaw) -> Result { + let client_message = VerifyClientMessage::decode_client_message(raw.client_message)?; + Ok(Self { client_message }) + } +} + +#[cw_serde] +pub struct CheckSubstituteAndUpdateStateMsg {} + +#[cw_serde] +pub struct VerifyUpgradeAndUpdateStateMsgRaw { + pub upgrade_client_state: WasmClientState, + pub upgrade_consensus_state: WasmConsensusState, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof_upgrade_client: Bytes, + #[schemars(with = "String")] + #[serde(with = "Base64", default)] + pub proof_upgrade_consensus_state: Bytes, +} + +pub struct VerifyUpgradeAndUpdateStateMsg { + pub upgrade_client_state: WasmClientState, + pub upgrade_consensus_state: WasmConsensusState, + pub proof_upgrade_client: CommitmentProofBytes, + pub proof_upgrade_consensus_state: CommitmentProofBytes, +} + +impl TryFrom for VerifyUpgradeAndUpdateStateMsg { + type Error = ContractError; + + fn try_from(raw: VerifyUpgradeAndUpdateStateMsgRaw) -> Result { + let any = Any::decode(&mut raw.upgrade_client_state.data.as_slice())?; + let upgrade_client_state: ics07_tendermint::client_state::ClientState = + ClientState::decode_vec(&any.value)?; + if upgrade_client_state.trust_level != TrustThreshold::ZERO || + upgrade_client_state.trusting_period != Duration::ZERO || + upgrade_client_state.max_clock_drift != Duration::ZERO || + upgrade_client_state.frozen_height.is_some() + { + return ibc::prelude::Err(ContractError::Tendermint( + "Upgrade client state not zeroed".to_string(), + )) + } + + Ok(VerifyUpgradeAndUpdateStateMsg { + upgrade_client_state: raw.upgrade_client_state, + upgrade_consensus_state: raw.upgrade_consensus_state, + proof_upgrade_client: CommitmentProofBytes::try_from(raw.proof_upgrade_client)?, + proof_upgrade_consensus_state: CommitmentProofBytes::try_from( + raw.proof_upgrade_consensus_state, + )?, + }) + } +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 654d4cf37..ec2d04a4e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,3 @@ [toolchain] -channel = "nightly-2023-08-24" targets = [ "wasm32-unknown-unknown"] profile = "minimal" \ No newline at end of file diff --git a/rustc-ice-2024-03-22T16:47:29.113636Z-65716.txt b/rustc-ice-2024-03-22T16:47:29.113636Z-65716.txt new file mode 100644 index 000000000..cea6767b2 --- /dev/null +++ b/rustc-ice-2024-03-22T16:47:29.113636Z-65716.txt @@ -0,0 +1,36 @@ +thread 'rustc' panicked at compiler/rustc_metadata/src/rmeta/encoder.rs:442:9: +assertion failed: pos.get() <= self.position() +stack backtrace: + 0: 0x100f025e0 - ::fmt::h2a254872ec49b12a + 1: 0x100f565b0 - core::fmt::write::h670c4416a1b64939 + 2: 0x100ef7ce0 - std::io::Write::write_fmt::h22c30f89b90f7322 + 3: 0x100f02420 - std::sys_common::backtrace::print::h98b26e6c694ef8e7 + 4: 0x100f051bc - std::panicking::panic_hook_with_disk_dump::{{closure}}::hf6d9b671ff5ff324 + 5: 0x100f04e8c - std::panicking::panic_hook_with_disk_dump::hfef178573869cf67 + 6: 0x1092c58d8 - rustc_driver_impl[27f723b8977e7d4f]::install_ice_hook::{closure#0} + 7: 0x100f059bc - std::panicking::rust_panic_with_hook::h4dc12b8951e04ef8 + 8: 0x100f05750 - std::panicking::begin_panic_handler::{{closure}}::had79a6be5c51ec05 + 9: 0x100f02a6c - std::sys_common::backtrace::__rust_end_short_backtrace::h5f8230151ad2e95a + 10: 0x100f054f0 - _rust_begin_unwind + 11: 0x100f81b58 - core::panicking::panic_fmt::hb20223d9855b32ef + 12: 0x100f81bc8 - core::panicking::panic::hab3b1c94bab11368 + 13: 0x10c9ff9c4 - ::encode_crate_root + 14: 0x10ca04ae0 - rustc_metadata[82b75fa48f00f84c]::rmeta::encoder::encode_metadata_impl + 15: 0x10ca51ba0 - rustc_data_structures[2937b4d599e1ba1b]::sync::join:: + 16: 0x10ca041bc - rustc_metadata[82b75fa48f00f84c]::rmeta::encoder::encode_metadata + 17: 0x10ca5c1e4 - rustc_metadata[82b75fa48f00f84c]::fs::encode_and_write_metadata + 18: 0x10943f2e8 - rustc_interface[4bc8500067647ed8]::passes::start_codegen + 19: 0x10942c0c8 - ::enter::<::ongoing_codegen::{closure#0}, core[5736f96b16ac4b37]::result::Result, rustc_span[1183a8a0fe266ebb]::ErrorGuaranteed>> + 20: 0x109463574 - ::ongoing_codegen + 21: 0x1092cef8c - ::enter::, rustc_span[1183a8a0fe266ebb]::ErrorGuaranteed>> + 22: 0x1092f9358 - std[58d10f45c6ffd7a3]::sys_common::backtrace::__rust_begin_short_backtrace::, rustc_driver_impl[27f723b8977e7d4f]::run_compiler::{closure#1}>::{closure#0}, core[5736f96b16ac4b37]::result::Result<(), rustc_span[1183a8a0fe266ebb]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[5736f96b16ac4b37]::result::Result<(), rustc_span[1183a8a0fe266ebb]::ErrorGuaranteed>> + 23: 0x1092fb0e0 - <::spawn_unchecked_, rustc_driver_impl[27f723b8977e7d4f]::run_compiler::{closure#1}>::{closure#0}, core[5736f96b16ac4b37]::result::Result<(), rustc_span[1183a8a0fe266ebb]::ErrorGuaranteed>>::{closure#0}::{closure#0}, core[5736f96b16ac4b37]::result::Result<(), rustc_span[1183a8a0fe266ebb]::ErrorGuaranteed>>::{closure#1} as core[5736f96b16ac4b37]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0} + 24: 0x100f0e640 - std::sys::unix::thread::Thread::new::thread_start::h97ad85389d191acf + 25: 0x18d64ffa8 - __pthread_joiner_wake + + +rustc version: 1.74.0-nightly (249595b75 2023-08-23) +platform: aarch64-apple-darwin + +query stack during panic: +end of query stack diff --git a/utils/parachain-node/runtime/build.rs b/utils/parachain-node/runtime/build.rs index 399f2628f..4d2712b30 100644 --- a/utils/parachain-node/runtime/build.rs +++ b/utils/parachain-node/runtime/build.rs @@ -15,9 +15,9 @@ use substrate_wasm_builder::WasmBuilder; fn main() { - WasmBuilder::new() - .with_current_project() - .export_heap_base() - .import_memory() - .build() + // WasmBuilder::new() + // .with_current_project() + // .export_heap_base() + // .import_memory() + // .build() } diff --git a/utils/subxt/codegen/src/lib.rs b/utils/subxt/codegen/src/lib.rs index d2336b543..cbce8df4a 100644 --- a/utils/subxt/codegen/src/lib.rs +++ b/utils/subxt/codegen/src/lib.rs @@ -26,16 +26,20 @@ use subxt_codegen::{CratePath, DerivesRegistry, TypeSubstitutes}; use subxt_metadata::Metadata; pub async fn fetch_metadata_ws(url: &str) -> anyhow::Result> { + println!("Here 11"); let (sender, receiver) = WsTransportClientBuilder::default() .build(url.parse::().unwrap()) .await .map_err(|e| Error::Transport(e.into()))?; + println!("Here 12"); let client = ClientBuilder::default() .max_notifs_per_subscription(4096) .build_with_tokio(sender, receiver); + println!("Here 13"); let metadata: String = client.request("state_getMetadata", rpc_params![]).await?; + println!("Here later"); Ok(hex::decode(metadata.trim_start_matches("0x"))?) }