diff --git a/Cargo.lock b/Cargo.lock index d31cf8d9d8..13494070c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,6 +4,21 @@ # SPDX-License-Identifier: Apache-2.0 version = 3 +[[package]] +name = "addr2line" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aes" version = "0.7.4" @@ -69,6 +84,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "anomaly" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "550632e31568ae1a5f47998c3aa48563030fc49b9ec91913ca337cf64fbc5ccb" +dependencies = [ + "backtrace", +] + [[package]] name = "ansi_term" version = "0.11.0" @@ -119,9 +143,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.50" +version = "0.1.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b98e84bbb4cbcdd97da190ba0c58a1bb0de2c1fdf67d159e192ed766aeca722" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" dependencies = [ "proc-macro2", "quote", @@ -143,7 +167,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" dependencies = [ - "autocfg", + "autocfg 1.0.1", ] [[package]] @@ -157,12 +181,33 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" + [[package]] name = "autocfg" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "backtrace" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "base-x" version = "0.2.8" @@ -181,23 +226,47 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" +[[package]] +name = "bip32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b48054b307f98bf2ddb17ffd4e9d029bfaf3e7cd5fe807e412768e4370015e3d" +dependencies = [ + "bs58 0.4.0", + "hkd32", + "hmac 0.11.0", + "k256", + "ripemd160", + "sha2", + "subtle 2.4.0", + "zeroize", +] + +[[package]] +name = "bip39" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e89470017230c38e52b82b3ee3f530db1856ba1d434e3a67a3456a8a8dec5f" +dependencies = [ + "bitcoin_hashes", + "rand 0.6.5", + "rand_core 0.4.2", + "serde", + "unicode-normalization", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce18265ec2324ad075345d5814fbeed4f41f0a660055dc78840b74d19b874b1" + [[package]] name = "bitflags" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "bitvec" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa" -dependencies = [ - "funty", - "radium 0.3.0", - "wyz", -] - [[package]] name = "bitvec" version = "0.19.5" @@ -205,7 +274,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" dependencies = [ "funty", - "radium 0.5.3", + "radium", "tap", "wyz", ] @@ -243,7 +312,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" dependencies = [ - "block-padding", + "block-padding 0.1.5", "byte-tools", "byteorder", "generic-array 0.12.4", @@ -255,6 +324,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ + "block-padding 0.2.1", "generic-array 0.14.4", ] @@ -267,6 +337,12 @@ dependencies = [ "byte-tools", ] +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "bs58" version = "0.3.1" @@ -278,6 +354,9 @@ name = "bs58" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2", +] [[package]] name = "build_const" @@ -347,7 +426,7 @@ dependencies = [ "num-integer", "num-traits", "serde", - "time 0.1.44", + "time 0.1.43", "winapi", ] @@ -408,6 +487,15 @@ dependencies = [ "validator-client", ] +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags", +] + [[package]] name = "colored" version = "2.0.0" @@ -441,9 +529,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.4.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6b64db6932c7e49332728e3a6bd82c6b7e16016607d20923b537c3bc4c0d5f" +checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" [[package]] name = "const_fn" @@ -490,11 +578,40 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +[[package]] +name = "cosmos-sdk-proto" +version = "0.6.0" +source = "git+https://github.com/cosmos/cosmos-rust/#ba012bd820240d3df2d9a0ab1deabe4ecd9a2f30" +dependencies = [ + "prost", + "prost-types", + "tendermint-proto", +] + +[[package]] +name = "cosmos_sdk" +version = "0.2.0" +source = "git+https://github.com/cosmos/cosmos-rust/#ba012bd820240d3df2d9a0ab1deabe4ecd9a2f30" +dependencies = [ + "bip32", + "cosmos-sdk-proto", + "ecdsa", + "eyre", + "getrandom 0.2.3", + "k256", + "prost", + "prost-types", + "rand_core 0.6.3", + "subtle-encoding", + "tendermint", + "tendermint-rpc", + "thiserror", +] + [[package]] name = "cosmwasm-crypto" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038089cdadfe61e4e85617d91cecec2c49f828db8e5986bb85e29d0b29c59b77" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "digest 0.9.0", "ed25519-zebra", @@ -506,8 +623,7 @@ dependencies = [ [[package]] name = "cosmwasm-derive" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bf3da935843795a7f52678262ef06398878b0cf4c89b69612d8525ea27b84" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "syn", ] @@ -515,8 +631,7 @@ dependencies = [ [[package]] name = "cosmwasm-std" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22de097cf4f7e7f575f51a22de7260932756ccfe499e005f98244a3043470e48" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "base64", "cosmwasm-crypto", @@ -624,6 +739,18 @@ dependencies = [ "x25519-dalek", ] +[[package]] +name = "crypto-bigint" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4" +dependencies = [ + "generic-array 0.14.4", + "rand_core 0.6.3", + "subtle 2.4.0", + "zeroize", +] + [[package]] name = "crypto-mac" version = "0.7.0" @@ -656,14 +783,23 @@ dependencies = [ [[package]] name = "crypto-mac" -version = "0.11.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ "generic-array 0.14.4", "subtle 2.4.0", ] +[[package]] +name = "ct-logs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" +dependencies = [ + "sct", +] + [[package]] name = "ctr" version = "0.6.0" @@ -742,9 +878,9 @@ dependencies = [ [[package]] name = "der" -version = "0.1.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f59c66c30bb7445c8320a5f9233e437e3572368099f25532a59054328899b4" +checksum = "49f215f706081a44cb702c71c39a52c05da637822e9c1645a50b7202689e982d" dependencies = [ "const-oid", ] @@ -858,12 +994,13 @@ checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" [[package]] name = "ecdsa" -version = "0.10.2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fbdb4ff710acb4db8ca29f93b897529ea6d6a45626d5183b47e012aa6ae7e4" +checksum = "05cb0ed2d2ce37766ac86c05f66973ace8c51f7f1533bedce8fb79e2b54b3f14" dependencies = [ + "der", "elliptic-curve", - "hmac 0.10.1", + "hmac 0.11.0", "signature", ] @@ -873,6 +1010,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d0860415b12243916284c67a9be413e044ee6668247b99ba26d94b2bc06c8f6" dependencies = [ + "serde", "signature", ] @@ -886,6 +1024,7 @@ dependencies = [ "ed25519", "rand 0.7.3", "serde", + "serde_bytes", "sha2", "zeroize", ] @@ -912,18 +1051,16 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "elliptic-curve" -version = "0.8.5" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2db227e61a43a34915680bdda462ec0e212095518020a88a1f91acd16092c39" +checksum = "83e5c176479da93a0983f0a6fdc3c1b8e7d5be0d7fe3fe05a99f15b96582b9a8" dependencies = [ - "bitvec 0.18.5", - "digest 0.9.0", + "crypto-bigint", "ff", - "funty", "generic-array 0.14.4", "group", "pkcs8", - "rand_core 0.5.1", + "rand_core 0.6.3", "subtle 2.4.0", "zeroize", ] @@ -950,6 +1087,15 @@ dependencies = [ "termcolor", ] +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + [[package]] name = "explorer-api" version = "0.1.0" @@ -970,6 +1116,16 @@ dependencies = [ "validator-client", ] +[[package]] +name = "eyre" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221239d1d5ea86bf5d6f91c9d6bc3646ffe471b08ff9b0f91c44f115ac969d2b" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fake-simd" version = "0.1.2" @@ -978,12 +1134,11 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "ff" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0" dependencies = [ - "bitvec 0.18.5", - "rand_core 0.5.1", + "rand_core 0.6.3", "subtle 2.4.0", ] @@ -1001,6 +1156,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "flate2" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1042,6 +1209,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "1.1.0" @@ -1102,7 +1275,7 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4c40298486cdf52cc00cd6d6987892ba502c7656a16a4192a9992b1ccedd121" dependencies = [ - "autocfg", + "autocfg 1.0.1", "proc-macro-hack", "proc-macro2", "quote", @@ -1127,7 +1300,7 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" dependencies = [ - "autocfg", + "autocfg 1.0.1", "futures-channel", "futures-core", "futures-io", @@ -1245,6 +1418,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" + [[package]] name = "glob" version = "0.3.0" @@ -1253,12 +1432,12 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "group" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff", - "rand_core 0.5.1", + "rand_core 0.6.3", "subtle 2.4.0", ] @@ -1313,6 +1492,31 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "headers" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "mime", + "sha-1 0.9.6", + "time 0.1.43", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + [[package]] name = "heck" version = "0.3.3" @@ -1337,6 +1541,20 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkd32" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" +dependencies = [ + "hmac 0.11.0", + "once_cell", + "pbkdf2", + "rand_core 0.6.3", + "sha2", + "zeroize", +] + [[package]] name = "hkdf" version = "0.10.0" @@ -1383,7 +1601,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ - "crypto-mac 0.11.1", + "crypto-mac 0.11.0", "digest 0.9.0", ] @@ -1470,6 +1688,41 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-proxy" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" +dependencies = [ + "bytes", + "futures", + "headers", + "http", + "hyper", + "hyper-tls", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "ct-logs", + "futures-util", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", + "webpki", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1491,22 +1744,28 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094" dependencies = [ "matches", "unicode-bidi", "unicode-normalization", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ - "autocfg", + "autocfg 1.0.1", "hashbrown", "serde", ] @@ -1560,6 +1819,24 @@ dependencies = [ "thiserror", ] +[[package]] +name = "itertools" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.7" @@ -1577,16 +1854,23 @@ dependencies = [ [[package]] name = "k256" -version = "0.7.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4476a0808212a9e81ce802eb1a0cfc60e73aea296553bacc0fac7e1268bc572a" +checksum = "f3a26a4a8e8b0ab315c687767b543c923c9667a1f2bf42a42818d1453891c7c1" dependencies = [ "cfg-if 1.0.0", "ecdsa", "elliptic-curve", "sha2", + "sha3", ] +[[package]] +name = "keccak" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" + [[package]] name = "keystream" version = "1.0.0" @@ -1690,6 +1974,12 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + [[package]] name = "memchr" version = "2.4.0" @@ -1702,7 +1992,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ - "autocfg", + "autocfg 1.0.1", ] [[package]] @@ -1717,6 +2007,16 @@ version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg 1.0.1", +] + [[package]] name = "mio" version = "0.7.13" @@ -1830,7 +2130,7 @@ version = "6.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" dependencies = [ - "bitvec 0.19.5", + "bitvec", "funty", "lexical-core", "memchr", @@ -1855,13 +2155,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "num-integer" version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" dependencies = [ - "autocfg", + "autocfg 1.0.1", "num-traits", ] @@ -1871,7 +2182,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" dependencies = [ - "autocfg", + "autocfg 1.0.1", "libm", ] @@ -2200,6 +2511,15 @@ dependencies = [ "sphinx", ] +[[package]] +name = "object" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386" +dependencies = [ + "memchr", +] + [[package]] name = "okapi" version = "0.6.0-alpha-1" @@ -2255,7 +2575,7 @@ version = "0.9.65" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a7907e3bfa08bb85105209cdfcb6c63d109f8f6c1ed6ca318fff5c1853fbc1d" dependencies = [ - "autocfg", + "autocfg 1.0.1", "cc", "libc", "pkg-config", @@ -2290,10 +2610,19 @@ dependencies = [ "instant", "libc", "redox_syscall", - "smallvec", + "smallvec 1.6.1", "winapi", ] +[[package]] +name = "pbkdf2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +dependencies = [ + "crypto-mac 0.11.0", +] + [[package]] name = "pear" version = "0.2.3" @@ -2418,11 +2747,12 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.3.3" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4839a901843f3942576e65857f0ebf2e190ef7024d3c62a94099ba3f819ad1d" +checksum = "09d156817ae0125e8aa5067710b0db24f0984830614f99875a70aa5e3b74db69" dependencies = [ "der", + "spki", ] [[package]] @@ -2481,6 +2811,39 @@ dependencies = [ "yansi", ] +[[package]] +name = "prost" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e6984d2f1a23009bd270b8bb56d0926810a3d483f59c987d77969e9d8e840b2" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "169a15f3008ecb5160cba7d37bcd690a7601b6d30cfb87a117d45e59d52af5d4" +dependencies = [ + "anyhow", + "itertools 0.9.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b518d7cdd93dab1d1122cf07fa9a60771836c668dde9d9e2a139f957f0d9f1bb" +dependencies = [ + "bytes", + "prost", +] + [[package]] name = "proxy-helpers" version = "0.1.0" @@ -2497,12 +2860,15 @@ dependencies = [ [[package]] name = "publicsuffix" -version = "1.5.6" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f" +checksum = "3bbaa49075179162b49acac1c6aa45fb4dafb5f13cf6794276d77bc7fd95757b" dependencies = [ + "error-chain", "idna", + "lazy_static", "native-tls", + "regex", "url", ] @@ -2538,18 +2904,31 @@ dependencies = [ "scheduled-thread-pool", ] -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - [[package]] name = "radium" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.7", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg", + "rand_xorshift", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -2575,6 +2954,16 @@ dependencies = [ "rand_hc 0.3.1", ] +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.3.1", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -2595,6 +2984,21 @@ dependencies = [ "rand_core 0.6.3", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -2623,6 +3027,15 @@ dependencies = [ "rand 0.7.3", ] +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -2641,6 +3054,68 @@ dependencies = [ "rand_core 0.6.3", ] +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.7", + "rand_core 0.4.2", +] + +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.9" @@ -2756,6 +3231,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + [[package]] name = "rocket" version = "0.5.0-rc.1" @@ -2846,7 +3332,7 @@ dependencies = [ "pin-project-lite", "ref-cast", "serde", - "smallvec", + "smallvec 1.6.1", "stable-pattern", "state", "time 0.2.27", @@ -2904,6 +3390,12 @@ dependencies = [ "quote", ] +[[package]] +name = "rustc-demangle" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" + [[package]] name = "rustc_version" version = "0.2.3" @@ -2926,6 +3418,18 @@ dependencies = [ "webpki", ] +[[package]] +name = "rustls-native-certs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" +dependencies = [ + "openssl-probe", + "rustls", + "schannel", + "security-framework", +] + [[package]] name = "rustversion" version = "1.0.5" @@ -2938,6 +3442,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.19" @@ -3078,6 +3591,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_bytes" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.126" @@ -3200,6 +3722,18 @@ dependencies = [ "opaque-debug 0.3.0", ] +[[package]] +name = "sha3" +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.0", +] + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -3211,12 +3745,12 @@ dependencies = [ [[package]] name = "signature" -version = "1.2.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" dependencies = [ "digest 0.9.0", - "rand_core 0.5.1", + "rand_core 0.6.3", ] [[package]] @@ -3241,6 +3775,15 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + [[package]] name = "smallvec" version = "1.6.1" @@ -3321,6 +3864,15 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5fdd7196b4ae35a111c6dc97f9cc152ca3ea8ad744f7cb46a9f27b3ef8f2f54" +[[package]] +name = "spki" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987637c5ae6b3121aba9d513f869bd2bff11c4cc086c22473befd6649c0bd521" +dependencies = [ + "der", +] + [[package]] name = "sqlformat" version = "0.1.6" @@ -3375,7 +3927,7 @@ dependencies = [ "percent-encoding", "rustls", "sha2", - "smallvec", + "smallvec 1.6.1", "sqlformat", "sqlx-rt", "stringprep", @@ -3535,6 +4087,15 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + [[package]] name = "syn" version = "1.0.73" @@ -3578,6 +4139,89 @@ dependencies = [ "winapi", ] +[[package]] +name = "tendermint" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0752808f59b612916614e92e43be64e9ba566b762a266bcfcf7dce1b324e9319" +dependencies = [ + "anomaly", + "async-trait", + "bytes", + "chrono", + "ed25519", + "ed25519-dalek", + "futures", + "k256", + "num-traits", + "once_cell", + "prost", + "prost-types", + "ripemd160", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2", + "signature", + "subtle 2.4.0", + "subtle-encoding", + "tendermint-proto", + "thiserror", + "toml", + "url", + "zeroize", +] + +[[package]] +name = "tendermint-proto" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfd0371c6b0c7fc4f6b053b8a1bc868a2a47c49a1408c4cd6f595d9f3bd3c238" +dependencies = [ + "anomaly", + "bytes", + "chrono", + "num-derive", + "num-traits", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "thiserror", +] + +[[package]] +name = "tendermint-rpc" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fa8d172e3129802d28de980531993dd25cc01841c5bc8fe4a87c7750a7f222" +dependencies = [ + "async-trait", + "bytes", + "chrono", + "futures", + "getrandom 0.1.16", + "http", + "hyper", + "hyper-proxy", + "hyper-rustls", + "pin-project", + "serde", + "serde_bytes", + "serde_json", + "subtle-encoding", + "tendermint", + "tendermint-proto", + "thiserror", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -3618,12 +4262,11 @@ dependencies = [ [[package]] name = "time" -version = "0.1.44" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] @@ -3665,28 +4308,13 @@ dependencies = [ "syn", ] -[[package]] -name = "tinyvec" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - [[package]] name = "tokio" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c" dependencies = [ - "autocfg", + "autocfg 1.0.1", "bytes", "libc", "memchr", @@ -3821,9 +4449,21 @@ checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.18" @@ -3948,11 +4588,11 @@ dependencies = [ [[package]] name = "unicode-normalization" -version = "0.1.19" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +checksum = "09c8070a9942f5e7cfccd93f490fdebd230ee3c3c9f107cb25bad5351ef671cf" dependencies = [ - "tinyvec", + "smallvec 0.6.14", ] [[package]] @@ -4003,19 +4643,35 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + [[package]] name = "validator-client" version = "0.1.0" dependencies = [ + "async-trait", "base64", + "bip39", + "config", + "cosmos_sdk", + "cosmwasm-std", + "flate2", "getrandom 0.2.3", + "itertools 0.10.1", "log", "mixnet-contract", + "prost", "rand 0.8.4", "reqwest", "serde", "serde_json", + "sha2", "thiserror", + "tokio", "url", "wasm-timer", ] @@ -4045,6 +4701,17 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "want" version = "0.3.0" diff --git a/clients/webassembly/Cargo.toml b/clients/webassembly/Cargo.toml index 8f2826def4..c8c1cb882e 100644 --- a/clients/webassembly/Cargo.toml +++ b/clients/webassembly/Cargo.toml @@ -28,7 +28,7 @@ crypto = { path = "../../common/crypto" } nymsphinx = { path = "../../common/nymsphinx" } topology = { path = "../../common/topology" } gateway-client = { path = "../../common/client-libs/gateway-client" } -validator-client = { path = "../../common/client-libs/validator-client" } +validator-client = { path = "../../common/client-libs/validator-client", default-features = false } wasm-utils = { path = "../../common/wasm-utils" } # The `console_error_panic_hook` crate provides better debugging of panics by diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 626c327082..7a744bf424 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -18,7 +18,26 @@ log = "0.4" url = "2" wasm-timer = "0.2" +# required for nymd-client +# at some point it might be possible to make it wasm-compatible +# perhaps after https://github.com/cosmos/cosmos-rust/pull/97 is resolved (and tendermint-rs is updated) +async-trait = { version = "0.1.51", optional = true } +bip39 = { version = "1", features = ["rand"], optional = true } +config = { path = "../../config", optional = true} +cosmos_sdk = { git = "https://github.com/cosmos/cosmos-rust/", commit="ba012bd820240d3df2d9a0ab1deabe4ecd9a2f30", features = ["rpc", "bip32", "cosmwasm"], optional = true } +prost = { version = "0.7", default-features = false, optional = true } +flate2 = { version = "1.0.20", optional = true } +sha2 = { version = "0.9.5", optional = true } +itertools = { version = "0.10", optional = true } +cosmwasm-std = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", optional = true } + [target."cfg(target_arch = \"wasm32\")".dependencies.getrandom] version = "0.2" features = ["js"] +[dev-dependencies] +tokio = {version = "1.5", features = ["full"]} + +[features] +default = ["nymd-client"] +nymd-client = ["async-trait", "bip39", "config", "cosmos_sdk", "prost", "flate2", "sha2", "itertools", "cosmwasm-std"] diff --git a/common/client-libs/validator-client/src/error.rs b/common/client-libs/validator-client/src/error.rs index 5abe4a5ca3..16690573de 100644 --- a/common/client-libs/validator-client/src/error.rs +++ b/common/client-libs/validator-client/src/error.rs @@ -1,6 +1,12 @@ +#[cfg(feature = "nymd-client")] +use crate::nymd::cosmwasm_client::types::ContractCodeId; use crate::validator_api; - +#[cfg(feature = "nymd-client")] +use cosmos_sdk::tendermint::block; +#[cfg(feature = "nymd-client")] +use cosmos_sdk::{bip32, rpc, tx, AccountId}; use serde::Deserialize; +use std::io; use thiserror::Error; #[derive(Error, Debug)] @@ -10,18 +16,169 @@ pub enum ValidatorClientError { #[from] source: reqwest::Error, }, + #[error("There was an issue with the validator-api request - {source}")] ValidatorAPIError { #[from] source: validator_api::error::ValidatorAPIClientError, }, + #[error("An IO error has occured: {source}")] IoError { #[from] - source: std::io::Error, + source: io::Error, }, + #[error("There was an issue with the validator client - {0}")] ValidatorError(String), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue with bip32 - {0}")] + Bip32Error(bip32::Error), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue with bip32 - {0}")] + Bip39Error(bip39::Error), + + #[cfg(feature = "nymd-client")] + #[error("Failed to derive account address")] + AccountDerivationError, + + #[cfg(feature = "nymd-client")] + #[error("Address {0} was not found in the wallet")] + SigningAccountNotFound(AccountId), + + #[cfg(feature = "nymd-client")] + #[error("Failed to sign raw transaction")] + SigningFailure, + + #[cfg(feature = "nymd-client")] + #[error("{0} is not a valid tx hash")] + InvalidTxHash(String), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue with a tendermint RPC request - {0}")] + TendermintError(rpc::Error), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue when attempting to serialize data")] + SerializationError(String), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue when attempting to deserialize data")] + DeserializationError(String), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue when attempting to encode our protobuf data - {0}")] + ProtobufEncodingError(prost::EncodeError), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue when attempting to decode our protobuf data - {0}")] + ProtobufDecodingError(prost::DecodeError), + + #[cfg(feature = "nymd-client")] + #[error("Account {0} does not exist on the chain")] + NonExistentAccountError(AccountId), + + #[cfg(feature = "nymd-client")] + #[error("There was an issue with the serialization/deserialization - {0}")] + SerdeJsonError(serde_json::Error), + + #[cfg(feature = "nymd-client")] + #[error("Account {0} is not a valid account address")] + MalformedAccountAddress(String), + + #[cfg(feature = "nymd-client")] + #[error("Account {0} has an invalid associated public key")] + InvalidPublicKey(AccountId), + + #[cfg(feature = "nymd-client")] + #[error("Queried contract (code_id: {0}) did not have any code information attached")] + NoCodeInformation(ContractCodeId), + + #[cfg(feature = "nymd-client")] + #[error("Queried contract (address: {0}) did not have any contract information attached")] + NoContractInformation(AccountId), + + #[cfg(feature = "nymd-client")] + #[error("Contract contains invalid operations in its history")] + InvalidContractHistoryOperation, + + #[cfg(feature = "nymd-client")] + #[error("Block has an invalid height (either negative or larger than i64::MAX")] + InvalidHeight, + + #[cfg(feature = "nymd-client")] + #[error("Failed to compress provided wasm code - {0}")] + WasmCompressionError(io::Error), + + #[cfg(feature = "nymd-client")] + #[error("Logs returned from the validator were malformed")] + MalformedLogString, + + #[cfg(feature = "nymd-client")] + #[error( + "Error when broadcasting tx {hash} at height {height}. Error occurred during CheckTx phase. Code: {code}; Raw log: {raw_log}" + )] + BroadcastTxErrorCheckTx { + hash: tx::Hash, + height: block::Height, + code: u32, + raw_log: String, + }, + + #[cfg(feature = "nymd-client")] + #[error( + "Error when broadcasting tx {hash} at height {height}. Error occurred during DeliverTx phase. Code: {code}; Raw log: {raw_log}" + )] + BroadcastTxErrorDeliverTx { + hash: tx::Hash, + height: block::Height, + code: u32, + raw_log: String, + }, +} + +#[cfg(feature = "nymd-client")] +impl From for ValidatorClientError { + fn from(err: bip32::Error) -> Self { + ValidatorClientError::Bip32Error(err) + } +} + +#[cfg(feature = "nymd-client")] +impl From for ValidatorClientError { + fn from(err: bip39::Error) -> Self { + ValidatorClientError::Bip39Error(err) + } +} + +#[cfg(feature = "nymd-client")] +impl From for ValidatorClientError { + fn from(err: rpc::Error) -> Self { + ValidatorClientError::TendermintError(err) + } +} + +#[cfg(feature = "nymd-client")] +impl From for ValidatorClientError { + fn from(err: prost::EncodeError) -> Self { + ValidatorClientError::ProtobufEncodingError(err) + } +} + +#[cfg(feature = "nymd-client")] +impl From for ValidatorClientError { + fn from(err: prost::DecodeError) -> Self { + ValidatorClientError::ProtobufDecodingError(err) + } +} + +#[cfg(feature = "nymd-client")] +impl From for ValidatorClientError { + fn from(err: serde_json::Error) -> Self { + ValidatorClientError::SerdeJsonError(err) + } } // this is the case of message like diff --git a/common/client-libs/validator-client/src/lib.rs b/common/client-libs/validator-client/src/lib.rs index 93e1ba086b..af4c2bdd4d 100644 --- a/common/client-libs/validator-client/src/lib.rs +++ b/common/client-libs/validator-client/src/lib.rs @@ -16,6 +16,8 @@ use url::Url; mod error; mod models; +#[cfg(feature = "nymd-client")] +pub mod nymd; pub(crate) mod serde_helpers; pub mod validator_api; diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs new file mode 100644 index 0000000000..aa970fc888 --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/client.rs @@ -0,0 +1,420 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nymd::cosmwasm_client::helpers::create_pagination; +use crate::nymd::cosmwasm_client::types::{ + Account, Code, CodeDetails, Contract, ContractCodeHistoryEntry, ContractCodeId, + SequenceResponse, +}; +use crate::ValidatorClientError; +use async_trait::async_trait; +use cosmos_sdk::proto::cosmos::auth::v1beta1::{ + BaseAccount, QueryAccountRequest, QueryAccountResponse, +}; +use cosmos_sdk::proto::cosmos::bank::v1beta1::{ + QueryAllBalancesRequest, QueryAllBalancesResponse, QueryBalanceRequest, QueryBalanceResponse, +}; +use cosmos_sdk::proto::cosmwasm::wasm::v1beta1::*; +use cosmos_sdk::rpc::endpoint::block::Response as BlockResponse; +use cosmos_sdk::rpc::endpoint::broadcast; +use cosmos_sdk::rpc::endpoint::tx::Response as TxResponse; +use cosmos_sdk::rpc::query::Query; +use cosmos_sdk::rpc::{self, HttpClient, Order}; +use cosmos_sdk::tendermint::abci::Transaction; +use cosmos_sdk::tendermint::{abci, block, chain}; +use cosmos_sdk::{tx, AccountId, Coin, Denom}; +use prost::Message; +use serde::{Deserialize, Serialize}; +use std::convert::{TryFrom, TryInto}; + +#[async_trait] +impl CosmWasmClient for HttpClient {} + +#[async_trait] +pub trait CosmWasmClient: rpc::Client { + // helper method to remove duplicate code involved in making abci requests with protobuf messages + // TODO: perhaps it should have an additional argument to determine whether the response should + // require proof? + async fn make_abci_query( + &self, + path: Option, + req: Req, + ) -> Result + where + Req: Message, + Res: Message + Default, + { + let mut buf = Vec::with_capacity(req.encoded_len()); + req.encode(&mut buf)?; + + let res = self.abci_query(path, buf, None, false).await?; + + Ok(Res::decode(res.value.as_ref())?) + } + + async fn get_chain_id(&self) -> Result { + Ok(self.status().await?.node_info.network) + } + + async fn get_height(&self) -> Result { + Ok(self.status().await?.sync_info.latest_block_height) + } + + // TODO: the return type should probably be changed to a non-proto, type-safe Account alternative + async fn get_account( + &self, + address: &AccountId, + ) -> Result, ValidatorClientError> { + let path = Some("/cosmos.auth.v1beta1.Query/Account".parse().unwrap()); + + let req = QueryAccountRequest { + address: address.to_string(), + }; + + let res = self + .make_abci_query::<_, QueryAccountResponse>(path, req) + .await?; + + let base_account = res + .account + .map(|account| BaseAccount::decode(account.value.as_ref())) + .transpose()?; + + base_account + .map(|base_account| base_account.try_into()) + .transpose() + } + + async fn get_sequence( + &self, + address: &AccountId, + ) -> Result { + let base_account = self + .get_account(address) + .await? + .ok_or_else(|| ValidatorClientError::NonExistentAccountError(address.clone()))?; + Ok(SequenceResponse { + account_number: base_account.account_number, + sequence: base_account.sequence, + }) + } + + async fn get_block(&self, height: Option) -> Result { + match height { + Some(height) => self.block(height).await.map_err(|err| err.into()), + None => self.latest_block().await.map_err(|err| err.into()), + } + } + + async fn get_balance( + &self, + address: &AccountId, + search_denom: Denom, + ) -> Result, ValidatorClientError> { + let path = Some("/cosmos.bank.v1beta1.Query/Balance".parse().unwrap()); + + let req = QueryBalanceRequest { + address: address.to_string(), + denom: search_denom.to_string(), + }; + + let res = self + .make_abci_query::<_, QueryBalanceResponse>(path, req) + .await?; + + res.balance + .map(TryFrom::try_from) + .transpose() + .map_err(|_| ValidatorClientError::SerializationError("Coin".to_owned())) + } + + async fn get_all_balances( + &self, + address: &AccountId, + ) -> Result, ValidatorClientError> { + let path = Some("/cosmos.bank.v1beta1.Query/AllBalances".parse().unwrap()); + + let mut raw_balances = Vec::new(); + let mut pagination = None; + + loop { + let req = QueryAllBalancesRequest { + address: address.to_string(), + pagination, + }; + + let mut res = self + .make_abci_query::<_, QueryAllBalancesResponse>(path.clone(), req) + .await?; + + raw_balances.append(&mut res.balances); + if let Some(pagination_info) = res.pagination { + pagination = Some(create_pagination(pagination_info.next_key)) + } else { + break; + } + } + + raw_balances + .into_iter() + .map(TryFrom::try_from) + .collect::>() + .map_err(|_| ValidatorClientError::SerializationError("Coins".to_owned())) + } + + async fn get_tx(&self, id: tx::Hash) -> Result { + Ok(self.tx(id, false).await?) + } + + async fn search_tx(&self, query: Query) -> Result, ValidatorClientError> { + // according to https://docs.tendermint.com/master/rpc/#/Info/tx_search + // the maximum entries per page is 100 and the default is 30 + // so let's attempt to use the maximum + let per_page = 100; + + let mut results = Vec::new(); + let mut page = 1; + + loop { + let mut res = self + .tx_search(query.clone(), false, page, 100, Order::Ascending) + .await?; + + results.append(&mut res.txs); + // sanity check for if tendermint's maximum per_page was modified - + // we don't want to accidentally be stuck in an infinite loop + if res.total_count == 0 || res.txs.is_empty() { + break; + } + + if res.total_count >= per_page { + page += 1 + } else { + break; + } + } + + Ok(results) + } + + /// Broadcast a transaction, returning immediately. + async fn broadcast_tx_async( + &self, + tx: Transaction, + ) -> Result { + Ok(rpc::Client::broadcast_tx_async(self, tx).await?) + } + + /// Broadcast a transaction, returning the response from `CheckTx`. + async fn broadcast_tx_sync( + &self, + tx: Transaction, + ) -> Result { + Ok(rpc::Client::broadcast_tx_sync(self, tx).await?) + } + + /// Broadcast a transaction, returning the response from `DeliverTx`. + async fn broadcast_tx_commit( + &self, + tx: Transaction, + ) -> Result { + Ok(rpc::Client::broadcast_tx_commit(self, tx).await?) + } + + async fn get_codes(&self) -> Result, ValidatorClientError> { + let path = Some("/cosmwasm.wasm.v1beta1.Query/Codes".parse().unwrap()); + + let mut raw_codes = Vec::new(); + let mut pagination = None; + + loop { + let req = QueryCodesRequest { pagination }; + + let mut res = self + .make_abci_query::<_, QueryCodesResponse>(path.clone(), req) + .await?; + + raw_codes.append(&mut res.code_infos); + if let Some(pagination_info) = res.pagination { + pagination = Some(create_pagination(pagination_info.next_key)) + } else { + break; + } + } + + raw_codes + .into_iter() + .map(TryFrom::try_from) + .collect::>() + } + + async fn get_code_details( + &self, + code_id: ContractCodeId, + ) -> Result { + let path = Some("/cosmwasm.wasm.v1beta1.Query/Code".parse().unwrap()); + + let req = QueryCodeRequest { code_id }; + + let res = self + .make_abci_query::<_, QueryCodeResponse>(path, req) + .await?; + + if let Some(code_info) = res.code_info { + Ok(CodeDetails::new(code_info.try_into()?, res.data)) + } else { + Err(ValidatorClientError::NoCodeInformation(code_id)) + } + } + async fn get_contracts( + &self, + code_id: ContractCodeId, + ) -> Result, ValidatorClientError> { + let path = Some( + "/cosmwasm.wasm.v1beta1.Query/ContractsByCode" + .parse() + .unwrap(), + ); + + let mut raw_contracts = Vec::new(); + let mut pagination = None; + + loop { + let req = QueryContractsByCodeRequest { + code_id, + pagination, + }; + + let mut res = self + .make_abci_query::<_, QueryContractsByCodeResponse>(path.clone(), req) + .await?; + + raw_contracts.append(&mut res.contracts); + if let Some(pagination_info) = res.pagination { + pagination = Some(create_pagination(pagination_info.next_key)) + } else { + break; + } + } + + raw_contracts + .iter() + .map(|raw| raw.parse()) + .collect::>() + .map_err(|_| { + ValidatorClientError::DeserializationError("Contract addresses".to_owned()) + }) + } + + async fn get_contract(&self, address: &AccountId) -> Result { + let path = Some("/cosmwasm.wasm.v1beta1.Query/ContractInfo".parse().unwrap()); + + let req = QueryContractInfoRequest { + address: address.to_string(), + }; + + let res = self + .make_abci_query::<_, QueryContractInfoResponse>(path, req) + .await?; + + let response_address = res.address; + if let Some(contract_info) = res.contract_info { + let address = response_address + .parse() + .map_err(|_| ValidatorClientError::MalformedAccountAddress(response_address))?; + Ok(Contract::new(address, contract_info.try_into()?)) + } else { + Err(ValidatorClientError::NoContractInformation(address.clone())) + } + } + + async fn get_contract_code_history( + &self, + address: &AccountId, + ) -> Result, ValidatorClientError> { + let path = Some( + "/cosmwasm.wasm.v1beta1.Query/ContractHistory" + .parse() + .unwrap(), + ); + + let mut raw_entries = Vec::new(); + let mut pagination = None; + + loop { + let req = QueryContractHistoryRequest { + address: address.to_string(), + pagination, + }; + + let mut res = self + .make_abci_query::<_, QueryContractHistoryResponse>(path.clone(), req) + .await?; + + raw_entries.append(&mut res.entries); + if let Some(pagination_info) = res.pagination { + pagination = Some(create_pagination(pagination_info.next_key)) + } else { + break; + } + } + + raw_entries + .into_iter() + .map(TryFrom::try_from) + .collect::>() + } + + async fn query_contract_raw( + &self, + address: &AccountId, + query_data: Vec, + ) -> Result, ValidatorClientError> { + let path = Some( + "/cosmwasm.wasm.v1beta1.Query/RawContractState" + .parse() + .unwrap(), + ); + + let req = QueryRawContractStateRequest { + address: address.to_string(), + query_data, + }; + + let res = self + .make_abci_query::<_, QueryRawContractStateResponse>(path, req) + .await?; + + Ok(res.data) + } + + async fn query_contract_smart( + &self, + address: &AccountId, + query_msg: &M, + ) -> Result + where + M: ?Sized + Serialize + Sync, + for<'a> T: Deserialize<'a>, + { + let path = Some( + "/cosmwasm.wasm.v1beta1.Query/SmartContractState" + .parse() + .unwrap(), + ); + + // As per serde documentation: + // Serialization can fail if `T`'s implementation of `Serialize` decides to + // fail, or if `T` contains a map with non-string keys. + let req = QuerySmartContractStateRequest { + address: address.to_string(), + query_data: serde_json::to_vec(query_msg)?, + }; + + let res = self + .make_abci_query::<_, QuerySmartContractStateResponse>(path, req) + .await?; + + Ok(serde_json::from_slice(&res.data)?) + } +} diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/helpers.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/helpers.rs new file mode 100644 index 0000000000..dac512dac1 --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/helpers.rs @@ -0,0 +1,57 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::ValidatorClientError; +use cosmos_sdk::proto::cosmos::base::query::v1beta1::PageRequest; +use cosmos_sdk::rpc::endpoint::broadcast; +use flate2::write::GzEncoder; +use flate2::Compression; +use std::io::Write; + +pub(crate) trait CheckResponse: Sized { + fn check_response(self) -> Result; +} + +impl CheckResponse for broadcast::tx_commit::Response { + fn check_response(self) -> Result { + if self.check_tx.code.is_err() { + return Err(ValidatorClientError::BroadcastTxErrorCheckTx { + hash: self.hash, + height: self.height, + code: self.check_tx.code.value(), + raw_log: self.check_tx.log.value().to_owned(), + }); + } + + if self.deliver_tx.code.is_err() { + return Err(ValidatorClientError::BroadcastTxErrorDeliverTx { + hash: self.hash, + height: self.height, + code: self.deliver_tx.code.value(), + raw_log: self.deliver_tx.log.value().to_owned(), + }); + } + + Ok(self) + } +} + +pub(crate) fn compress_wasm_code(code: &[u8]) -> Result, ValidatorClientError> { + // using compression level 9, same as cosmjs, that optimises for size + let mut encoder = GzEncoder::new(Vec::new(), Compression::best()); + encoder + .write_all(code) + .map_err(ValidatorClientError::WasmCompressionError)?; + encoder + .finish() + .map_err(ValidatorClientError::WasmCompressionError) +} + +pub(crate) fn create_pagination(key: Vec) -> PageRequest { + PageRequest { + key, + offset: 0, + limit: 0, + count_total: false, + } +} diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/logs.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/logs.rs new file mode 100644 index 0000000000..0e1aaf3ff2 --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/logs.rs @@ -0,0 +1,92 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::ValidatorClientError; +use cosmos_sdk::tendermint::abci; +use itertools::Itertools; +use serde::Deserialize; + +// it seems that currently validators just emit stringified events (which are also returned as part of deliverTx response) +// as theirs logs +#[derive(Debug, Deserialize)] +pub struct Log { + #[serde(default)] + // weird thing is that the first msg_index seems to always be undefined on the raw logs + msg_index: usize, + // unless I'm missing something obvious, the "log" type in cosmjs is always an empty string + // and launchpad cosmos validator was setting it to what essentially is just the raw version of what + // we received (and we don't care about launchpad, we, as the time of writing this, work on the stargate) + // log: String, + events: Vec, +} + +/// Searches in logs for the first event of the given event type and in that event +/// for the first attribute with the given attribute key. +pub(crate) fn find_attribute<'a>( + logs: &'a [Log], + event_type: &str, + attribute_key: &str, +) -> Option<&'a cosmwasm_std::Attribute> { + logs.iter() + .flat_map(|log| log.events.iter()) + .find(|event| event.kind == event_type)? + .attributes + .iter() + .find(|attr| attr.key == attribute_key) +} + +// those two functions were separated so that the internal logic could actually be tested +fn parse_raw_str_logs(raw: &str) -> Result, ValidatorClientError> { + let logs: Vec = + serde_json::from_str(raw).map_err(|_| ValidatorClientError::MalformedLogString)?; + if logs.len() != logs.iter().unique_by(|log| log.msg_index).count() { + // this check is only here because I don't yet fully understand raw log string generation and + // the fact the first entry does not seem to have `msg_index` defined on it. + return Err(ValidatorClientError::MalformedLogString); + } + Ok(logs) +} + +pub fn parse_raw_logs(raw: abci::Log) -> Result, ValidatorClientError> { + parse_raw_str_logs(raw.as_ref()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn logs_parsing_with_single_tx() { + let raw = r#"[{"events":[{"type":"message","attributes":[{"key":"action","value":"store-code"},{"key":"module","value":"wasm"},{"key":"signer","value":"punk1m4aj8tgc0rqlms3s0c8jf3pcrma5xw2waafzjt"},{"key":"code_id","value":"1"}]}]}]"#; + let parsed = parse_raw_str_logs(raw).unwrap(); + assert_eq!(parsed.len(), 1); + assert_eq!(parsed[0].msg_index, 0); + assert_eq!(parsed[0].events.len(), 1); + assert_eq!(parsed[0].events[0].kind, "message"); + assert_eq!(parsed[0].events[0].attributes[3].key, "code_id"); + assert_eq!(parsed[0].events[0].attributes[3].value, "1"); + } + + #[test] + fn logs_parsing_with_multiple_txs() { + let raw = r#"[{"events":[{"type":"message","attributes":[{"key":"action","value":"store-code"},{"key":"module","value":"wasm"},{"key":"signer","value":"punk1q9n5a3cgw3azegcddr82s0f5nxeel4pup8vxzt"},{"key":"code_id","value":"9"}]}]},{"msg_index":1,"events":[{"type":"message","attributes":[{"key":"action","value":"store-code"},{"key":"module","value":"wasm"},{"key":"signer","value":"punk1q9n5a3cgw3azegcddr82s0f5nxeel4pup8vxzt"},{"key":"code_id","value":"10"}]}]},{"msg_index":2,"events":[{"type":"message","attributes":[{"key":"action","value":"store-code"},{"key":"module","value":"wasm"},{"key":"signer","value":"punk1q9n5a3cgw3azegcddr82s0f5nxeel4pup8vxzt"},{"key":"code_id","value":"11"}]}]}]"#; + let parsed = parse_raw_str_logs(raw).unwrap(); + assert_eq!(parsed.len(), 3); + assert_eq!(parsed[0].msg_index, 0); + assert_eq!(parsed[1].msg_index, 1); + assert_eq!(parsed[2].msg_index, 2); + + assert_eq!(parsed[0].events.len(), 1); + assert_eq!(parsed[0].events[0].kind, "message"); + assert_eq!(parsed[0].events[0].attributes[3].key, "code_id"); + assert_eq!(parsed[0].events[0].attributes[3].value, "9"); + + assert_eq!(parsed[2].events.len(), 1); + assert_eq!(parsed[2].events[0].kind, "message"); + assert_eq!(parsed[2].events[0].attributes[2].key, "signer"); + assert_eq!( + parsed[2].events[0].attributes[2].value, + "punk1q9n5a3cgw3azegcddr82s0f5nxeel4pup8vxzt" + ); + } +} diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs new file mode 100644 index 0000000000..75f5a3460a --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs @@ -0,0 +1,31 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nymd::wallet::DirectSecp256k1HdWallet; +use crate::ValidatorClientError; +use cosmos_sdk::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl}; +use std::convert::TryInto; + +pub mod client; +mod helpers; +pub mod logs; +pub mod signing_client; +pub mod types; + +pub fn connect(endpoint: U) -> Result +where + U: TryInto, +{ + Ok(HttpClient::new(endpoint)?) +} + +// maybe the wallet could be made into a generic, but for now, let's just have this one implementation +pub fn connect_with_signer( + endpoint: U, + signer: DirectSecp256k1HdWallet, +) -> Result +where + U: TryInto, +{ + signing_client::Client::connect_with_signer(endpoint, signer) +} diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs new file mode 100644 index 0000000000..b893120de5 --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs @@ -0,0 +1,485 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nymd::cosmwasm_client::client::CosmWasmClient; +use crate::nymd::cosmwasm_client::helpers::{compress_wasm_code, CheckResponse}; +use crate::nymd::cosmwasm_client::logs::{self, parse_raw_logs}; +use crate::nymd::cosmwasm_client::types::*; +use crate::nymd::wallet::DirectSecp256k1HdWallet; +use crate::ValidatorClientError; +use async_trait::async_trait; +use cosmos_sdk::bank::MsgSend; +use cosmos_sdk::distribution::MsgWithdrawDelegatorReward; +use cosmos_sdk::rpc::endpoint::broadcast; +use cosmos_sdk::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl, SimpleRequest}; +use cosmos_sdk::staking::{MsgDelegate, MsgUndelegate}; +use cosmos_sdk::tx::{Fee, Msg, MsgType, SignDoc, SignerInfo}; +use cosmos_sdk::{cosmwasm, rpc, tx, AccountId, Coin}; +use serde::Serialize; +use sha2::Digest; +use sha2::Sha256; +use std::convert::TryInto; + +#[async_trait] +pub trait SigningCosmWasmClient: CosmWasmClient { + fn signer(&self) -> &DirectSecp256k1HdWallet; + + async fn upload( + &self, + sender_address: &AccountId, + wasm_code: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + mut meta: Option, + ) -> Result { + let compressed = compress_wasm_code(&wasm_code)?; + let compressed_size = compressed.len(); + let compressed_checksum = Sha256::digest(&compressed).to_vec(); + + // TODO: what about instantiate_permission? + // cosmjs is just ignoring that field... + let upload_msg = cosmwasm::MsgStoreCode { + sender: sender_address.clone(), + wasm_byte_code: compressed, + source: meta + .as_mut() + .map(|meta| meta.source.take()) + .unwrap_or_default(), + builder: meta + .as_mut() + .map(|meta| meta.builder.take()) + .unwrap_or_default(), + instantiate_permission: Default::default(), + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgStoreCode".to_owned()))?; + + let tx_res = self + .sign_and_broadcast_commit(sender_address, vec![upload_msg], fee, memo) + .await? + .check_response()?; + + let logs = parse_raw_logs(tx_res.deliver_tx.log)?; + + // TODO: should those strings be extracted into some constants? + // the reason I think unwrap here is fine is that if the transaction succeeded and those + // fields do not exist or code_id is not a number, there's no way we can recover, we're probably connected + // to wrong validator or something + let code_id = logs::find_attribute(&logs, "message", "code_id") + .unwrap() + .value + .parse() + .unwrap(); + + Ok(UploadResult { + original_size: wasm_code.len(), + original_checksum: Sha256::digest(&wasm_code).to_vec(), + compressed_size, + compressed_checksum, + code_id, + logs, + transaction_hash: tx_res.hash, + }) + } + + // honestly, I don't see a nice way of removing any arguments + // perhaps memo could be moved to options like what cosmjs is doing + // put personally I'd prefer to leave it there for consistency with + // signatures of other methods + #[allow(clippy::too_many_arguments)] + async fn instantiate( + &self, + sender_address: &AccountId, + code_id: ContractCodeId, + msg: &M, + label: String, + fee: Fee, + memo: impl Into + Send + 'static, + mut options: Option, + ) -> Result + where + M: ?Sized + Serialize + Sync, + { + let init_msg = cosmwasm::MsgInstantiateContract { + sender: sender_address.clone(), + admin: options + .as_mut() + .map(|options| options.admin.take()) + .flatten(), + code_id, + // now this is a weird one. the protobuf files say this field is optional, + // but if you omit it, the initialisation will fail CheckTx + label: Some(label), + init_msg: serde_json::to_vec(msg)?, + funds: options.map(|options| options.funds).unwrap_or_default(), + } + .to_msg() + .map_err(|_| { + ValidatorClientError::SerializationError("MsgInstantiateContract".to_owned()) + })?; + + let tx_res = self + .sign_and_broadcast_commit(sender_address, vec![init_msg], fee, memo) + .await? + .check_response()?; + + let logs = parse_raw_logs(tx_res.deliver_tx.log)?; + + // TODO: should those strings be extracted into some constants? + // the reason I think unwrap here is fine is that if the transaction succeeded and those + // fields do not exist or address is malformed, there's no way we can recover, we're probably connected + // to wrong validator or something + let contract_address = logs::find_attribute(&logs, "message", "contract_address") + .unwrap() + .value + .parse() + .unwrap(); + + Ok(InstantiateResult { + contract_address, + logs, + transaction_hash: tx_res.hash, + }) + } + + async fn update_admin( + &self, + sender_address: &AccountId, + contract_address: &AccountId, + new_admin: &AccountId, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let change_admin_msg = cosmwasm::MsgUpdateAdmin { + sender: sender_address.clone(), + new_admin: new_admin.clone(), + contract: contract_address.clone(), + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgUpdateAdmin".to_owned()))?; + + let tx_res = self + .sign_and_broadcast_commit(sender_address, vec![change_admin_msg], fee, memo) + .await? + .check_response()?; + + Ok(ChangeAdminResult { + logs: parse_raw_logs(tx_res.deliver_tx.log)?, + transaction_hash: tx_res.hash, + }) + } + + async fn clear_admin( + &self, + sender_address: &AccountId, + contract_address: &AccountId, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let change_admin_msg = cosmwasm::MsgClearAdmin { + sender: sender_address.clone(), + contract: contract_address.clone(), + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgClearAdmin".to_owned()))?; + + let tx_res = self + .sign_and_broadcast_commit(sender_address, vec![change_admin_msg], fee, memo) + .await? + .check_response()?; + + Ok(ChangeAdminResult { + logs: parse_raw_logs(tx_res.deliver_tx.log)?, + transaction_hash: tx_res.hash, + }) + } + + async fn migrate( + &self, + sender_address: &AccountId, + contract_address: &AccountId, + code_id: u64, + fee: Fee, + msg: &M, + memo: impl Into + Send + 'static, + ) -> Result + where + M: ?Sized + Serialize + Sync, + { + let migrate_msg = cosmwasm::MsgMigrateContract { + sender: sender_address.clone(), + contract: contract_address.clone(), + code_id, + migrate_msg: serde_json::to_vec(msg)?, + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgMigrateContract".to_owned()))?; + + let tx_res = self + .sign_and_broadcast_commit(sender_address, vec![migrate_msg], fee, memo) + .await? + .check_response()?; + + Ok(MigrateResult { + logs: parse_raw_logs(tx_res.deliver_tx.log)?, + transaction_hash: tx_res.hash, + }) + } + + async fn execute( + &self, + sender_address: &AccountId, + contract_address: &AccountId, + msg: &M, + fee: Fee, + memo: impl Into + Send + 'static, + funds: Option>, + ) -> Result + where + M: ?Sized + Serialize + Sync, + { + let execute_msg = cosmwasm::MsgExecuteContract { + sender: sender_address.clone(), + contract: contract_address.clone(), + msg: serde_json::to_vec(msg)?, + funds: funds.unwrap_or_default(), + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgExecuteContract".to_owned()))?; + + let tx_res = self + .sign_and_broadcast_commit(sender_address, vec![execute_msg], fee, memo) + .await? + .check_response()?; + + Ok(ExecuteResult { + logs: parse_raw_logs(tx_res.deliver_tx.log)?, + transaction_hash: tx_res.hash, + }) + } + + async fn send_tokens( + &self, + sender_address: &AccountId, + recipient_address: &AccountId, + amount: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let send_msg = MsgSend { + from_address: sender_address.clone(), + to_address: recipient_address.clone(), + amount, + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgSend".to_owned()))?; + + self.sign_and_broadcast_commit(sender_address, vec![send_msg], fee, memo) + .await + } + + async fn delegate_tokens( + &self, + delegator_address: &AccountId, + validator_address: &AccountId, + amount: Coin, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let delegate_msg = MsgDelegate { + delegator_address: delegator_address.to_owned(), + validator_address: validator_address.to_owned(), + amount: Some(amount), + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgDelegate".to_owned()))?; + + self.sign_and_broadcast_commit(delegator_address, vec![delegate_msg], fee, memo) + .await + } + + async fn undelegate_tokens( + &self, + delegator_address: &AccountId, + validator_address: &AccountId, + amount: Coin, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let undelegate_msg = MsgUndelegate { + delegator_address: delegator_address.to_owned(), + validator_address: validator_address.to_owned(), + amount: Some(amount), + } + .to_msg() + .map_err(|_| ValidatorClientError::SerializationError("MsgUndelegate".to_owned()))?; + + self.sign_and_broadcast_commit(delegator_address, vec![undelegate_msg], fee, memo) + .await + } + + async fn withdraw_rewards( + &self, + delegator_address: &AccountId, + validator_address: &AccountId, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let withdraw_msg = MsgWithdrawDelegatorReward { + delegator_address: delegator_address.to_owned(), + validator_address: validator_address.to_owned(), + } + .to_msg() + .map_err(|_| { + ValidatorClientError::SerializationError("MsgWithdrawDelegatorReward".to_owned()) + })?; + + self.sign_and_broadcast_commit(delegator_address, vec![withdraw_msg], fee, memo) + .await + } + + /// Broadcast a transaction, returning immediately. + async fn sign_and_broadcast_async( + &self, + signer_address: &AccountId, + messages: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let tx_raw = self.sign(signer_address, messages, fee, memo).await?; + let tx_bytes = tx_raw + .to_bytes() + .map_err(|_| ValidatorClientError::SerializationError("Tx".to_owned()))?; + + CosmWasmClient::broadcast_tx_async(self, tx_bytes.into()).await + } + + /// Broadcast a transaction, returning the response from `CheckTx`. + async fn sign_and_broadcast_sync( + &self, + signer_address: &AccountId, + messages: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let tx_raw = self.sign(signer_address, messages, fee, memo).await?; + let tx_bytes = tx_raw + .to_bytes() + .map_err(|_| ValidatorClientError::SerializationError("Tx".to_owned()))?; + + CosmWasmClient::broadcast_tx_sync(self, tx_bytes.into()).await + } + + /// Broadcast a transaction, returning the response from `DeliverTx`. + async fn sign_and_broadcast_commit( + &self, + signer_address: &AccountId, + messages: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + let tx_raw = self.sign(signer_address, messages, fee, memo).await?; + let tx_bytes = tx_raw + .to_bytes() + .map_err(|_| ValidatorClientError::SerializationError("Tx".to_owned()))?; + + CosmWasmClient::broadcast_tx_commit(self, tx_bytes.into()).await + } + + fn sign_direct( + &self, + signer_address: &AccountId, + messages: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + signer_data: SignerData, + ) -> Result { + let signer_accounts = self.signer().try_derive_accounts()?; + let account_from_signer = signer_accounts + .iter() + .find(|account| &account.address == signer_address) + .ok_or_else(|| ValidatorClientError::SigningAccountNotFound(signer_address.clone()))?; + + // TODO: WTF HOW IS TIMEOUT_HEIGHT SUPPOSED TO GET DETERMINED? + // IT DOESNT EXIST IN COSMJS!! + // try to set to 0 + let timeout_height = 0u32; + + let tx_body = tx::Body::new(messages, memo, timeout_height); + let signer_info = + SignerInfo::single_direct(Some(account_from_signer.public_key), signer_data.sequence); + let auth_info = signer_info.auth_info(fee); + + // ideally I'd prefer to have the entire error put into the ValidatorClientError::SigningFailure + // but I'm super hesitant to trying to downcast the eyre::Report to cosmos_sdk::error::Error + let sign_doc = SignDoc::new( + &tx_body, + &auth_info, + &signer_data.chain_id, + signer_data.account_number, + ) + .map_err(|_| ValidatorClientError::SigningFailure)?; + + self.signer() + .sign_direct_with_account(account_from_signer, sign_doc) + } + + async fn sign( + &self, + signer_address: &AccountId, + messages: Vec, + fee: Fee, + memo: impl Into + Send + 'static, + ) -> Result { + // TODO: Future optimisation: rather than grabbing current account_number and sequence + // on every sign request -> just keep them cached on the struct and increment as required + let sequence_response = self.get_sequence(signer_address).await?; + let chain_id = self.get_chain_id().await?; + + let signer_data = SignerData { + account_number: sequence_response.account_number, + sequence: sequence_response.sequence, + chain_id, + }; + + self.sign_direct(signer_address, messages, fee, memo, signer_data) + } +} + +pub struct Client { + rpc_client: HttpClient, + signer: DirectSecp256k1HdWallet, +} + +impl Client { + pub fn connect_with_signer( + endpoint: U, + signer: DirectSecp256k1HdWallet, + ) -> Result + where + U: TryInto, + { + let rpc_client = HttpClient::new(endpoint)?; + Ok(Client { rpc_client, signer }) + } +} + +#[async_trait] +impl rpc::Client for Client { + async fn perform(&self, request: R) -> rpc::Result + where + R: SimpleRequest, + { + self.rpc_client.perform(request).await + } +} + +#[async_trait] +impl CosmWasmClient for Client {} + +#[async_trait] +impl SigningCosmWasmClient for Client { + fn signer(&self) -> &DirectSecp256k1HdWallet { + &self.signer + } +} diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs new file mode 100644 index 0000000000..af158916fa --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/types.rs @@ -0,0 +1,344 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +// TODO: There's a significant argument to pull those out of the package and make a PR on https://github.com/cosmos/cosmos-rust/ + +use crate::nymd::cosmwasm_client::logs::Log; +use crate::ValidatorClientError; +use cosmos_sdk::crypto::PublicKey; +use cosmos_sdk::proto::cosmos::auth::v1beta1::BaseAccount; +use cosmos_sdk::proto::cosmwasm::wasm::v1beta1::{ + CodeInfoResponse, ContractCodeHistoryEntry as ProtoContractCodeHistoryEntry, + ContractCodeHistoryOperationType, ContractInfo as ProtoContractInfo, +}; +use cosmos_sdk::tendermint::chain; +use cosmos_sdk::tx::{AccountNumber, SequenceNumber}; +use cosmos_sdk::{tx, AccountId, Coin}; +use serde::Serialize; +use std::convert::TryFrom; + +pub type ContractCodeId = u64; + +#[derive(Serialize)] +pub struct EmptyMsg {} + +#[derive(Debug)] +pub struct SequenceResponse { + pub account_number: AccountNumber, + pub sequence: SequenceNumber, +} + +#[derive(Debug)] +pub struct Account { + /// Bech32 account address + pub address: AccountId, + pub pubkey: Option, + pub account_number: AccountNumber, + pub sequence: SequenceNumber, +} + +impl TryFrom for Account { + type Error = ValidatorClientError; + + fn try_from(value: BaseAccount) -> Result { + let address: AccountId = value + .address + .parse() + .map_err(|_| ValidatorClientError::MalformedAccountAddress(value.address.clone()))?; + + let pubkey = value + .pub_key + .map(PublicKey::try_from) + .transpose() + .map_err(|_| ValidatorClientError::InvalidPublicKey(address.clone()))?; + + Ok(Account { + address, + pubkey, + account_number: value.account_number, + sequence: value.sequence, + }) + } +} + +#[derive(Debug)] +pub struct Code { + pub code_id: ContractCodeId, + + /// Bech32 account address + pub creator: AccountId, + + /// sha256 hash of the code stored + pub data_hash: Vec, + + /// An URL to a .tar.gz archive of the source code of the contract, + /// which can be used to reproducibly build the Wasm bytecode. + /// + /// @see https://github.com/CosmWasm/cosmwasm-verify + pub source: Option, + + /// A docker image (including version) to reproducibly build the Wasm bytecode from the source code. + /// + /// @example ```cosmwasm/rust-optimizer:0.8.0``` + /// @see https://github.com/CosmWasm/cosmwasm-verify + pub builder: Option, +} + +impl TryFrom for Code { + type Error = ValidatorClientError; + + fn try_from(value: CodeInfoResponse) -> Result { + let CodeInfoResponse { + code_id, + creator, + data_hash, + source, + builder, + } = value; + + let creator = creator + .parse() + .map_err(|_| ValidatorClientError::MalformedAccountAddress(creator))?; + + let source = if source.is_empty() { + None + } else { + Some(source) + }; + let builder = if builder.is_empty() { + None + } else { + Some(builder) + }; + + Ok(Code { + code_id, + creator, + data_hash, + source, + builder, + }) + } +} + +#[derive(Debug)] +pub struct CodeDetails { + pub code_info: Code, + + /// The original wasm bytes + pub data: Vec, +} + +impl CodeDetails { + pub fn new(code_info: Code, data: Vec) -> Self { + CodeDetails { code_info, data } + } +} + +#[derive(Debug)] +pub(crate) struct ContractInfo { + code_id: ContractCodeId, + creator: AccountId, + admin: Option, + label: String, +} + +impl TryFrom for ContractInfo { + type Error = ValidatorClientError; + + fn try_from(value: ProtoContractInfo) -> Result { + let ProtoContractInfo { + code_id, + creator, + admin, + label, + .. + } = value; + + let admin = if admin.is_empty() { + None + } else { + Some( + admin + .parse() + .map_err(|_| ValidatorClientError::MalformedAccountAddress(admin))?, + ) + }; + + Ok(ContractInfo { + code_id, + creator: creator + .parse() + .map_err(|_| ValidatorClientError::MalformedAccountAddress(creator))?, + admin, + label, + }) + } +} + +#[derive(Debug)] +pub struct Contract { + pub address: AccountId, + + pub code_id: ContractCodeId, + + /// Bech32 account address + pub creator: AccountId, + + /// Bech32-encoded admin address + pub admin: Option, + + pub label: String, +} + +impl Contract { + pub(crate) fn new(address: AccountId, contract_info: ContractInfo) -> Self { + Contract { + address, + code_id: contract_info.code_id, + creator: contract_info.creator, + admin: contract_info.admin, + label: contract_info.label, + } + } +} + +#[derive(Clone, Copy, Debug)] +pub enum ContractCodeHistoryEntryOperation { + Init, + Genesis, + Migrate, +} + +#[derive(Debug)] +pub struct ContractCodeHistoryEntry { + /// The source of this history entry + pub operation: ContractCodeHistoryEntryOperation, + pub code_id: ContractCodeId, + pub msg_json: String, +} + +impl TryFrom for ContractCodeHistoryEntry { + type Error = ValidatorClientError; + + fn try_from(value: ProtoContractCodeHistoryEntry) -> Result { + let operation = match ContractCodeHistoryOperationType::from_i32(value.operation) + .ok_or(ValidatorClientError::InvalidContractHistoryOperation)? + { + ContractCodeHistoryOperationType::Unspecified => { + return Err(ValidatorClientError::InvalidContractHistoryOperation) + } + ContractCodeHistoryOperationType::Init => ContractCodeHistoryEntryOperation::Init, + ContractCodeHistoryOperationType::Genesis => ContractCodeHistoryEntryOperation::Genesis, + ContractCodeHistoryOperationType::Migrate => ContractCodeHistoryEntryOperation::Migrate, + }; + + Ok(ContractCodeHistoryEntry { + operation, + code_id: value.code_id, + msg_json: String::from_utf8(value.msg).map_err(|_| { + ValidatorClientError::DeserializationError("Contract history msg".to_owned()) + })?, + }) + } +} + +// ############################################################################## +// types specific to the signing client (perhaps they should go to separate file) +// ############################################################################## + +/// Signing information for a single signer that is not included in the transaction. +#[derive(Debug)] +pub struct SignerData { + pub account_number: AccountNumber, + pub sequence: SequenceNumber, + pub chain_id: chain::Id, +} + +#[derive(Debug)] +pub struct UploadMeta { + /// An URL to a .tar.gz archive of the source code of the contract, + /// which can be used to reproducibly build the Wasm bytecode. + /// + /// @see https://github.com/CosmWasm/cosmwasm-verify + pub source: Option, + + /// A docker image (including version) to reproducibly build the Wasm bytecode from the source code. + /// + /// @example ```cosmwasm/rust-optimizer:0.8.0``` + /// @see https://github.com/CosmWasm/cosmwasm-verify + pub builder: Option, +} + +#[derive(Debug)] +pub struct UploadResult { + /// Size of the original wasm code in bytes + pub original_size: usize, + + /// A hex encoded sha256 checksum of the original wasm code (that is stored on chain) + pub original_checksum: Vec, + + /// Size of the compressed wasm code in bytes + pub compressed_size: usize, + + /// A sha256 checksum of the compressed wasm code (that is stored in the transaction) + pub compressed_checksum: Vec, + + /// The ID of the code assigned by the chain + pub code_id: ContractCodeId, + + pub logs: Vec, + + /// Transaction hash (might be used as transaction ID) + pub transaction_hash: tx::Hash, +} + +#[derive(Debug)] +pub struct InstantiateOptions { + /// The funds that are transferred from the sender to the newly created contract. + /// The funds are transferred as part of the message execution after the contract address is + /// created and before the instantiation message is executed by the contract. + /// + /// Only native tokens are supported. + pub funds: Vec, + + /// A bech32 encoded address of an admin account. + /// Caution: an admin has the privilege to upgrade a contract. + /// If this is not desired, do not set this value. + pub admin: Option, +} + +#[derive(Debug)] +pub struct InstantiateResult { + /// The address of the newly instantiated contract + pub contract_address: AccountId, + + pub logs: Vec, + + /// Transaction hash (might be used as transaction ID) + pub transaction_hash: tx::Hash, +} + +#[derive(Debug)] +pub struct ChangeAdminResult { + pub logs: Vec, + + /// Transaction hash (might be used as transaction ID) + pub transaction_hash: tx::Hash, +} + +#[derive(Debug)] +pub struct MigrateResult { + pub logs: Vec, + + /// Transaction hash (might be used as transaction ID) + pub transaction_hash: tx::Hash, +} + +#[derive(Debug)] +pub struct ExecuteResult { + pub logs: Vec, + + /// Transaction hash (might be used as transaction ID) + pub transaction_hash: tx::Hash, +} diff --git a/common/client-libs/validator-client/src/nymd/mod.rs b/common/client-libs/validator-client/src/nymd/mod.rs new file mode 100644 index 0000000000..14b21e5a59 --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/mod.rs @@ -0,0 +1,226 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::models::QueryRequest; +use crate::nymd::cosmwasm_client::client::CosmWasmClient; +use crate::nymd::cosmwasm_client::signing_client; +use crate::nymd::cosmwasm_client::signing_client::SigningCosmWasmClient; +use crate::nymd::cosmwasm_client::types::ExecuteResult; +use crate::nymd::wallet::DirectSecp256k1HdWallet; +use crate::ValidatorClientError; +use cosmos_sdk::rpc::{Error as TendermintRpcError, HttpClient, HttpClientUrl}; +use cosmos_sdk::tx::Fee; +use cosmos_sdk::Coin as CosmosCoin; +use cosmos_sdk::{AccountId, Denom}; +use cosmwasm_std::Coin; +use mixnet_contract::LayerDistribution; +use std::convert::TryInto; + +pub mod cosmwasm_client; +pub mod wallet; + +pub struct NymdClient { + client: C, + contract_address: AccountId, + client_address: Option>, +} + +impl NymdClient { + pub fn connect( + endpoint: U, + contract_address: AccountId, + ) -> Result, ValidatorClientError> + where + U: TryInto, + { + Ok(NymdClient { + client: HttpClient::new(endpoint)?, + contract_address, + client_address: None, + }) + } +} + +impl NymdClient { + // maybe the wallet could be made into a generic, but for now, let's just have this one implementation + pub fn connect_with_signer( + endpoint: U, + contract_address: AccountId, + signer: DirectSecp256k1HdWallet, + ) -> Result, ValidatorClientError> + where + U: TryInto, + { + let client_address = signer + .try_derive_accounts()? + .into_iter() + .map(|account| account.address) + .collect(); + + Ok(NymdClient { + client: signing_client::Client::connect_with_signer(endpoint, signer)?, + contract_address, + client_address: Some(client_address), + }) + } + + pub fn connect_with_mnemonic( + endpoint: U, + contract_address: AccountId, + mnemonic: bip39::Mnemonic, + ) -> Result, ValidatorClientError> + where + U: TryInto, + { + let wallet = DirectSecp256k1HdWallet::from_mnemonic(mnemonic)?; + let client_address = wallet + .try_derive_accounts()? + .into_iter() + .map(|account| account.address) + .collect(); + + Ok(NymdClient { + client: signing_client::Client::connect_with_signer(endpoint, wallet)?, + contract_address, + client_address: Some(client_address), + }) + } +} + +impl NymdClient { + pub fn address(&self) -> &AccountId + where + C: SigningCosmWasmClient, + { + // if this is a signing client (as required by the trait bound), it must have the address set + &self.client_address.as_ref().unwrap()[0] + } + + // now the question is as follows: will denom always be in the format of `u{prefix}`? + fn denom(&self) -> Denom { + format!("u{}", self.contract_address.prefix()) + .parse() + .unwrap() + } + + // just some example API (that will be expanded on in another PR) that those generics allow us to make: + + // this requires signing + pub async fn bond_mixnode( + &self, + mixnode: MixNode, + bond: Coin, + ) -> Result + where + C: SigningCosmWasmClient + Sync, + { + // TODO: will need to create some nice fee table, for now, for test sake, just use hardcoded value + let fee_amount = CosmosCoin { + amount: 100_0000u64.into(), + denom: self.denom(), + }; + let gas = 100_0000; + let fee = Fee::from_amount_and_gas(fee_amount, gas); + + let req = ExecuteMsg::BondMixnode { mix_node: mixnode }; + + self.client + .execute( + self.address(), + &self.contract_address, + &req, + fee, + "Bonding mixnode from rust!", + Some(vec![cosmwasm_coin_to_cosmos_coin(bond)]), + ) + .await + } + + // this is just a query + pub async fn get_layer_distribution(&self) -> Result + where + C: CosmWasmClient + Sync, + { + let request = QueryRequest::LayerDistribution {}; + self.client + .query_contract_smart(&self.contract_address, &request) + .await + } +} + +// this will be extracted from the smart contract into the common crate later. +// right now it's just to show how it will look later +#[derive(serde::Serialize)] +pub struct MixNode { + pub host: String, + pub mix_port: u16, + pub verloc_port: u16, + pub http_api_port: u16, + pub sphinx_key: String, + pub identity_key: String, + pub version: String, +} + +#[derive(serde::Serialize)] +#[serde(rename_all = "snake_case")] +pub enum ExecuteMsg { + BondMixnode { mix_node: MixNode }, +} + +// this should go to helpers +fn cosmwasm_coin_to_cosmos_coin(coin: Coin) -> CosmosCoin { + CosmosCoin { + denom: coin.denom.parse().unwrap(), + // this might be a bit iffy, cosmwasm coin stores value as u128, while cosmos does it as u64 + amount: (coin.amount.u128() as u64).into(), + } +} + +// #[cfg(test)] +// mod tests { +// use super::*; +// use cosmwasm_std::coin; +// +// #[tokio::test] +// async fn test_bond() { +// let validator = "http://127.0.0.1:26657"; +// let contract = "punk1uft3mmgha04vr23lx08fydpjym2003xuy9cnga" +// .parse::() +// .unwrap(); +// (this is just mnemonic for validator running on my local machine, so feel free to 'steal' it) +// let mnemonic = "claim border flee add vehicle crack romance assault fold wide flag year cousin false junk analyst parent eagle act visual tongue weasel basket impulse"; +// +// let client = +// NymdClient::connect_with_mnemonic(validator, contract, mnemonic.parse().unwrap()) +// .unwrap(); +// +// let mix = MixNode { +// host: "1.1.1.1".to_string(), +// mix_port: 1789, +// verloc_port: 1790, +// http_api_port: 8080, +// sphinx_key: "sphinxkey".to_string(), +// identity_key: "identitykey".to_string(), +// version: "0.11.0".to_string(), +// }; +// +// let result = client +// .bond_mixnode(mix, coin(100_000000, client.denom().as_ref())) +// .await +// .unwrap(); +// println!("{:#?}", result) +// } +// +// #[tokio::test] +// async fn test_get_layers() { +// let validator = "https://testnet-milhon-validator1.nymtech.net"; +// let contract = "punk10pyejy66429refv3g35g2t7am0was7yalwrzen" +// .parse::() +// .unwrap(); +// +// let client = NymdClient::connect(validator, contract).unwrap(); +// let layers = client.get_layer_distribution().await.unwrap(); +// +// println!("layers: {:#?}", layers); +// } +// } diff --git a/common/client-libs/validator-client/src/nymd/wallet/mod.rs b/common/client-libs/validator-client/src/nymd/wallet/mod.rs new file mode 100644 index 0000000000..ae293dd910 --- /dev/null +++ b/common/client-libs/validator-client/src/nymd/wallet/mod.rs @@ -0,0 +1,213 @@ +// Copyright 2021 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::ValidatorClientError; +use config::defaults; +use cosmos_sdk::bip32::{DerivationPath, XPrv}; +use cosmos_sdk::crypto::secp256k1::SigningKey; +use cosmos_sdk::crypto::PublicKey; +use cosmos_sdk::tx::SignDoc; +use cosmos_sdk::{tx, AccountId}; + +/// Derivation information required to derive a keypair and an address from a mnemonic. +struct Secp256k1Derivation { + hd_path: DerivationPath, + prefix: String, +} + +pub struct AccountData { + pub(crate) address: AccountId, + + pub(crate) public_key: PublicKey, + + pub(crate) private_key: SigningKey, +} + +type Secp256k1Keypair = (SigningKey, PublicKey); + +pub struct DirectSecp256k1HdWallet { + /// Base secret + secret: bip39::Mnemonic, + + /// BIP39 seed + seed: [u8; 64], + + // An unfortunate result of immature rust async story is that async traits (only available in the separate package) + // can't yet figure out everything and if we stored our derived account data on the struct, + // that would include the secret key which is a dyn EcdsaSigner and hence not Sync making the wallet + // not Sync and if used on the signing client in an async trait, it wouldn't be Send + /// Derivation instructions + accounts: Vec, +} + +impl DirectSecp256k1HdWallet { + pub fn builder() -> DirectSecp256k1HdWalletBuilder { + DirectSecp256k1HdWalletBuilder::default() + } + + /// Restores a wallet from the given BIP39 mnemonic using default options. + pub fn from_mnemonic(mnemonic: bip39::Mnemonic) -> Result { + DirectSecp256k1HdWalletBuilder::new().build(mnemonic) + } + + pub fn generate(word_count: usize) -> Result { + let mneomonic = bip39::Mnemonic::generate(word_count)?; + Self::from_mnemonic(mneomonic) + } + + fn derive_keypair( + &self, + hd_path: &DerivationPath, + ) -> Result { + let extended_private_key = XPrv::derive_from_path(&self.seed, hd_path)?; + + let private_key: SigningKey = extended_private_key.into(); + let public_key = private_key.public_key(); + + Ok((private_key, public_key)) + } + + pub fn try_derive_accounts(&self) -> Result, ValidatorClientError> { + let mut accounts = Vec::with_capacity(self.accounts.len()); + for derivation_info in &self.accounts { + let keypair = self.derive_keypair(&derivation_info.hd_path)?; + + // it seems this can only fail if the provided account prefix is invalid + let address = keypair + .1 + .account_id(&derivation_info.prefix) + .map_err(|_| ValidatorClientError::AccountDerivationError)?; + + accounts.push(AccountData { + address, + public_key: keypair.1, + private_key: keypair.0, + }) + } + + Ok(accounts) + } + + pub fn mnemonic(&self) -> String { + self.secret.to_string() + } + + pub fn sign_direct_with_account( + &self, + signer: &AccountData, + sign_doc: SignDoc, + ) -> Result { + // ideally I'd prefer to have the entire error put into the ValidatorClientError::SigningFailure + // but I'm super hesitant to trying to downcast the eyre::Report to cosmos_sdk::error::Error + sign_doc + .sign(&signer.private_key) + .map_err(|_| ValidatorClientError::SigningFailure) + } + + pub fn sign_direct( + &self, + signer_address: &AccountId, + sign_doc: SignDoc, + ) -> Result { + // I hate deriving accounts at every sign here so much : ( + let accounts = self.try_derive_accounts()?; + let account = accounts + .iter() + .find(|account| &account.address == signer_address) + .ok_or_else(|| ValidatorClientError::SigningAccountNotFound(signer_address.clone()))?; + + self.sign_direct_with_account(account, sign_doc) + } +} + +pub struct DirectSecp256k1HdWalletBuilder { + /// The password to use when deriving a BIP39 seed from a mnemonic. + bip39_password: String, + + /// The BIP-32/SLIP-10 derivation paths + hd_paths: Vec, + + /// The bech32 address prefix (human readable part) + prefix: String, +} + +impl Default for DirectSecp256k1HdWalletBuilder { + fn default() -> Self { + DirectSecp256k1HdWalletBuilder { + bip39_password: String::new(), + hd_paths: vec![defaults::COSMOS_DERIVATION_PATH.parse().unwrap()], + prefix: defaults::BECH32_PREFIX.to_string(), + } + } +} + +impl DirectSecp256k1HdWalletBuilder { + pub fn new() -> Self { + Default::default() + } + + pub fn with_bip39_password>(mut self, password: S) -> Self { + self.bip39_password = password.into(); + self + } + + pub fn with_hd_path(mut self, path: DerivationPath) -> Self { + self.hd_paths.push(path); + self + } + + pub fn with_hd_paths(mut self, hd_paths: Vec) -> Self { + self.hd_paths = hd_paths; + self + } + + pub fn with_prefix>(mut self, prefix: S) -> Self { + self.prefix = prefix.into(); + self + } + + pub fn build( + self, + mnemonic: bip39::Mnemonic, + ) -> Result { + let seed = mnemonic.to_seed(&self.bip39_password); + let prefix = self.prefix; + let accounts = self + .hd_paths + .into_iter() + .map(|hd_path| Secp256k1Derivation { + hd_path, + prefix: prefix.clone(), + }) + .collect(); + + Ok(DirectSecp256k1HdWallet { + accounts, + seed, + secret: mnemonic, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn generating_account_addresses() { + // test vectors produced from our js wallet + let mnemonic_address = vec![ + ("crush minute paddle tobacco message debate cabin peace bar jacket execute twenty winner view sure mask popular couch penalty fragile demise fresh pizza stove", "punk1jw6mp7d5xqc7w6xm79lha27glmd0vdt32a3fj2"), + ("acquire rebel spot skin gun such erupt pull swear must define ill chief turtle today flower chunk truth battle claw rigid detail gym feel", "punk1h5hgn94nsq4kh99rjj794hr5h5q6yfm22mcqqn"), + ("step income throw wheat mobile ship wave drink pool sudden upset jaguar bar globe rifle spice frost bless glimpse size regular carry aspect ball", "punk17n9flp6jflljg6fp05dsy07wcprf2uuujse962") + ]; + + for (mnemonic, address) in mnemonic_address.into_iter() { + let wallet = DirectSecp256k1HdWallet::from_mnemonic(mnemonic.parse().unwrap()).unwrap(); + assert_eq!( + wallet.try_derive_accounts().unwrap()[0].address, + address.parse().unwrap() + ) + } + } +} diff --git a/common/config/src/defaults.rs b/common/config/src/defaults.rs index e67cc413cc..00e67e74f7 100644 --- a/common/config/src/defaults.rs +++ b/common/config/src/defaults.rs @@ -7,6 +7,8 @@ pub const DEFAULT_VALIDATOR_REST_ENDPOINTS: &[&str] = &[ ]; pub const DEFAULT_MIXNET_CONTRACT_ADDRESS: &str = "punk10pyejy66429refv3g35g2t7am0was7yalwrzen"; pub const NETWORK_MONITOR_ADDRESS: &str = "punk1v9qauwdq5terag6uvfsdytcs2d0sdmfdy7hgk3"; +/// Defaults Cosmos Hub/ATOM path +pub const COSMOS_DERIVATION_PATH: &str = "m/44'/118'/0'/0/0"; pub const BECH32_PREFIX: &str = "punk"; pub const DENOM: &str = "upunk"; diff --git a/common/mixnet-contract/Cargo.toml b/common/mixnet-contract/Cargo.toml index cf58e7d104..6b963cfcac 100644 --- a/common/mixnet-contract/Cargo.toml +++ b/common/mixnet-contract/Cargo.toml @@ -7,7 +7,10 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -cosmwasm-std = { version = "0.14.1" } +# this branch is identical to 0.14.1 with addition of updated k256 dependency required to help poor cargo choose correct version +cosmwasm-std = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256" } +#cosmwasm-std = { version = "0.14.1" } + serde = { version = "1.0", features = ["derive"] } serde_repr = "0.1" schemars = "0.8" diff --git a/contracts/mixnet/Cargo.lock b/contracts/mixnet/Cargo.lock index 1ef54fd3cd..433b409d3c 100644 --- a/contracts/mixnet/Cargo.lock +++ b/contracts/mixnet/Cargo.lock @@ -8,17 +8,6 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "bitvec" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98fcd36dda4e17b7d7abc64cb549bf0201f4ab71e00700c798ca7e62ed3761fa" -dependencies = [ - "funty", - "radium", - "wyz", -] - [[package]] name = "block-buffer" version = "0.7.3" @@ -79,28 +68,26 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.4.5" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f6b64db6932c7e49332728e3a6bd82c6b7e16016607d20923b537c3bc4c0d5f" +checksum = "44c32f031ea41b4291d695026c023b95d59db2d8a2c7640800ed56bc8f510f22" [[package]] name = "cosmwasm-crypto" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038089cdadfe61e4e85617d91cecec2c49f828db8e5986bb85e29d0b29c59b77" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "digest 0.9.0", "ed25519-zebra", "k256", - "rand_core", + "rand_core 0.5.1", "thiserror", ] [[package]] name = "cosmwasm-derive" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bf3da935843795a7f52678262ef06398878b0cf4c89b69612d8525ea27b84" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "syn", ] @@ -118,8 +105,7 @@ dependencies = [ [[package]] name = "cosmwasm-std" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22de097cf4f7e7f575f51a22de7260932756ccfe499e005f98244a3043470e48" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "base64", "cosmwasm-crypto", @@ -134,8 +120,7 @@ dependencies = [ [[package]] name = "cosmwasm-storage" version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4abf200c2651e123595b18edf67df8702d19127b487d8b3e115dcc6c2ac0e0e" +source = "git+https://github.com/jstuczyn/cosmwasm?branch=0.14.1-updatedk256#308781cd5f33b0e996176c6b500793d3648c0f7b" dependencies = [ "cosmwasm-std", "serde", @@ -157,10 +142,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "crypto-mac" -version = "0.10.0" +name = "crypto-bigint" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" +checksum = "b32a398eb1ccfbe7e4f452bc749c44d38dd732e9a253f19da224c416f00ee7f4" +dependencies = [ + "generic-array 0.14.4", + "rand_core 0.6.3", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ "generic-array 0.14.4", "subtle", @@ -174,16 +171,16 @@ checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" dependencies = [ "byteorder", "digest 0.9.0", - "rand_core", + "rand_core 0.5.1", "subtle", "zeroize", ] [[package]] name = "der" -version = "0.1.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f59c66c30bb7445c8320a5f9233e437e3572368099f25532a59054328899b4" +checksum = "49f215f706081a44cb702c71c39a52c05da637822e9c1645a50b7202689e982d" dependencies = [ "const-oid", ] @@ -214,10 +211,11 @@ checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" [[package]] name = "ecdsa" -version = "0.10.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fbdb4ff710acb4db8ca29f93b897529ea6d6a45626d5183b47e012aa6ae7e4" +checksum = "713c32426287891008edb98f8b5c6abb2130aa043c93a818728fcda78606f274" dependencies = [ + "der", "elliptic-curve", "hmac", "signature", @@ -231,7 +229,7 @@ checksum = "0a128b76af6dd4b427e34a6fd43dc78dbfe73672ec41ff615a2414c1a0ad0409" dependencies = [ "curve25519-dalek", "hex", - "rand_core", + "rand_core 0.5.1", "serde", "sha2", "thiserror", @@ -239,18 +237,16 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.8.5" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2db227e61a43a34915680bdda462ec0e212095518020a88a1f91acd16092c39" +checksum = "83e5c176479da93a0983f0a6fdc3c1b8e7d5be0d7fe3fe05a99f15b96582b9a8" dependencies = [ - "bitvec", - "digest 0.9.0", + "crypto-bigint", "ff", - "funty", "generic-array 0.14.4", "group", "pkcs8", - "rand_core", + "rand_core 0.6.3", "subtle", "zeroize", ] @@ -263,21 +259,14 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "ff" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01646e077d4ebda82b73f1bca002ea1e91561a77df2431a9e79729bcc31950ef" +checksum = "63eec06c61e487eecf0f7e6e6372e596a81922c28d33e645d6983ca6493a1af0" dependencies = [ - "bitvec", - "rand_core", + "rand_core 0.6.3", "subtle", ] -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - [[package]] name = "generic-array" version = "0.12.4" @@ -305,17 +294,28 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", ] [[package]] name = "group" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc11f9f5fbf1943b48ae7c2bf6846e7d827a512d1be4f23af708f5ca5d01dde1" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.3", "subtle", ] @@ -341,9 +341,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hmac" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" dependencies = [ "crypto-mac", "digest 0.9.0", @@ -373,9 +373,9 @@ checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" [[package]] name = "k256" -version = "0.7.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4476a0808212a9e81ce802eb1a0cfc60e73aea296553bacc0fac7e1268bc572a" +checksum = "008b0281ca8032567c9711cd48631781c15228301860a39b32deb28d63125e46" dependencies = [ "cfg-if", "ecdsa", @@ -485,11 +485,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.3.3" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4839a901843f3942576e65857f0ebf2e190ef7024d3c62a94099ba3f819ad1d" +checksum = "fbee84ed13e44dd82689fa18348a49934fa79cc774a344c42fc9b301c71b140a" dependencies = [ "der", + "spki", ] [[package]] @@ -516,19 +517,22 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - [[package]] name = "rand_core" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "getrandom", + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", ] [[package]] @@ -650,12 +654,21 @@ dependencies = [ [[package]] name = "signature" -version = "1.2.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f060a7d147e33490ec10da418795238fd7545bba241504d6b31a409f2e6210" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" dependencies = [ "digest 0.9.0", - "rand_core", + "rand_core 0.6.3", +] + +[[package]] +name = "spki" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "987637c5ae6b3121aba9d513f869bd2bff11c4cc086c22473befd6649c0bd521" +dependencies = [ + "der", ] [[package]] @@ -753,10 +766,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] -name = "wyz" -version = "0.2.0" +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "zeroize" diff --git a/contracts/mixnet/Cargo.toml b/contracts/mixnet/Cargo.toml index 174a0f2dcf..13bd3ed584 100644 --- a/contracts/mixnet/Cargo.toml +++ b/contracts/mixnet/Cargo.toml @@ -35,8 +35,14 @@ backtraces = ["cosmwasm-std/backtraces"] [dependencies] mixnet-contract = { path = "../../common/mixnet-contract" } config = { path = "../../common/config"} -cosmwasm-std = { version = "0.14.1", features = ["iterator"] } -cosmwasm-storage = { version = "0.14.1", features = ["iterator"] } + +# this branch is identical to 0.14.1 with addition of updated k256 dependency required to help poor cargo choose correct version +cosmwasm-std = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", features = ["iterator"] } +cosmwasm-storage = { git = "https://github.com/jstuczyn/cosmwasm", branch="0.14.1-updatedk256", features = ["iterator"] } + +#cosmwasm-std = { version = "0.14.1", features = ["iterator"] } +#cosmwasm-storage = { version = "0.14.1", features = ["iterator"] } + schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { version = "1.0.23" }