diff --git a/Cargo.lock b/Cargo.lock index 2c40b9d7de..da32fb9729 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.26.2", + "gimli 0.27.2", ] [[package]] @@ -23,7 +23,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -44,16 +44,27 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.9", + "once_cell", + "version_check 0.9.4", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if 1.0.0", "once_cell", "version_check 0.9.4", ] [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -78,9 +89,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.65" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "ark-bls12-381" @@ -144,7 +155,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -156,7 +167,7 @@ dependencies = [ "num-bigint", "num-traits 0.2.15", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -191,7 +202,7 @@ checksum = "8dd4e5f0bf8285d5ed538d27fab7411f3e297908fd93c62195de8bee3f199e82" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -206,9 +217,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" @@ -250,34 +261,34 @@ checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" [[package]] name = "async-channel" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" dependencies = [ - "concurrent-queue", + "concurrent-queue 2.2.0", "event-listener", "futures-core", ] [[package]] name = "async-executor" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" dependencies = [ + "async-lock", "async-task", - "concurrent-queue", + "concurrent-queue 2.2.0", "fastrand", "futures-lite", - "once_cell", "slab", ] [[package]] name = "async-global-executor" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0da5b41ee986eed3f524c380e6d64965aea573882a8907682ad100f7859305ca" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" dependencies = [ "async-channel", "async-executor", @@ -294,7 +305,7 @@ version = "1.9.0" source = "git+https://github.com/heliaxdev/async-io.git?rev=9285dad39c9a37ecd0dbd498c5ce5b0e65b02489#9285dad39c9a37ecd0dbd498c5ce5b0e65b02489" dependencies = [ "autocfg 1.1.0", - "concurrent-queue", + "concurrent-queue 1.2.4", "futures-lite", "libc", "log 0.4.17", @@ -310,9 +321,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "2.5.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" dependencies = [ "event-listener", ] @@ -346,7 +357,7 @@ dependencies = [ "async-io", "async-lock", "async-process", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "futures-channel", "futures-core", "futures-io", @@ -365,40 +376,41 @@ dependencies = [ [[package]] name = "async-stream" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", + "pin-project-lite", ] [[package]] name = "async-stream-impl" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "async-task" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] @@ -419,9 +431,9 @@ dependencies = [ [[package]] name = "atomic-waker" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" [[package]] name = "atty" @@ -429,7 +441,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi 0.3.9", ] @@ -451,9 +463,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.7" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fb79c228270dcf2426e74864cabc94babb5dbab01a4314e702d2f16540e1591" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", @@ -462,34 +474,33 @@ dependencies = [ "futures-util", "http", "http-body", - "hyper 0.14.20", + "hyper 0.14.26", "itoa", "matchit", "memchr", - "mime 0.3.16", + "mime 0.3.17", "percent-encoding 2.2.0", "pin-project-lite", "rustversion", - "serde 1.0.145", + "serde 1.0.163", "sync_wrapper", "tower", - "tower-http", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes 1.4.0", "futures-util", "http", "http-body", - "mime 0.3.16", + "mime 0.3.17", "rustversion", "tower-layer", "tower-service", @@ -497,16 +508,16 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", - "miniz_oxide", - "object 0.29.0", + "miniz_oxide 0.6.2", + "object 0.30.3", "rustc-demangle", ] @@ -537,9 +548,9 @@ dependencies = [ [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" @@ -574,7 +585,7 @@ dependencies = [ "bitvec 0.22.3", "blake2s_simd 0.5.11", "byteorder", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "ff", "group", "lazy_static", @@ -598,11 +609,11 @@ dependencies = [ [[package]] name = "bimap" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0455254eb5c6964c4545d8bac815e1a1be4f3afe0ae695ea539c12d728d44b" +checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -611,7 +622,7 @@ version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -673,7 +684,7 @@ dependencies = [ "bech32 0.9.1", "bitcoin_hashes", "secp256k1 0.24.3", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -682,14 +693,14 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] name = "bitflags" -version = "1.3.2" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "bitvec" @@ -717,9 +728,9 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.4" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cf849ee05b2ee5fba5e36f97ff8ec2533916700fc0758d40d92136a42f3388" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ "digest 0.10.6", ] @@ -742,18 +753,18 @@ checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake2b_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.2.5", ] [[package]] @@ -764,31 +775,31 @@ checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake2s_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.2.5", ] [[package]] name = "blake3" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" dependencies = [ "arrayref", "arrayvec 0.7.2", "cc", "cfg-if 1.0.0", - "constant_time_eq", + "constant_time_eq 0.2.5", "digest 0.10.6", ] @@ -810,16 +821,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -849,16 +860,17 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" dependencies = [ "async-channel", + "async-lock", "async-task", "atomic-waker", "fastrand", "futures-lite", - "once_cell", + "log 0.4.17", ] [[package]] @@ -885,12 +897,12 @@ dependencies = [ [[package]] name = "borsh" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40f9ca3698b2e4cb7c15571db0abc5551dca417a21ae8140460b50309bb2cc62" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" dependencies = [ - "borsh-derive 0.10.2", - "hashbrown 0.12.3", + "borsh-derive 0.10.3", + "hashbrown 0.13.2", ] [[package]] @@ -902,20 +914,20 @@ dependencies = [ "borsh-schema-derive-internal 0.9.4", "proc-macro-crate 0.1.5", "proc-macro2", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "borsh-derive" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "598b3eacc6db9c3ee57b22707ad8f6a8d2f6d442bfe24ffeb8cbb70ca59e6a35" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" dependencies = [ - "borsh-derive-internal 0.10.2", - "borsh-schema-derive-internal 0.10.2", + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", "proc-macro2", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -925,18 +937,18 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "borsh-derive-internal" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186b734fa1c9f6743e90c95d7233c9faab6360d1a96d4ffa19d9cfd1e9350f8a" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -946,18 +958,18 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "borsh-schema-derive-internal" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b7ff1008316626f485991b960ade129253d4034014616b94f309a15366cc49" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -979,9 +991,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "byte-slice-cast" @@ -997,32 +1009,34 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "byte-unit" -version = "4.0.14" +version = "4.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95ebf10dda65f19ff0f42ea15572a359ed60d7fc74fdc984d90310937be0014b" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" dependencies = [ + "serde 1.0.163", "utf8-width", ] [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1066,17 +1080,17 @@ dependencies = [ [[package]] name = "cache-padded" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" +checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "camino" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -1085,7 +1099,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -1096,16 +1110,16 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.14", - "serde 1.0.145", + "semver 1.0.17", + "serde 1.0.163", "serde_json", ] [[package]] name = "cc" -version = "1.0.73" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] @@ -1116,7 +1130,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom 7.1.1", + "nom 7.1.3", ] [[package]] @@ -1158,9 +1172,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.22" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "num-integer", @@ -1170,9 +1184,9 @@ dependencies = [ [[package]] name = "chunked_transfer" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e" +checksum = "cca491388666e04d7248af3f60f0c40cfb0991c72205595d7c396e3510207d1a" [[package]] name = "cipher" @@ -1180,7 +1194,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -1194,9 +1208,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.4.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" dependencies = [ "glob", "libc", @@ -1234,16 +1248,6 @@ name = "clru" version = "0.5.0" source = "git+https://github.com/marmeladema/clru-rs.git?rev=71ca566#71ca566915f21f3c308091ca7756a91b0f8b5afc" -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", -] - [[package]] name = "color-eyre" version = "0.5.11" @@ -1267,18 +1271,18 @@ checksum = "b6eee477a4a8a72f4addd4de416eb56d54bc307b284d6601bafdee1f4ea462d1" dependencies = [ "once_cell", "owo-colors", - "tracing-core 0.1.30", + "tracing-core 0.1.31", "tracing-error", ] [[package]] name = "concat-idents" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6f90860248d75014b7b103db8fee4f291c07bfb41306cdf77a0a5ab7a10d2f" +checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832" dependencies = [ "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1290,6 +1294,15 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils 0.8.15", +] + [[package]] name = "config" version = "0.11.0" @@ -1297,9 +1310,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369" dependencies = [ "lazy_static", - "nom 5.1.2", + "nom 5.1.3", "rust-ini", - "serde 1.0.145", + "serde 1.0.163", "serde-hjson", "serde_json", "toml", @@ -1312,7 +1325,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "977baae4026273d7f9bb69a0a8eb4aed7ab9dac98799f742dce09173a9734754" dependencies = [ - "windows", + "windows 0.29.0", ] [[package]] @@ -1327,6 +1340,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + [[package]] name = "contracts" version = "0.6.3" @@ -1335,7 +1354,7 @@ checksum = "f1d1429e3bd78171c65aa010eabcdf8f863ba3254728dbfb0ad4b1545beac15c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1350,15 +1369,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -1444,35 +1463,35 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", ] [[package]] name = "crossbeam-epoch" -version = "0.9.11" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg 1.1.0", "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", - "memoffset", + "crossbeam-utils 0.8.15", + "memoffset 0.8.0", "scopeguard", ] @@ -1489,9 +1508,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if 1.0.0", ] @@ -1514,7 +1533,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "rand_core 0.6.4", "subtle", "zeroize", @@ -1526,7 +1545,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "typenum", ] @@ -1536,7 +1555,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -1546,7 +1565,7 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -1587,7 +1606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1622,55 +1641,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "cxx" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f83d0ebf42c6eafb8d7c52f7e5f2d3003b89c7aa4fd2b79229209459a849af8" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07d050484b55975889284352b0ffc2ecbda25c0c55978017c132b29ba0818a86" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn 1.0.102", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d2199b00553eda8012dfec8d3b1c75fce747cf27c169a270b3b99e3448ab78" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb67a6de1f602736dd7eaead0080cf3435df806c61b24b13328db128c58868f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.102", -] - [[package]] name = "darling" -version = "0.14.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4529658bdda7fd6769b8614be250cdcfc3aeb0ee72fe66f9e41e5e5eb73eac02" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ "darling_core", "darling_macro", @@ -1678,33 +1653,33 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "649c91bc01e8b1eac09fb91e8dbc7d517684ca6be8ebc75bb9cafc894f9fdb6f" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "darling_macro" -version = "0.14.1" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc69c5bfcbd2fc09a0f38451d2daf0e372e367986a83906d1b0dbc88134fb5" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "der" @@ -1729,7 +1704,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1740,7 +1715,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1770,7 +1745,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", ] [[package]] @@ -1779,7 +1754,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", "subtle", ] @@ -1827,13 +1802,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] @@ -1850,9 +1825,9 @@ checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" [[package]] name = "dyn-clone" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" +checksum = "68b0cf012f1230e43cd00ebb729c6bb58707ecfa8ad08b52ef3a4ccd2697fc30" [[package]] name = "dynasm" @@ -1866,7 +1841,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -1898,7 +1873,7 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", "signature", ] @@ -1911,7 +1886,7 @@ dependencies = [ "curve25519-dalek-ng", "hex", "rand_core 0.6.4", - "serde 1.0.145", + "serde 1.0.163", "sha2 0.9.9", "thiserror", "zeroize", @@ -1927,7 +1902,7 @@ dependencies = [ "ed25519", "merlin", "rand 0.7.3", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "sha2 0.9.9", "zeroize", @@ -1947,9 +1922,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -1961,7 +1936,7 @@ dependencies = [ "crypto-bigint", "der", "ff", - "generic-array 0.14.6", + "generic-array 0.14.7", "group", "rand_core 0.6.4", "sec1", @@ -1971,9 +1946,9 @@ dependencies = [ [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if 1.0.0", ] @@ -1995,46 +1970,67 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "equihash" version = "0.1.0" -source = "git+https://github.com/zcash/librustzcash?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" +source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "byteorder", ] [[package]] name = "erased-serde" -version = "0.3.24" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +dependencies = [ + "serde 1.0.163", +] + +[[package]] +name = "errno" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ca605381c017ec7a5fef5e548f1cfaa419ed0f6df6367339300db74c92aa7d" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ - "serde 1.0.145", + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", ] [[package]] @@ -2054,7 +2050,7 @@ checksum = "f5584ba17d7ab26a8a7284f13e5bd196294dd2f2d79773cff29b9e9edef601a6" dependencies = [ "log 0.4.17", "once_cell", - "serde 1.0.145", + "serde 1.0.163", "serde_json", ] @@ -2071,7 +2067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2795e11f4ee3124984d454f25ac899515a5fa6d956562ef2b147fef6050b02f8" dependencies = [ "conpty", - "nix 0.23.1", + "nix 0.23.2", "ptyprocess", "regex", ] @@ -2100,9 +2096,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -2122,7 +2118,7 @@ dependencies = [ "ark-std", "bincode", "blake2", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "borsh 0.9.4", "digest 0.10.6", "ed25519-dalek", @@ -2136,7 +2132,7 @@ dependencies = [ "num", "rand 0.7.3", "rand 0.8.5", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "serde_json", "subproductdomain", @@ -2153,7 +2149,7 @@ dependencies = [ "ark-ec", "ark-serialize", "ark-std", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", ] @@ -2170,21 +2166,19 @@ dependencies = [ [[package]] name = "file-lock" -version = "2.1.6" +version = "2.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0815fc2a1924e651b71ae6d13df07b356a671a09ecaf857dbd344a2ba937a496" +checksum = "f59be9010c5418713a48aac4c1b897d85dafd958055683dc31bdae553536647b" dependencies = [ "cc", "libc", - "mktemp", - "nix 0.24.2", ] [[package]] name = "file-serve" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e43addbb09a5dcb5609cb44a01a79e67716fe40b50c109f50112ef201a8c7c59" +checksum = "547ebf393d987692a02b5d2be1c0b398b16a5b185c23a047c1d3fc3050d6d803" dependencies = [ "log 0.4.17", "mime_guess", @@ -2193,14 +2187,14 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall 0.2.16", - "windows-sys 0.36.1", + "windows-sys 0.48.0", ] [[package]] @@ -2223,12 +2217,12 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.7.1", ] [[package]] @@ -2287,9 +2281,9 @@ dependencies = [ [[package]] name = "fs_extra" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "fuchsia-cprng" @@ -2332,9 +2326,9 @@ checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" [[package]] name = "futures" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -2347,9 +2341,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -2357,15 +2351,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -2374,15 +2368,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ "fastrand", "futures-core", @@ -2395,32 +2389,32 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -2445,9 +2439,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check 0.9.4", @@ -2466,9 +2460,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.7" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "libc", @@ -2488,9 +2482,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.26.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "git2" @@ -2509,15 +2503,15 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gloo-timers" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ "futures-channel", "futures-core", @@ -2549,7 +2543,7 @@ dependencies = [ "ark-poly", "ark-serialize", "ark-std", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "chacha20", "hex", "itertools", @@ -2578,14 +2572,14 @@ checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "h2" -version = "0.3.14" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca32592cf21ac7ccab1825cd87f6c9b3d9022c44d086172ed0966bec8af30be" +checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ "bytes 1.4.0", "fnv", @@ -2596,7 +2590,7 @@ dependencies = [ "indexmap", "slab", "tokio", - "tokio-util 0.7.4", + "tokio-util 0.7.8", "tracing 0.1.37", ] @@ -2626,7 +2620,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" dependencies = [ - "ahash", + "ahash 0.7.6", ] [[package]] @@ -2635,14 +2629,23 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", ] [[package]] name = "hdpath" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dafb09e5d85df264339ad786a147d9de1da13687a3697c52244297e5e7c32d9c" +checksum = "09ae1615f843ce3981b47468f3f7c435ac17deb33c2261e64d7f1e87f5c11acc" dependencies = [ "byteorder", ] @@ -2663,13 +2666,13 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "bitflags", "bytes 1.4.0", "headers-core", "http", "httpdate", - "mime 0.3.16", + "mime 0.3.17", "sha1", ] @@ -2697,6 +2700,21 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -2739,15 +2757,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" dependencies = [ "digest 0.9.0", - "generic-array 0.14.6", + "generic-array 0.14.7", "hmac 0.8.1", ] [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes 1.4.0", "fnv", @@ -2765,12 +2783,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - [[package]] name = "httparse" version = "1.8.0" @@ -2796,7 +2808,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" dependencies = [ "humantime", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -2811,7 +2823,7 @@ dependencies = [ "log 0.3.9", "mime 0.2.6", "num_cpus", - "time 0.1.44", + "time 0.1.43", "traitobject", "typeable", "unicase 1.4.2", @@ -2820,9 +2832,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.20" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes 1.4.0", "futures-channel", @@ -2849,10 +2861,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" dependencies = [ "bytes 1.4.0", - "futures 0.3.26", + "futures 0.3.28", "headers", "http", - "hyper 0.14.20", + "hyper 0.14.26", "hyper-rustls", "rustls-native-certs 0.5.0", "tokio", @@ -2869,7 +2881,7 @@ checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" dependencies = [ "ct-logs", "futures-util", - "hyper 0.14.20", + "hyper 0.14.26", "log 0.4.17", "rustls 0.19.1", "rustls-native-certs 0.5.0", @@ -2885,7 +2897,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.20", + "hyper 0.14.26", "pin-project-lite", "tokio", "tokio-io-timeout", @@ -2898,7 +2910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes 1.4.0", - "hyper 0.14.20", + "hyper 0.14.26", "native-tls", "tokio", "tokio-native-tls", @@ -2906,32 +2918,31 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.51" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5a6ef98976b22b3b7f2f3a806f858cb862044cfa66805aa3ad84cb3d3b785ed" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi 0.3.9", + "windows 0.48.0", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "ibc" version = "0.36.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6#db14744bfba6239cc5f58345ff90f8b7d42637d6" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9#2d7edc16412b60cabf78163fe24a6264e11f77a9" dependencies = [ "bytes 1.4.0", "cfg-if 1.0.0", @@ -2939,23 +2950,23 @@ dependencies = [ "displaydoc", "dyn-clone", "erased-serde", - "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)", + "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)", "ics23", "num-traits 0.2.15", "parking_lot 0.12.1", "primitive-types", "prost", "safe-regex", - "serde 1.0.145", + "serde 1.0.163", "serde_derive", "serde_json", "sha2 0.10.6", "subtle-encoding", - "tendermint 0.23.5", - "tendermint-light-client-verifier 0.23.5", - "tendermint-proto 0.23.5", - "tendermint-testgen 0.23.5", - "time 0.3.15", + "tendermint 0.23.6", + "tendermint-light-client-verifier 0.23.6", + "tendermint-proto 0.23.6", + "tendermint-testgen 0.23.6", + "time 0.3.17", "tracing 0.1.37", "uint", ] @@ -2963,7 +2974,7 @@ dependencies = [ [[package]] name = "ibc" version = "0.36.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=dcce4ac23d4d0a4324d23c54a1a99d41f0be2076#dcce4ac23d4d0a4324d23c54a1a99d41f0be2076" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6#db14744bfba6239cc5f58345ff90f8b7d42637d6" dependencies = [ "bytes 1.4.0", "cfg-if 1.0.0", @@ -2971,23 +2982,23 @@ dependencies = [ "displaydoc", "dyn-clone", "erased-serde", - "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb)", + "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)", "ics23", "num-traits 0.2.15", "parking_lot 0.12.1", "primitive-types", "prost", "safe-regex", - "serde 1.0.145", + "serde 1.0.163", "serde_derive", "serde_json", "sha2 0.10.6", "subtle-encoding", - "tendermint 0.23.6", - "tendermint-light-client-verifier 0.23.6", - "tendermint-proto 0.23.6", - "tendermint-testgen 0.23.6", - "time 0.3.15", + "tendermint 0.23.5", + "tendermint-light-client-verifier 0.23.5", + "tendermint-proto 0.23.5", + "tendermint-testgen 0.23.5", + "time 0.3.17", "tracing 0.1.37", "uint", ] @@ -2995,13 +3006,13 @@ dependencies = [ [[package]] name = "ibc-proto" version = "0.26.0" -source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb#acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb" +source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f#7e527b5b8c95d83351e93ceafc14ac853224283f" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "bytes 1.4.0", "flex-error", "prost", - "serde 1.0.145", + "serde 1.0.163", "subtle-encoding", "tendermint-proto 0.23.6", "tonic", @@ -3012,14 +3023,14 @@ name = "ibc-proto" version = "0.26.0" source = "git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a#dd8ba23110a144ffe2074a0b889676468266435a" dependencies = [ - "base64 0.13.0", - "borsh 0.10.2", + "base64 0.13.1", + "borsh 0.10.3", "bytes 1.4.0", "flex-error", "parity-scale-codec", "prost", "scale-info", - "serde 1.0.145", + "serde 1.0.163", "subtle-encoding", "tendermint-proto 0.23.5", ] @@ -3027,7 +3038,7 @@ dependencies = [ [[package]] name = "ibc-relayer" version = "0.22.0" -source = "git+https://github.com/heliaxdev/hermes.git?rev=b475b1cc9c94eac91d44da22aee2038f0512d702#b475b1cc9c94eac91d44da22aee2038f0512d702" +source = "git+https://github.com/heliaxdev/hermes.git?rev=8e2ff3479edc0653f34b22df450d451eedd2c2ab#8e2ff3479edc0653f34b22df450d451eedd2c2ab" dependencies = [ "anyhow", "async-stream", @@ -3035,21 +3046,21 @@ dependencies = [ "bitcoin", "bs58", "bytes 1.4.0", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "digest 0.10.6", "dirs-next", "ed25519", "ed25519-dalek", "ed25519-dalek-bip32", "flex-error", - "futures 0.3.26", - "generic-array 0.14.6", + "futures 0.3.28", + "generic-array 0.14.7", "hdpath", "hex", "http", "humantime", "humantime-serde", - "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb)", + "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)", "ibc-relayer-types", "itertools", "moka", @@ -3060,8 +3071,8 @@ dependencies = [ "retry", "ripemd", "secp256k1 0.24.3", - "semver 1.0.14", - "serde 1.0.145", + "semver 1.0.17", + "serde 1.0.163", "serde_derive", "serde_json", "sha2 0.10.6", @@ -3080,27 +3091,27 @@ dependencies = [ "toml", "tonic", "tracing 0.1.37", - "uuid 1.2.2", + "uuid 1.3.2", ] [[package]] name = "ibc-relayer-types" version = "0.22.0" -source = "git+https://github.com/heliaxdev/hermes.git?rev=b475b1cc9c94eac91d44da22aee2038f0512d702#b475b1cc9c94eac91d44da22aee2038f0512d702" +source = "git+https://github.com/heliaxdev/hermes.git?rev=8e2ff3479edc0653f34b22df450d451eedd2c2ab#8e2ff3479edc0653f34b22df450d451eedd2c2ab" dependencies = [ "bytes 1.4.0", "derive_more", "dyn-clone", "erased-serde", "flex-error", - "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb)", + "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)", "ics23", "itertools", "num-rational", "primitive-types", "prost", "safe-regex", - "serde 1.0.145", + "serde 1.0.163", "serde_derive", "serde_json", "subtle-encoding", @@ -3109,7 +3120,7 @@ dependencies = [ "tendermint-proto 0.23.6", "tendermint-rpc 0.23.6", "tendermint-testgen 0.23.6", - "time 0.3.15", + "time 0.3.17", "uint", ] @@ -3170,7 +3181,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -3181,7 +3192,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -3190,7 +3201,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "186fd3ab92aeac865d4b80b410de9a7b341d31ba8281373caed0b6d17b2b5e96" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -3205,18 +3216,18 @@ version = "0.7.1" source = "git+https://github.com/heliaxdev/index-set?tag=v0.7.1#dc24cdbbe3664514d59f1a4c4031863fc565f1c2" dependencies = [ "borsh 0.9.4", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg 1.1.0", "hashbrown 0.12.3", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -3240,6 +3251,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "iovec" version = "0.1.4" @@ -3251,9 +3273,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.5.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" +checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" [[package]] name = "itertools" @@ -3266,24 +3288,24 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -3317,9 +3339,12 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] [[package]] name = "kernel32-sys" @@ -3379,9 +3404,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.135" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libgit2-sys" @@ -3399,9 +3424,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" dependencies = [ "cfg-if 1.0.0", "winapi 0.3.9", @@ -3435,14 +3460,14 @@ version = "0.7.0" source = "git+https://github.com/heliaxdev/libsecp256k1?rev=bbb3bd44a49db361f21d9db80f9a087c194c0ae9#bbb3bd44a49db361f21d9db80f9a087c194c0ae9" dependencies = [ "arrayref", - "base64 0.13.0", + "base64 0.13.1", "digest 0.9.0", "hmac-drbg", "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", "rand 0.8.5", - "serde 1.0.145", + "serde 1.0.163", "sha2 0.9.9", "typenum", ] @@ -3489,9 +3514,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" dependencies = [ "cc", "libc", @@ -3499,24 +3524,21 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "link-cplusplus" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] - [[package]] name = "linked-hash-map" version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] +[[package]] +name = "linux-raw-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" + [[package]] name = "lock_api" version = "0.3.4" @@ -3573,7 +3595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" dependencies = [ "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -3594,7 +3616,7 @@ dependencies = [ "indexmap", "linked-hash-map", "regex", - "serde 1.0.145", + "serde 1.0.163", "serde_derive", "serde_yaml", ] @@ -3607,8 +3629,8 @@ dependencies = [ "aes", "bip0039", "bitvec 0.22.3", - "blake2b_simd 1.0.0", - "blake2s_simd 1.0.0", + "blake2b_simd 1.0.1", + "blake2s_simd 1.0.1", "bls12_381", "borsh 0.9.4", "byteorder", @@ -3625,7 +3647,7 @@ dependencies = [ "rand_core 0.6.4", "ripemd160", "secp256k1 0.20.3", - "serde 1.0.145", + "serde 1.0.163", "sha2 0.9.9", "subtle", "zcash_encoding", @@ -3638,7 +3660,7 @@ version = "0.5.0" source = "git+https://github.com/anoma/masp?rev=bee40fc465f6afbd10558d12fe96eb1742eee45c#bee40fc465f6afbd10558d12fe96eb1742eee45c" dependencies = [ "bellman", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "bls12_381", "byteorder", "directories", @@ -3666,9 +3688,9 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "matchit" @@ -3700,9 +3722,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.7" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] @@ -3716,6 +3738,15 @@ dependencies = [ "autocfg 1.1.0", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg 1.1.0", +] + [[package]] name = "memuse" version = "0.2.1" @@ -3748,9 +3779,9 @@ dependencies = [ [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" @@ -3758,7 +3789,7 @@ version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" dependencies = [ - "mime 0.3.16", + "mime 0.3.17", "unicase 2.6.0", ] @@ -3770,22 +3801,31 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.5.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] [[package]] name = "minreq" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c785bc6027fd359756e538541c8624012ba3776d3d3fe123885643092ed4132" +checksum = "cb6c6973f78ef55d0e5fc04fdb8f9ad67c87c9e86bca0ff77b6a3102b0eb36b7" dependencies = [ - "lazy_static", "log 0.4.17", - "rustls 0.20.7", + "once_cell", + "rustls 0.20.8", "webpki 0.22.0", "webpki-roots 0.22.6", ] @@ -3811,14 +3851,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log 0.4.17", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.36.1", + "windows-sys 0.45.0", ] [[package]] @@ -3839,24 +3879,15 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94c7128ba23c81f6471141b90f17654f89ef44a56e14b8a4dd0fddfccd655277" -[[package]] -name = "mktemp" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "975de676448231fcde04b9149d2543077e166b78fc29eae5aa219e7928410da2" -dependencies = [ - "uuid 0.8.2", -] - [[package]] name = "moka" version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b9268097a2cf211ac9955b1cc95e80fa84fff5c2d13ba292916445dc8a311f" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "num_cpus", "once_cell", "parking_lot 0.12.1", @@ -3868,7 +3899,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.2.2", + "uuid 1.3.2", ] [[package]] @@ -3888,8 +3919,10 @@ name = "namada" version = "0.15.3" dependencies = [ "assert_matches", + "async-std", "async-trait", "bellman", + "bimap", "bls12_381", "borsh 0.9.4", "byte-unit", @@ -3897,9 +3930,9 @@ dependencies = [ "clru", "data-encoding", "derivative", + "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9)", "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6)", - "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=dcce4ac23d4d0a4324d23c54a1a99d41f0be2076)", - "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb)", + "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)", "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)", "itertools", "libsecp256k1", @@ -3909,29 +3942,31 @@ dependencies = [ "namada_core", "namada_proof_of_stake", "namada_test_utils", + "orion", "parity-wasm", "paste", "pretty_assertions", "proptest", "prost", "pwasm-utils", + "rand 0.8.5", + "rand_core 0.6.4", "rayon", "rust_decimal", "rust_decimal_macros", + "serde 1.0.163", "serde_json", "sha2 0.9.9", "tempfile", - "tendermint 0.23.5", "tendermint 0.23.6", - "tendermint-proto 0.23.5", "tendermint-proto 0.23.6", - "tendermint-rpc 0.23.5", "tendermint-rpc 0.23.6", "test-log", "thiserror", "tokio", + "toml", "tracing 0.1.37", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", "wasmer", "wasmer-cache", "wasmer-compiler-singlepass", @@ -3951,7 +3986,7 @@ dependencies = [ "assert_matches", "async-std", "async-trait", - "base64 0.13.0", + "base64 0.13.1", "bech32 0.8.1", "bimap", "bit-set", @@ -3971,7 +4006,7 @@ dependencies = [ "ferveo-common", "file-lock", "flate2", - "futures 0.3.26", + "futures 0.3.28", "git2", "itertools", "libc", @@ -3999,7 +4034,7 @@ dependencies = [ "rpassword", "rust_decimal", "rust_decimal_macros", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "serde_json", "sha2 0.9.9", @@ -4008,13 +4043,9 @@ dependencies = [ "sysinfo", "tar", "tempfile", - "tendermint 0.23.5", "tendermint 0.23.6", - "tendermint-config 0.23.5", "tendermint-config 0.23.6", - "tendermint-proto 0.23.5", "tendermint-proto 0.23.6", - "tendermint-rpc 0.23.5", "tendermint-rpc 0.23.6", "test-log", "thiserror", @@ -4023,11 +4054,11 @@ dependencies = [ "toml", "tonic", "tower", - "tower-abci 0.1.0 (git+https://github.com/heliaxdev/tower-abci.git?rev=3fb3b5c9d187d7009bc25c25813ddaab38216e73)", + "tower-abci 0.1.0 (git+https://github.com/heliaxdev/tower-abci.git?rev=79069a441cee7d9955a3d826d29656a0fb16115c)", "tower-abci 0.1.0 (git+https://github.com/heliaxdev/tower-abci?rev=a31ce06533f5fbd943508676059d44de27395792)", "tracing 0.1.37", "tracing-log", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", "websocket", "winapi 0.3.9", ] @@ -4050,9 +4081,9 @@ dependencies = [ "ferveo", "ferveo-common", "group-threshold-cryptography", + "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9)", "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=db14744bfba6239cc5f58345ff90f8b7d42637d6)", - "ibc 0.36.0 (git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=dcce4ac23d4d0a4324d23c54a1a99d41f0be2076)", - "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb)", + "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f)", "ibc-proto 0.26.0 (git+https://github.com/heliaxdev/ibc-proto-rs?rev=dd8ba23110a144ffe2074a0b889676468266435a)", "ics23", "index-set", @@ -4069,19 +4100,17 @@ dependencies = [ "rayon", "rust_decimal", "rust_decimal_macros", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "sha2 0.9.9", "sparse-merkle-tree", - "tendermint 0.23.5", "tendermint 0.23.6", - "tendermint-proto 0.23.5", "tendermint-proto 0.23.6", "test-log", "thiserror", "tonic-build", "tracing 0.1.37", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", "zeroize", ] @@ -4102,7 +4131,7 @@ version = "0.15.3" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -4122,7 +4151,7 @@ dependencies = [ "test-log", "thiserror", "tracing 0.1.37", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", ] [[package]] @@ -4177,7 +4206,7 @@ dependencies = [ "tokio", "toml", "tracing 0.1.37", - "tracing-subscriber 0.3.16", + "tracing-subscriber 0.3.17", ] [[package]] @@ -4221,9 +4250,9 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" dependencies = [ "lazy_static", "libc", @@ -4243,53 +4272,42 @@ version = "0.2.38" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", -] - -[[package]] -name = "nix" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", + "cfg-if 0.1.10", "libc", - "memoffset", + "winapi 0.3.9", ] [[package]] name = "nix" -version = "0.23.1" +version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +checksum = "77d9f3521ea8e0641a153b3cddaf008dcbf26acd4ed739a2517295e0760d12c7" dependencies = [ "bitflags", "cc", "cfg-if 1.0.0", "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] name = "nix" -version = "0.24.2" +version = "0.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" dependencies = [ "bitflags", + "cc", "cfg-if 1.0.0", "libc", + "memoffset 0.6.5", ] [[package]] name = "nom" -version = "5.1.2" +version = "5.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "08959a387a676302eebf4ddbcbc611da04285579f76f88ee0506c63b1a61dd4b" dependencies = [ "lexical-core", "memchr", @@ -4298,23 +4316,14 @@ dependencies = [ [[package]] name = "nom" -version = "7.1.1" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ "memchr", "minimal-lexical", ] -[[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - [[package]] name = "nonempty" version = "0.7.0" @@ -4363,14 +4372,14 @@ dependencies = [ "autocfg 1.1.0", "num-integer", "num-traits 0.2.15", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] name = "num-complex" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ae39348c8bc5fbd7f40c727a9925f03517afd2ab27d46702108b6a7e5414c19" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" dependencies = [ "num-traits 0.2.15", ] @@ -4383,7 +4392,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -4417,7 +4426,7 @@ dependencies = [ "num-bigint", "num-integer", "num-traits 0.2.15", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -4441,20 +4450,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_threads" -version = "0.1.6" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ + "hermit-abi 0.2.6", "libc", ] @@ -4472,18 +4472,18 @@ dependencies = [ [[package]] name = "object" -version = "0.29.0" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.15.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -4499,9 +4499,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.42" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12fc0523e3bd51a692c8850d075d74dc062ccf251c0110668cbd921917118a13" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -4514,13 +4514,13 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] @@ -4531,11 +4531,10 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.76" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5230151e44c0f05157effb743e8d517472843121cf9243e8b81393edb5acd9ce" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ - "autocfg 1.1.0", "cc", "libc", "pkg-config", @@ -4552,7 +4551,7 @@ dependencies = [ "arrayvec 0.7.2", "bigint", "bitvec 0.22.3", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "ff", "fpe", "group", @@ -4564,7 +4563,7 @@ dependencies = [ "pasta_curves", "rand 0.8.5", "reddsa", - "serde 1.0.145", + "serde 1.0.163", "subtle", "zcash_note_encryption 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -4576,7 +4575,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c" dependencies = [ "ct-codecs", - "getrandom 0.2.7", + "getrandom 0.2.9", "subtle", "zeroize", ] @@ -4619,16 +4618,16 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" +checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", "byte-slice-cast", "impl-trait-for-tuples", "parity-scale-codec-derive", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -4637,10 +4636,10 @@ version = "3.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "86b26a931f824dd4eca30b3e43bb4f31cd5f0d3a403c5f5ff27106b805bfde7b" dependencies = [ - "proc-macro-crate 1.3.0", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -4651,9 +4650,9 @@ checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" [[package]] name = "parking" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "parking_lot" @@ -4662,7 +4661,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" dependencies = [ "lock_api 0.3.4", - "parking_lot_core 0.6.2", + "parking_lot_core 0.6.3", "rustc_version 0.2.3", ] @@ -4673,14 +4672,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api 0.4.9", - "parking_lot_core 0.9.4", + "parking_lot_core 0.9.7", ] [[package]] name = "parking_lot_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b876b1b9e7ac6e1a74a6da34d25c42e17e8862aa409cbbbdcfc8d86c6f3bc62b" +checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" dependencies = [ "cfg-if 0.1.10", "cloudabi", @@ -4693,15 +4692,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall 0.2.16", "smallvec 1.10.0", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -4732,9 +4731,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" @@ -4802,18 +4801,19 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.1.3" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" dependencies = [ + "thiserror", "ucd-trie", ] [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", "indexmap", @@ -4821,22 +4821,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.12" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] @@ -4853,9 +4853,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.25" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "polling" @@ -4884,15 +4884,15 @@ dependencies = [ [[package]] name = "ppv-lite86" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "predicates" -version = "2.1.1" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" +checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" dependencies = [ "difflib", "itertools", @@ -4901,15 +4901,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.3" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" [[package]] name = "predicates-tree" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" dependencies = [ "predicates-core", "termtree", @@ -4934,7 +4934,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -4970,9 +4970,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", "toml_edit", @@ -4987,7 +4987,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", "version_check 0.9.4", ] @@ -5024,7 +5024,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift 0.3.0", - "regex-syntax", + "regex-syntax 0.6.29", "rusty-fork", "tempfile", "unarray", @@ -5032,9 +5032,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21dc42e00223fc37204bd4aa177e69420c604ca4a183209a8f9de30c6d934698" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes 1.4.0", "prost-derive", @@ -5042,9 +5042,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f8ad728fb08fe212df3c05169e940fbb6d9d16a877ddde14644a983ba2012e" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes 1.4.0", "heck", @@ -5057,31 +5057,30 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 1.0.102", + "syn 1.0.109", "tempfile", "which", ] [[package]] name = "prost-derive" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda8c0881ea9f722eb9629376db3d0b903b462477c1aafcb0566610ac28ac5d" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "prost-types" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e0526209433e96d83d750dd81a99118edbc55739e7e61a46764fd2ad537788" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "bytes 1.4.0", "prost", ] @@ -5102,7 +5101,7 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -5111,7 +5110,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69c28fcebfd842bfe19d69409fc321230ea8c1bebe31f274906485c761ce1917" dependencies = [ - "nix 0.21.0", + "nix 0.21.2", ] [[package]] @@ -5141,12 +5140,12 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e31331286705f455e56cca62e0e717158474ff02b7936c1fa596d983f4ae27" dependencies = [ - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "libc", "mach", "once_cell", "raw-cpuid", - "wasi 0.10.0+wasi-snapshot-preview1", + "wasi 0.10.2+wasi-snapshot-preview1", "web-sys", "winapi 0.3.9", ] @@ -5281,7 +5280,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.9", ] [[package]] @@ -5366,9 +5365,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "10.6.0" +version = "10.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6823ea29436221176fe662da99998ad3b4db2c7f31e7b6f5fe43adccd6320bb" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" dependencies = [ "bitflags", ] @@ -5387,13 +5386,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-deque", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "num_cpus", ] @@ -5419,7 +5418,7 @@ dependencies = [ "jubjub", "pasta_curves", "rand_core 0.6.4", - "serde 1.0.145", + "serde 1.0.163", "thiserror", "zeroize", ] @@ -5439,13 +5438,22 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.9", "redox_syscall 0.2.16", "thiserror", ] @@ -5463,13 +5471,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -5478,14 +5486,20 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] name = "regex-syntax" -version = "0.6.27" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "region" @@ -5499,31 +5513,22 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.12" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "431949c384f4e2ae07605ccaa56d1d9d2ecdb5cadd4f9577ccfab29f2e5149fc" +checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ - "base64 0.13.0", + "base64 0.21.0", "bytes 1.4.0", "encoding_rs", "futures-core", @@ -5531,17 +5536,17 @@ dependencies = [ "h2", "http", "http-body", - "hyper 0.14.20", + "hyper 0.14.26", "hyper-tls", "ipnet", "js-sys", "log 0.4.17", - "mime 0.3.16", + "mime 0.3.17", "native-tls", "once_cell", "percent-encoding 2.2.0", "pin-project-lite", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "serde_urlencoded", "tokio", @@ -5608,27 +5613,30 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec 1.0.1", "bytecheck", "hashbrown 0.12.3", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid 1.3.2", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -5675,7 +5683,7 @@ dependencies = [ "arrayvec 0.7.2", "borsh 0.9.4", "num-traits 0.2.15", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -5690,9 +5698,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -5730,7 +5738,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver 1.0.17", +] + +[[package]] +name = "rustix" +version = "0.37.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79bef90eb6d984c72722595b5b1348ab39275a5e5123faca6863bf07d75a4e0" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", ] [[package]] @@ -5739,7 +5761,7 @@ version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "log 0.4.17", "ring", "sct 0.6.1", @@ -5748,9 +5770,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.7" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c" +checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log 0.4.17", "ring", @@ -5793,9 +5815,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rusty-fork" @@ -5811,9 +5833,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "safe-proc-macro2" @@ -5879,9 +5901,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.3.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "001cf62ece89779fd16105b5f515ad0e5cedcd5440d3dd806bb067978e7c3608" +checksum = "dfdef77228a4c05dc94211441595746732131ad7f6530c6c18f045da7b7ab937" dependencies = [ "cfg-if 1.0.0", "derive_more", @@ -5891,31 +5913,30 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.3.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "303959cf613a6f6efd19ed4b4ad5bf79966a13352716299ad532cfb115f4205c" +checksum = "53012eae69e5aa5c14671942a5dd47de59d4cdcff8532a6dd0e081faf1119482" dependencies = [ - "proc-macro-crate 1.3.0", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "scheduled-thread-pool" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ "parking_lot 0.12.1", ] @@ -5926,12 +5947,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - [[package]] name = "sct" version = "0.6.1" @@ -5965,7 +5980,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" dependencies = [ "der", - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", "zeroize", ] @@ -5988,7 +6003,7 @@ dependencies = [ "bitcoin_hashes", "rand 0.8.5", "secp256k1-sys 0.6.1", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -6024,9 +6039,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -6052,11 +6067,11 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -6082,9 +6097,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" [[package]] name = "serde" -version = "1.0.145" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] @@ -6103,11 +6118,11 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.7" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -6117,40 +6132,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" dependencies = [ "half", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] name = "serde_derive" -version = "1.0.145" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] name = "serde_repr" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] @@ -6162,7 +6177,7 @@ dependencies = [ "form_urlencoded", "itoa", "ryu", - "serde 1.0.145", + "serde 1.0.163", ] [[package]] @@ -6173,7 +6188,7 @@ checksum = "ef8099d3df28273c99a1728190c7a9f19d444c941044f64adf986bee7ec53051" dependencies = [ "dtoa", "linked-hash-map", - "serde 1.0.145", + "serde 1.0.163", "yaml-rust", ] @@ -6239,9 +6254,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.6", "keccak", @@ -6264,9 +6279,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -6274,9 +6289,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -6291,6 +6306,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "simple-error" version = "0.2.3" @@ -6314,9 +6335,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg 1.1.0", ] @@ -6338,9 +6359,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi 0.3.9", @@ -6401,7 +6422,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -6440,9 +6461,9 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "syn" -version = "1.0.102" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -6466,18 +6487,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.102", - "unicode-xid", -] - [[package]] name = "sysinfo" version = "0.21.1" @@ -6517,22 +6526,21 @@ dependencies = [ [[package]] name = "target-lexicon" -version = "0.12.4" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c02424087780c9b71cc96799eaeddff35af2bc513278cda5c99fc1f5d026d3c1" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if 1.0.0", "fastrand", - "libc", - "redox_syscall 0.2.16", - "remove_dir_all", - "winapi 0.3.9", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] @@ -6545,12 +6553,12 @@ dependencies = [ "ed25519", "ed25519-dalek", "flex-error", - "futures 0.3.26", + "futures 0.3.28", "num-traits 0.2.15", "once_cell", "prost", "prost-types", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "serde_json", "serde_repr", @@ -6559,28 +6567,28 @@ dependencies = [ "subtle", "subtle-encoding", "tendermint-proto 0.23.5", - "time 0.3.15", + "time 0.3.17", "zeroize", ] [[package]] name = "tendermint" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "async-trait", "bytes 1.4.0", "ed25519", "ed25519-dalek", "flex-error", - "futures 0.3.26", + "futures 0.3.28", "k256", "num-traits 0.2.15", "once_cell", "prost", "prost-types", "ripemd160", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "serde_json", "serde_repr", @@ -6589,7 +6597,7 @@ dependencies = [ "subtle", "subtle-encoding", "tendermint-proto 0.23.6", - "time 0.3.15", + "time 0.3.17", "zeroize", ] @@ -6599,7 +6607,7 @@ version = "0.23.5" source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916" dependencies = [ "flex-error", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "tendermint 0.23.5", "toml", @@ -6609,10 +6617,10 @@ dependencies = [ [[package]] name = "tendermint-config" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "flex-error", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "tendermint 0.23.6", "toml", @@ -6622,21 +6630,21 @@ dependencies = [ [[package]] name = "tendermint-light-client" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "contracts", "crossbeam-channel 0.4.4", "derive_more", "flex-error", - "futures 0.3.26", - "serde 1.0.145", + "futures 0.3.28", + "serde 1.0.163", "serde_cbor", "serde_derive", "static_assertions", "tendermint 0.23.6", "tendermint-light-client-verifier 0.23.6", "tendermint-rpc 0.23.6", - "time 0.3.15", + "time 0.3.17", "tokio", ] @@ -6647,22 +6655,22 @@ source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bb dependencies = [ "derive_more", "flex-error", - "serde 1.0.145", + "serde 1.0.163", "tendermint 0.23.5", "tendermint-rpc 0.23.5", - "time 0.3.15", + "time 0.3.17", ] [[package]] name = "tendermint-light-client-verifier" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "derive_more", "flex-error", - "serde 1.0.145", + "serde 1.0.163", "tendermint 0.23.6", - "time 0.3.15", + "time 0.3.17", ] [[package]] @@ -6676,16 +6684,16 @@ dependencies = [ "num-traits 0.2.15", "prost", "prost-types", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "subtle-encoding", - "time 0.3.15", + "time 0.3.17", ] [[package]] name = "tendermint-proto" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "bytes 1.4.0", "flex-error", @@ -6693,10 +6701,10 @@ dependencies = [ "num-traits 0.2.15", "prost", "prost-types", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "subtle-encoding", - "time 0.3.15", + "time 0.3.17", ] [[package]] @@ -6704,19 +6712,12 @@ name = "tendermint-rpc" version = "0.23.5" source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bbd5321239aec9cc3a8f916#a3a0ad5f07d380976bbd5321239aec9cc3a8f916" dependencies = [ - "async-trait", - "async-tungstenite", "bytes 1.4.0", "flex-error", - "futures 0.3.26", - "getrandom 0.2.7", - "http", - "hyper 0.14.20", - "hyper-proxy", - "hyper-rustls", + "getrandom 0.2.9", "peg", "pin-project", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "serde_json", "subtle-encoding", @@ -6724,9 +6725,7 @@ dependencies = [ "tendermint-config 0.23.5", "tendermint-proto 0.23.5", "thiserror", - "time 0.3.15", - "tokio", - "tracing 0.1.37", + "time 0.3.17", "url 2.3.1", "uuid 0.8.2", "walkdir", @@ -6735,21 +6734,21 @@ dependencies = [ [[package]] name = "tendermint-rpc" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "async-trait", "async-tungstenite", "bytes 1.4.0", "flex-error", - "futures 0.3.26", - "getrandom 0.2.7", + "futures 0.3.28", + "getrandom 0.2.9", "http", - "hyper 0.14.20", + "hyper 0.14.26", "hyper-proxy", "hyper-rustls", "peg", "pin-project", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "serde_json", "subtle-encoding", @@ -6757,7 +6756,7 @@ dependencies = [ "tendermint-config 0.23.6", "tendermint-proto 0.23.6", "thiserror", - "time 0.3.15", + "time 0.3.17", "tokio", "tracing 0.1.37", "url 2.3.1", @@ -6772,43 +6771,43 @@ source = "git+https://github.com/heliaxdev/tendermint-rs?rev=a3a0ad5f07d380976bb dependencies = [ "ed25519-dalek", "gumdrop", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "simple-error", "tempfile", "tendermint 0.23.5", - "time 0.3.15", + "time 0.3.17", ] [[package]] name = "tendermint-testgen" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "ed25519-dalek", "gumdrop", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "simple-error", "tempfile", "tendermint 0.23.6", - "time 0.3.15", + "time 0.3.17", ] [[package]] name = "termcolor" -version = "1.1.3" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" dependencies = [ "winapi-util", ] [[package]] name = "termtree" -version = "0.2.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "test-log" @@ -6818,7 +6817,7 @@ checksum = "38f0c854faeb68a048f0f2dc410c5ddae3bf83854ef0e4977d58306a5edef50e" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -6832,72 +6831,79 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if 1.0.0", "once_cell", ] [[package]] name = "tikv-jemalloc-sys" -version = "0.5.2+5.3.0-patched" +version = "0.5.3+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec45c14da997d0925c7835883e4d5c181f196fa142f8c19d7643d1e9af2592c3" +checksum = "a678df20055b43e57ef8cddde41cdfda9a3c1a060b67f4c5836dfb1d78543ba8" dependencies = [ "cc", - "fs_extra", "libc", ] [[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 0.3.9", ] [[package]] name = "time" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d634a985c4d4238ec39cacaed2e7ae552fbd3c476b552c1deac3021b7d7eaf0c" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" dependencies = [ - "itoa", - "libc", - "num_threads", + "serde 1.0.163", + "time-core", "time-macros", ] +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + [[package]] name = "time-macros" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] [[package]] name = "tiny-bip39" @@ -6929,15 +6935,14 @@ dependencies = [ [[package]] name = "tiny_http" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d6ef4e10d23c1efb862eecad25c5054429a71958b4eeef85eb5e7170b477ca" +checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" dependencies = [ "ascii", "chunked_transfer", + "httpdate", "log 0.4.17", - "time 0.3.15", - "url 2.3.1", ] [[package]] @@ -6951,28 +6956,27 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.21.2" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg 1.1.0", "bytes 1.4.0", "libc", - "memchr", - "mio 0.8.4", + "mio 0.8.6", "num_cpus", "parking_lot 0.12.1", "pin-project-lite", "signal-hook-registry", "socket2", "tokio-macros", - "winapi 0.3.9", + "windows-sys 0.48.0", ] [[package]] @@ -7019,20 +7023,20 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -7074,16 +7078,16 @@ version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" dependencies = [ - "rustls 0.20.7", + "rustls 0.20.8", "tokio", "webpki 0.22.0", ] [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", "pin-project-lite", @@ -7154,9 +7158,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes 1.4.0", "futures-core", @@ -7168,28 +7172,28 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ - "serde 1.0.145", + "serde 1.0.163", ] [[package]] name = "toml_datetime" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" [[package]] name = "toml_edit" -version = "0.18.1" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ "indexmap", - "nom8", "toml_datetime", + "winnow", ] [[package]] @@ -7201,14 +7205,14 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.13.0", + "base64 0.13.1", "bytes 1.4.0", "futures-core", "futures-util", "h2", "http", "http-body", - "hyper 0.14.20", + "hyper 0.14.26", "hyper-timeout", "percent-encoding 2.2.0", "pin-project", @@ -7219,7 +7223,7 @@ dependencies = [ "tokio", "tokio-rustls 0.23.4", "tokio-stream", - "tokio-util 0.7.4", + "tokio-util 0.7.8", "tower", "tower-layer", "tower-service", @@ -7237,7 +7241,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -7255,7 +7259,7 @@ dependencies = [ "rand 0.8.5", "slab", "tokio", - "tokio-util 0.7.4", + "tokio-util 0.7.8", "tower-layer", "tower-service", "tracing 0.1.37", @@ -7264,10 +7268,10 @@ dependencies = [ [[package]] name = "tower-abci" version = "0.1.0" -source = "git+https://github.com/heliaxdev/tower-abci.git?rev=3fb3b5c9d187d7009bc25c25813ddaab38216e73#3fb3b5c9d187d7009bc25c25813ddaab38216e73" +source = "git+https://github.com/heliaxdev/tower-abci.git?rev=79069a441cee7d9955a3d826d29656a0fb16115c#79069a441cee7d9955a3d826d29656a0fb16115c" dependencies = [ "bytes 1.4.0", - "futures 0.3.26", + "futures 0.3.28", "pin-project", "prost", "tendermint-proto 0.23.6", @@ -7285,7 +7289,7 @@ version = "0.1.0" source = "git+https://github.com/heliaxdev/tower-abci?rev=a31ce06533f5fbd943508676059d44de27395792#a31ce06533f5fbd943508676059d44de27395792" dependencies = [ "bytes 1.4.0", - "futures 0.3.26", + "futures 0.3.28", "pin-project", "prost", "tendermint-proto 0.23.5", @@ -7297,25 +7301,6 @@ dependencies = [ "tracing-tower", ] -[[package]] -name = "tower-http" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" -dependencies = [ - "bitflags", - "bytes 1.4.0", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - [[package]] name = "tower-layer" version = "0.3.2" @@ -7357,8 +7342,8 @@ dependencies = [ "cfg-if 1.0.0", "log 0.4.17", "pin-project-lite", - "tracing-attributes 0.1.23", - "tracing-core 0.1.30", + "tracing-attributes 0.1.24", + "tracing-core 0.1.31", ] [[package]] @@ -7368,18 +7353,18 @@ source = "git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30#df4ba17d85 dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", ] [[package]] @@ -7392,9 +7377,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", "valuable", @@ -7437,7 +7422,7 @@ checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" dependencies = [ "lazy_static", "log 0.4.17", - "tracing-core 0.1.30", + "tracing-core 0.1.31", ] [[package]] @@ -7446,8 +7431,8 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" dependencies = [ - "serde 1.0.145", - "tracing-core 0.1.30", + "serde 1.0.163", + "tracing-core 0.1.31", ] [[package]] @@ -7458,26 +7443,26 @@ checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ "sharded-slab", "thread_local", - "tracing-core 0.1.30", + "tracing-core 0.1.31", ] [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "nu-ansi-term", "once_cell", "regex", - "serde 1.0.145", + "serde 1.0.163", "serde_json", "sharded-slab", "smallvec 1.10.0", "thread_local", "tracing 0.1.37", - "tracing-core 0.1.30", + "tracing-core 0.1.31", "tracing-log", "tracing-serde", ] @@ -7487,7 +7472,7 @@ name = "tracing-tower" version = "0.1.0" source = "git+https://github.com/tokio-rs/tracing/?tag=tracing-0.1.30#df4ba17d857db8ba1b553f7b293ac8ba967a42f8" dependencies = [ - "futures 0.3.26", + "futures 0.3.28", "pin-project-lite", "tower-layer", "tower-make", @@ -7510,9 +7495,9 @@ checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" @@ -7520,7 +7505,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "byteorder", "bytes 1.4.0", "http", @@ -7541,9 +7526,9 @@ checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -7589,15 +7574,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -7626,7 +7611,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" dependencies = [ - "generic-array 0.14.6", + "generic-array 0.14.7", "subtle", ] @@ -7675,17 +7660,14 @@ name = "uuid" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" -dependencies = [ - "getrandom 0.2.7", -] [[package]] name = "uuid" -version = "1.2.2" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" dependencies = [ - "getrandom 0.2.7", + "getrandom 0.2.9", ] [[package]] @@ -7795,12 +7777,11 @@ checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi 0.3.9", "winapi-util", ] @@ -7822,9 +7803,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasi" @@ -7834,9 +7815,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -7844,24 +7825,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log 0.4.17", "once_cell", "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.33" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -7871,9 +7852,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7881,28 +7862,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-encoder" -version = "0.18.0" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64ac98d5d61192cc45c701b7e4bd0b9aff91e2edfc7a088406cfe2288581e2c" +checksum = "d05d0b6fcd0aeb98adf16e7975331b3c17222aa815148f5b976370ce589d80ef" dependencies = [ "leb128", ] @@ -7954,7 +7935,7 @@ dependencies = [ "enumset", "loupe", "rkyv", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "smallvec 1.10.0", "target-lexicon", @@ -8013,7 +7994,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.102", + "syn 1.0.109", ] [[package]] @@ -8029,7 +8010,7 @@ dependencies = [ "memmap2", "more-asserts", "rustc-demangle", - "serde 1.0.145", + "serde 1.0.163", "serde_bytes", "target-lexicon", "thiserror", @@ -8052,7 +8033,7 @@ dependencies = [ "loupe", "object 0.28.4", "rkyv", - "serde 1.0.145", + "serde 1.0.163", "tempfile", "tracing 0.1.37", "wasmer-compiler", @@ -8104,7 +8085,7 @@ dependencies = [ "indexmap", "loupe", "rkyv", - "serde 1.0.145", + "serde 1.0.163", "thiserror", ] @@ -8121,11 +8102,11 @@ dependencies = [ "indexmap", "libc", "loupe", - "memoffset", + "memoffset 0.6.5", "more-asserts", "region", "rkyv", - "serde 1.0.145", + "serde 1.0.163", "thiserror", "wasmer-types", "winapi 0.3.9", @@ -8145,9 +8126,9 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wast" -version = "47.0.1" +version = "57.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b98502f3978adea49551e801a6687678e6015317d7d9470a67fe813393f2a8" +checksum = "6eb0f5ed17ac4421193c7477da05892c2edafd67f9639e3c11a82086416662dc" dependencies = [ "leb128", "memchr", @@ -8157,18 +8138,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.49" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aab4e20c60429fbba9670a6cae0fff9520046ba0aa3e6d0b1cd2653bea14898" +checksum = "ab9ab0d87337c3be2bb6fc5cd331c4ba9fd6bcb4ee85048a0dd59ed9ecf92e53" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" dependencies = [ "js-sys", "wasm-bindgen", @@ -8264,9 +8245,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", @@ -8330,16 +8311,12 @@ dependencies = [ ] [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets 0.48.0", ] [[package]] @@ -8348,20 +8325,74 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" @@ -8371,15 +8402,15 @@ checksum = "c3d027175d00b01e0cbeb97d6ab6ebe03b12330a35786cbaca5252b1c4bf5d9b" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" @@ -8389,15 +8420,15 @@ checksum = "8793f59f7b8e8b01eda1a652b2697d87b93097198ae85f823b969ca5b89bba58" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" @@ -8407,15 +8438,15 @@ checksum = "8602f6c418b67024be2996c512f5f995de3ba417f4c75af68401ab8756796ae4" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" @@ -8425,21 +8456,27 @@ checksum = "f3d615f419543e0bd7d2b3323af0d86ff19cbc4f816e6453f36a2c2ce889c354" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" @@ -8449,15 +8486,24 @@ checksum = "11d95421d9ed3672c280884da53201a5c46b7b2765ca6faf34b0d71cf34a3561" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +dependencies = [ + "memchr", +] [[package]] name = "winreg" @@ -8517,7 +8563,7 @@ dependencies = [ [[package]] name = "zcash_encoding" version = "0.0.0" -source = "git+https://github.com/zcash/librustzcash?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" +source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ "byteorder", "nonempty", @@ -8538,7 +8584,7 @@ dependencies = [ [[package]] name = "zcash_note_encryption" version = "0.1.0" -source = "git+https://github.com/zcash/librustzcash?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" +source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ "chacha20", "chacha20poly1305", @@ -8549,13 +8595,13 @@ dependencies = [ [[package]] name = "zcash_primitives" version = "0.5.0" -source = "git+https://github.com/zcash/librustzcash?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" +source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ "aes", "bip0039", "bitvec 0.22.3", - "blake2b_simd 1.0.0", - "blake2s_simd 1.0.0", + "blake2b_simd 1.0.1", + "blake2s_simd 1.0.1", "bls12_381", "byteorder", "chacha20poly1305", @@ -8575,16 +8621,16 @@ dependencies = [ "sha2 0.9.9", "subtle", "zcash_encoding", - "zcash_note_encryption 0.1.0 (git+https://github.com/zcash/librustzcash?rev=2425a08)", + "zcash_note_encryption 0.1.0 (git+https://github.com/zcash/librustzcash/?rev=2425a08)", ] [[package]] name = "zcash_proofs" version = "0.5.0" -source = "git+https://github.com/zcash/librustzcash?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" +source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ "bellman", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "bls12_381", "byteorder", "directories", @@ -8598,31 +8644,31 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 1.0.102", - "synstructure", + "syn 2.0.15", ] [[package]] name = "zstd-sys" -version = "2.0.1+zstd.1.5.2" +version = "2.0.8+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd07cbbc53846d9145dbffdf6dd09a7a0aa52be46741825f5c97bdd4f73f12b" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" dependencies = [ "cc", "libc", + "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index e6908495a1..6c9c630d82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,21 +37,21 @@ async-process = {git = "https://github.com/heliaxdev/async-process.git", rev = " # borsh-schema-derive-internal = {path = "../borsh-rs/borsh-schema-derive-internal"} # patched to a commit on the `eth-bridge-integration+consensus-timeout` branch of our fork -tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} +tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} # patched to a commit on the `eth-bridge-integration` branch of our fork -ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "dcce4ac23d4d0a4324d23c54a1a99d41f0be2076"} -ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb"} -ibc-relayer = {git = "https://github.com/heliaxdev/hermes.git", rev = "b475b1cc9c94eac91d44da22aee2038f0512d702"} -ibc-relayer-types = {git = "https://github.com/heliaxdev/hermes.git", rev = "b475b1cc9c94eac91d44da22aee2038f0512d702"} +ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "2d7edc16412b60cabf78163fe24a6264e11f77a9"} +ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "7e527b5b8c95d83351e93ceafc14ac853224283f"} +ibc-relayer = {git = "https://github.com/heliaxdev/hermes.git", rev = "8e2ff3479edc0653f34b22df450d451eedd2c2ab"} +ibc-relayer-types = {git = "https://github.com/heliaxdev/hermes.git", rev = "8e2ff3479edc0653f34b22df450d451eedd2c2ab"} # patched to a commit on the `eth-bridge-integration` branch of our fork -tower-abci = {git = "https://github.com/heliaxdev/tower-abci.git", rev = "3fb3b5c9d187d7009bc25c25813ddaab38216e73"} +tower-abci = {git = "https://github.com/heliaxdev/tower-abci.git", rev = "79069a441cee7d9955a3d826d29656a0fb16115c"} # patched to the yanked 1.2.0 until masp updates bitvec funty = { git = "https://github.com/bitvecto-rs/funty/", rev = "7ef0d890fbcd8b3def1635ac1a877fc298488446" } diff --git a/apps/Cargo.toml b/apps/Cargo.toml index 52c498b14a..5be2549f75 100644 --- a/apps/Cargo.toml +++ b/apps/Cargo.toml @@ -70,7 +70,7 @@ abciplus = [ ] [dependencies] -namada = {path = "../shared", default-features = false, features = ["wasm-runtime", "ferveo-tpke"]} +namada = {path = "../shared", default-features = false, features = ["wasm-runtime", "ferveo-tpke", "masp-tx-gen"]} ark-serialize = "0.3.0" ark-std = "0.3.0" # branch = "bat/arse-merkle-tree" @@ -125,10 +125,10 @@ signal-hook = "0.3.9" sysinfo = {version = "=0.21.1", default-features = false} tar = "0.4.37" # temporarily using fork work-around -tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} -tendermint-config-abcipp = {package = "tendermint-config", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} -tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} -tendermint-rpc-abcipp = {package = "tendermint-rpc", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", features = ["http-client", "websocket-client"], optional = true} +tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} +tendermint-config-abcipp = {package = "tendermint-config", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} +tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} +tendermint-rpc-abcipp = {package = "tendermint-rpc", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", features = ["http-client", "websocket-client"], optional = true} tendermint = {version = "0.23.6", optional = true} tendermint-config = {version = "0.23.6", optional = true} tendermint-proto = {version = "0.23.6", optional = true} @@ -151,8 +151,8 @@ winapi = "0.3.9" masp_primitives = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c", features = ["transparent-inputs"] } masp_proofs = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c", features = ["bundled-prover", "download-params"] } bimap = {version = "0.6.2", features = ["serde"]} -rust_decimal = "1.26.1" -rust_decimal_macros = "1.26.1" +rust_decimal = "=1.26.1" +rust_decimal_macros = "=1.26.1" directories = "4.0.1" [dev-dependencies] diff --git a/apps/src/bin/namada-client/cli.rs b/apps/src/bin/namada-client/cli.rs index 659f198953..10316cb6bf 100644 --- a/apps/src/bin/namada-client/cli.rs +++ b/apps/src/bin/namada-client/cli.rs @@ -3,6 +3,7 @@ use std::time::Duration; use color_eyre::eyre::Result; +use namada_apps::cli::args::CliToSdk; use namada_apps::cli::cmds::*; use namada_apps::cli::{self, safe_exit}; use namada_apps::client::{rpc, tx, utils}; @@ -14,132 +15,290 @@ use tokio::time::sleep; pub async fn main() -> Result<()> { match cli::namada_client_cli()? { cli::NamadaClient::WithContext(cmd_box) => { - let (cmd, ctx) = *cmd_box; + let (cmd, mut ctx) = *cmd_box; use NamadaClientWithContext as Sub; match cmd { // Ledger cmds Sub::TxCustom(TxCustom(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_custom(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + let dry_run = args.tx.dry_run; + tx::submit_custom::(&client, &mut ctx, args) + .await?; + if !dry_run { + namada_apps::wallet::save(&ctx.wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); + } else { + println!( + "Transaction dry run. No addresses have been \ + saved." + ) + } } Sub::TxTransfer(TxTransfer(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_transfer(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_transfer(&client, ctx, args).await?; } Sub::TxIbcTransfer(TxIbcTransfer(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_ibc_transfer(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_ibc_transfer::(&client, ctx, args) + .await?; } Sub::TxUpdateVp(TxUpdateVp(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_update_vp(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_update_vp::(&client, &mut ctx, args) + .await?; } Sub::TxInitAccount(TxInitAccount(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_init_account(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + let dry_run = args.tx.dry_run; + tx::submit_init_account::( + &client, &mut ctx, args, + ) + .await?; + if !dry_run { + namada_apps::wallet::save(&ctx.wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); + } else { + println!( + "Transaction dry run. No addresses have been \ + saved." + ) + } } Sub::TxInitValidator(TxInitValidator(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_init_validator(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_init_validator::(&client, ctx, args) + .await; } Sub::TxInitProposal(TxInitProposal(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_init_proposal(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_init_proposal::(&client, ctx, args) + .await?; } Sub::TxVoteProposal(TxVoteProposal(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_vote_proposal(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_vote_proposal::(&client, ctx, args) + .await?; } Sub::TxRevealPk(TxRevealPk(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_reveal_pk(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_reveal_pk::(&client, &mut ctx, args) + .await?; } Sub::Bond(Bond(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_bond(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_bond::(&client, &mut ctx, args) + .await?; } Sub::Unbond(Unbond(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_unbond(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_unbond::(&client, &mut ctx, args) + .await?; } Sub::Withdraw(Withdraw(args)) => { wait_until_node_is_synched(&args.tx.ledger_address).await; - tx::submit_withdraw(ctx, args).await; + let client = + HttpClient::new(args.tx.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + tx::submit_withdraw::(&client, ctx, args) + .await?; } // Ledger queries Sub::QueryEpoch(QueryEpoch(args)) => { wait_until_node_is_synched(&args.ledger_address).await; - rpc::query_and_print_epoch(args).await; + let client = HttpClient::new(args.ledger_address).unwrap(); + rpc::query_and_print_epoch(&client).await; } Sub::QueryTransfers(QueryTransfers(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_transfers(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_transfers( + &client, + &mut ctx.wallet, + &mut ctx.shielded, + args, + ) + .await; } Sub::QueryConversions(QueryConversions(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_conversions(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_conversions(&client, &mut ctx.wallet, args) + .await; } Sub::QueryBlock(QueryBlock(args)) => { wait_until_node_is_synched(&args.ledger_address).await; - rpc::query_block(args).await; + let client = + HttpClient::new(args.ledger_address.clone()).unwrap(); + rpc::query_block(&client).await; } Sub::QueryBalance(QueryBalance(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_balance(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_balance( + &client, + &mut ctx.wallet, + &mut ctx.shielded, + args, + ) + .await; } Sub::QueryBonds(QueryBonds(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_bonds(ctx, args).await.unwrap(); + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_bonds(&client, &mut ctx.wallet, args) + .await + .expect("expected successful query of bonds"); } Sub::QueryBondedStake(QueryBondedStake(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_bonded_stake(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_bonded_stake(&client, args).await; } Sub::QueryCommissionRate(QueryCommissionRate(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_and_print_commission_rate(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_and_print_commission_rate( + &client, + &mut ctx.wallet, + args, + ) + .await; } Sub::QuerySlashes(QuerySlashes(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_slashes(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_slashes(&client, &mut ctx.wallet, args).await; } Sub::QueryDelegations(QueryDelegations(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_delegations(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_delegations(&client, &mut ctx.wallet, args) + .await; } Sub::QueryResult(QueryResult(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_result(ctx, args).await; + // Connect to the Tendermint server holding the transactions + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_result(&client, args).await; } Sub::QueryRawBytes(QueryRawBytes(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_raw_bytes(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_raw_bytes(&client, args).await; } Sub::QueryProposal(QueryProposal(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_proposal(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_proposal(&client, args).await; } Sub::QueryProposalResult(QueryProposalResult(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_proposal_result(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_proposal_result(&client, args).await; } Sub::QueryProtocolParameters(QueryProtocolParameters(args)) => { wait_until_node_is_synched(&args.query.ledger_address) .await; - rpc::query_protocol_parameters(ctx, args).await; + let client = + HttpClient::new(args.query.ledger_address.clone()) + .unwrap(); + let args = args.to_sdk(&mut ctx); + rpc::query_protocol_parameters(&client, args).await; } } } diff --git a/apps/src/bin/namada-wallet/cli.rs b/apps/src/bin/namada-wallet/cli.rs index 82a994b0ac..a3673b6399 100644 --- a/apps/src/bin/namada-wallet/cli.rs +++ b/apps/src/bin/namada-wallet/cli.rs @@ -7,16 +7,20 @@ use borsh::BorshSerialize; use color_eyre::eyre::Result; use itertools::sorted; use masp_primitives::zip32::ExtendedFullViewingKey; +use namada::ledger::masp::find_valid_diversifier; +use namada::ledger::wallet::FindKeyError; use namada::types::key::*; use namada::types::masp::{MaspValue, PaymentAddress}; use namada_apps::cli; +use namada_apps::cli::args::CliToSdk; use namada_apps::cli::{args, cmds, Context}; -use namada_apps::client::tx::find_valid_diversifier; -use namada_apps::wallet::{DecryptionError, FindKeyError}; +use namada_apps::wallet::{ + read_and_confirm_pwd, CliWalletUtils, DecryptionError, +}; use rand_core::OsRng; pub fn main() -> Result<()> { - let (cmd, ctx) = cli::namada_wallet_cli()?; + let (cmd, mut ctx) = cli::namada_wallet_cli()?; match cmd { cmds::NamadaWallet::Key(sub) => match sub { cmds::WalletKey::Gen(cmds::KeyGen(args)) => { @@ -45,6 +49,7 @@ pub fn main() -> Result<()> { spending_key_gen(ctx, args) } cmds::WalletMasp::GenPayAddr(cmds::MaspGenPayAddr(args)) => { + let args = args.to_sdk(&mut ctx); payment_address_gen(ctx, args) } cmds::WalletMasp::AddAddrKey(cmds::MaspAddAddrKey(args)) => { @@ -79,7 +84,7 @@ fn address_key_find( println!("Viewing key: {}", viewing_key); if unsafe_show_secret { // Check if alias is also a spending key - match wallet.find_spending_key(&alias) { + match wallet.find_spending_key(&alias, None) { Ok(spending_key) => println!("Spending key: {}", spending_key), Err(FindKeyError::KeyNotFound) => {} Err(err) => eprintln!("{}", err), @@ -141,7 +146,7 @@ fn spending_keys_list( // Print those too if they are available and requested. if unsafe_show_secret { if let Some(spending_key) = spending_key_opt { - match spending_key.get(decrypt, None) { + match spending_key.get::(decrypt, None) { // Here the spending key is unencrypted or successfully // decrypted Ok(spending_key) => { @@ -199,8 +204,10 @@ fn spending_key_gen( ) { let mut wallet = ctx.wallet; let alias = alias.to_lowercase(); - let (alias, _key) = wallet.gen_spending_key(alias, unsafe_dont_encrypt); - wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); + let (alias, _key) = wallet.gen_spending_key(alias, password); + namada_apps::wallet::save(&wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); println!( "Successfully added a spending key with alias: \"{}\"", alias @@ -209,7 +216,7 @@ fn spending_key_gen( /// Generate a shielded payment address from the given key. fn payment_address_gen( - mut ctx: Context, + ctx: Context, args::MaspPayAddrGen { alias, viewing_key, @@ -217,10 +224,7 @@ fn payment_address_gen( }: args::MaspPayAddrGen, ) { let alias = alias.to_lowercase(); - let viewing_key = - ExtendedFullViewingKey::from(ctx.get_cached(&viewing_key)) - .fvk - .vk; + let viewing_key = ExtendedFullViewingKey::from(viewing_key).fvk.vk; let (div, _g_d) = find_valid_diversifier(&mut OsRng); let payment_addr = viewing_key .to_payment_address(div) @@ -235,7 +239,8 @@ fn payment_address_gen( eprintln!("Payment address not added"); cli::safe_exit(1); }); - wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); + namada_apps::wallet::save(&wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); println!( "Successfully generated a payment address with the following alias: {}", alias, @@ -264,13 +269,10 @@ fn address_key_add( (alias, "viewing key") } MaspValue::ExtendedSpendingKey(spending_key) => { + let password = read_and_confirm_pwd(unsafe_dont_encrypt); let alias = ctx .wallet - .encrypt_insert_spending_key( - alias, - spending_key, - unsafe_dont_encrypt, - ) + .encrypt_insert_spending_key(alias, spending_key, password) .unwrap_or_else(|| { eprintln!("Spending key not added"); cli::safe_exit(1); @@ -288,7 +290,8 @@ fn address_key_add( (alias, "payment address") } }; - ctx.wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); + namada_apps::wallet::save(&ctx.wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); println!( "Successfully added a {} with the following alias to wallet: {}", typ, alias, @@ -306,8 +309,10 @@ fn key_and_address_gen( }: args::KeyAndAddressGen, ) { let mut wallet = ctx.wallet; - let (alias, _key) = wallet.gen_key(scheme, alias, unsafe_dont_encrypt); - wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); + let (alias, _key) = wallet.gen_key(scheme, alias, password); + namada_apps::wallet::save(&wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); println!( "Successfully added a key and an address with alias: \"{}\"", alias @@ -326,7 +331,7 @@ fn key_find( ) { let mut wallet = ctx.wallet; let found_keypair = match public_key { - Some(pk) => wallet.find_key_by_pk(&pk), + Some(pk) => wallet.find_key_by_pk(&pk, None), None => { let alias = alias.or(value); match alias { @@ -337,7 +342,7 @@ fn key_find( ); cli::safe_exit(1) } - Some(alias) => wallet.find_key(alias.to_lowercase()), + Some(alias) => wallet.find_key(alias.to_lowercase(), None), } } }; @@ -385,7 +390,7 @@ fn key_list( if let Some(pkh) = pkh { writeln!(w, " Public key hash: {}", pkh).unwrap(); } - match stored_keypair.get(decrypt, None) { + match stored_keypair.get::(decrypt, None) { Ok(keypair) => { writeln!(w, " Public key: {}", keypair.ref_to()) .unwrap(); @@ -409,7 +414,7 @@ fn key_list( fn key_export(ctx: Context, args::KeyExport { alias }: args::KeyExport) { let mut wallet = ctx.wallet; wallet - .find_key(alias.to_lowercase()) + .find_key(alias.to_lowercase(), None) .map(|keypair| { let file_data = keypair .try_to_vec() @@ -488,7 +493,8 @@ fn address_add(ctx: Context, args: args::AddressAdd) { eprintln!("Address not added"); cli::safe_exit(1); } - wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); + namada_apps::wallet::save(&wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); println!( "Successfully added a key and an address with alias: \"{}\"", args.alias.to_lowercase() diff --git a/apps/src/lib/cli.rs b/apps/src/lib/cli.rs index a86bfd259d..1e1f81402e 100644 --- a/apps/src/lib/cli.rs +++ b/apps/src/lib/cli.rs @@ -617,7 +617,7 @@ pub mod cmds { /// Generate a payment address from a viewing key or payment address #[derive(Clone, Debug)] - pub struct MaspGenPayAddr(pub args::MaspPayAddrGen); + pub struct MaspGenPayAddr(pub args::MaspPayAddrGen); impl SubCmd for MaspGenPayAddr { const CMD: &'static str = "gen-addr"; @@ -633,7 +633,7 @@ pub mod cmds { .about( "Generates a payment address from the given spending key", ) - .add_args::() + .add_args::>() } } @@ -938,7 +938,7 @@ pub mod cmds { } #[derive(Clone, Debug)] - pub struct QueryResult(pub args::QueryResult); + pub struct QueryResult(pub args::QueryResult); impl SubCmd for QueryResult { const CMD: &'static str = "tx-result"; @@ -952,12 +952,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query the result of a transaction.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryProposal(pub args::QueryProposal); + pub struct QueryProposal(pub args::QueryProposal); impl SubCmd for QueryProposal { const CMD: &'static str = "query-proposal"; @@ -974,12 +974,14 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query proposals.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryProposalResult(pub args::QueryProposalResult); + pub struct QueryProposalResult( + pub args::QueryProposalResult, + ); impl SubCmd for QueryProposalResult { const CMD: &'static str = "query-proposal-result"; @@ -996,12 +998,14 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query proposals result.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryProtocolParameters(pub args::QueryProtocolParameters); + pub struct QueryProtocolParameters( + pub args::QueryProtocolParameters, + ); impl SubCmd for QueryProtocolParameters { const CMD: &'static str = "query-protocol-parameters"; @@ -1020,12 +1024,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query protocol parameters.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxCustom(pub args::TxCustom); + pub struct TxCustom(pub args::TxCustom); impl SubCmd for TxCustom { const CMD: &'static str = "tx"; @@ -1039,12 +1043,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Send a transaction with custom WASM code.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxTransfer(pub args::TxTransfer); + pub struct TxTransfer(pub args::TxTransfer); impl SubCmd for TxTransfer { const CMD: &'static str = "transfer"; @@ -1058,12 +1062,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Send a signed transfer transaction.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxIbcTransfer(pub args::TxIbcTransfer); + pub struct TxIbcTransfer(pub args::TxIbcTransfer); impl SubCmd for TxIbcTransfer { const CMD: &'static str = "ibc-transfer"; @@ -1077,12 +1081,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Send a signed IBC transfer transaction.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxUpdateVp(pub args::TxUpdateVp); + pub struct TxUpdateVp(pub args::TxUpdateVp); impl SubCmd for TxUpdateVp { const CMD: &'static str = "update"; @@ -1099,12 +1103,12 @@ pub mod cmds { "Send a signed transaction to update account's validity \ predicate.", ) - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxInitAccount(pub args::TxInitAccount); + pub struct TxInitAccount(pub args::TxInitAccount); impl SubCmd for TxInitAccount { const CMD: &'static str = "init-account"; @@ -1121,12 +1125,12 @@ pub mod cmds { "Send a signed transaction to create a new established \ account.", ) - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxInitValidator(pub args::TxInitValidator); + pub struct TxInitValidator(pub args::TxInitValidator); impl SubCmd for TxInitValidator { const CMD: &'static str = "init-validator"; @@ -1143,12 +1147,12 @@ pub mod cmds { "Send a signed transaction to create a new validator \ account.", ) - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct Bond(pub args::Bond); + pub struct Bond(pub args::Bond); impl SubCmd for Bond { const CMD: &'static str = "bond"; @@ -1162,12 +1166,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Bond tokens in PoS system.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct Unbond(pub args::Unbond); + pub struct Unbond(pub args::Unbond); impl SubCmd for Unbond { const CMD: &'static str = "unbond"; @@ -1181,12 +1185,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Unbond tokens from a PoS bond.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct Withdraw(pub args::Withdraw); + pub struct Withdraw(pub args::Withdraw); impl SubCmd for Withdraw { const CMD: &'static str = "withdraw"; @@ -1200,12 +1204,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Withdraw tokens from previously unbonded PoS bond.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryEpoch(pub args::Query); + pub struct QueryEpoch(pub args::Query); impl SubCmd for QueryEpoch { const CMD: &'static str = "epoch"; @@ -1219,12 +1223,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query the epoch of the last committed block.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryConversions(pub args::QueryConversions); + pub struct QueryConversions(pub args::QueryConversions); impl SubCmd for QueryConversions { const CMD: &'static str = "conversions"; @@ -1238,12 +1242,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query currently applicable conversions.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryBlock(pub args::Query); + pub struct QueryBlock(pub args::Query); impl SubCmd for QueryBlock { const CMD: &'static str = "block"; @@ -1257,12 +1261,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query the last committed block.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryBalance(pub args::QueryBalance); + pub struct QueryBalance(pub args::QueryBalance); impl SubCmd for QueryBalance { const CMD: &'static str = "balance"; @@ -1276,12 +1280,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query balance(s) of tokens.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryBonds(pub args::QueryBonds); + pub struct QueryBonds(pub args::QueryBonds); impl SubCmd for QueryBonds { const CMD: &'static str = "bonds"; @@ -1295,12 +1299,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query PoS bond(s).") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryBondedStake(pub args::QueryBondedStake); + pub struct QueryBondedStake(pub args::QueryBondedStake); impl SubCmd for QueryBondedStake { const CMD: &'static str = "bonded-stake"; @@ -1314,12 +1318,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query PoS bonded stake.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryTransfers(pub args::QueryTransfers); + pub struct QueryTransfers(pub args::QueryTransfers); impl SubCmd for QueryTransfers { const CMD: &'static str = "show-transfers"; @@ -1333,12 +1337,14 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query the accepted transfers to date.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryCommissionRate(pub args::QueryCommissionRate); + pub struct QueryCommissionRate( + pub args::QueryCommissionRate, + ); impl SubCmd for QueryCommissionRate { const CMD: &'static str = "commission-rate"; @@ -1352,12 +1358,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query commission rate.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QuerySlashes(pub args::QuerySlashes); + pub struct QuerySlashes(pub args::QuerySlashes); impl SubCmd for QuerySlashes { const CMD: &'static str = "slashes"; @@ -1374,12 +1380,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query PoS applied slashes.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryDelegations(pub args::QueryDelegations); + pub struct QueryDelegations(pub args::QueryDelegations); impl SubCmd for QueryDelegations { const CMD: &'static str = "delegations"; @@ -1396,12 +1402,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Find PoS delegations from the given owner address.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct QueryRawBytes(pub args::QueryRawBytes); + pub struct QueryRawBytes(pub args::QueryRawBytes); impl SubCmd for QueryRawBytes { const CMD: &'static str = "query-bytes"; @@ -1415,12 +1421,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Query the raw bytes of a given storage key") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxInitProposal(pub args::InitProposal); + pub struct TxInitProposal(pub args::InitProposal); impl SubCmd for TxInitProposal { const CMD: &'static str = "init-proposal"; @@ -1437,12 +1443,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Create a new proposal.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxVoteProposal(pub args::VoteProposal); + pub struct TxVoteProposal(pub args::VoteProposal); impl SubCmd for TxVoteProposal { const CMD: &'static str = "vote-proposal"; @@ -1459,12 +1465,12 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) .about("Vote a proposal.") - .add_args::() + .add_args::>() } } #[derive(Clone, Debug)] - pub struct TxRevealPk(pub args::RevealPk); + pub struct TxRevealPk(pub args::RevealPk); impl SubCmd for TxRevealPk { const CMD: &'static str = "reveal-pk"; @@ -1489,7 +1495,7 @@ pub mod cmds { signature verification on transactions authorized by \ this account.", ) - .add_args::() + .add_args::>() } } @@ -1647,6 +1653,7 @@ pub mod args { use std::str::FromStr; use namada::ibc::core::ics24_host::identifier::{ChannelId, PortId}; + pub use namada::ledger::args::*; use namada::types::address::Address; use namada::types::chain::{ChainId, ChainIdPrefix}; use namada::types::key::*; @@ -1654,7 +1661,6 @@ pub mod args { use namada::types::storage::{self, BlockHeight, Epoch}; use namada::types::time::DateTimeUtc; use namada::types::token; - use namada::types::transaction::GasLimit; use rust_decimal::Decimal; use super::context::*; @@ -1664,125 +1670,143 @@ pub mod args { use crate::facade::tendermint::Timeout; use crate::facade::tendermint_config::net::Address as TendermintAddress; - const ADDRESS: Arg = arg("address"); - const ALIAS_OPT: ArgOpt = ALIAS.opt(); - const ALIAS: Arg = arg("alias"); - const ALLOW_DUPLICATE_IP: ArgFlag = flag("allow-duplicate-ip"); - const AMOUNT: Arg = arg("amount"); - const ARCHIVE_DIR: ArgOpt = arg_opt("archive-dir"); - const BALANCE_OWNER: ArgOpt = arg_opt("owner"); - const BASE_DIR: ArgDefault = arg_default( + pub const TX_INIT_ACCOUNT_WASM: &str = "tx_init_account.wasm"; + pub const TX_INIT_VALIDATOR_WASM: &str = "tx_init_validator.wasm"; + pub const TX_INIT_PROPOSAL: &str = "tx_init_proposal.wasm"; + pub const TX_VOTE_PROPOSAL: &str = "tx_vote_proposal.wasm"; + pub const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm"; + pub const TX_UPDATE_VP_WASM: &str = "tx_update_vp.wasm"; + pub const TX_TRANSFER_WASM: &str = "tx_transfer.wasm"; + pub const TX_IBC_WASM: &str = "tx_ibc.wasm"; + pub const VP_USER_WASM: &str = "vp_user.wasm"; + pub const TX_BOND_WASM: &str = "tx_bond.wasm"; + pub const TX_UNBOND_WASM: &str = "tx_unbond.wasm"; + pub const TX_WITHDRAW_WASM: &str = "tx_withdraw.wasm"; + pub const TX_CHANGE_COMMISSION_WASM: &str = + "tx_change_validator_commission.wasm"; + + pub const ADDRESS: Arg = arg("address"); + pub const ALIAS_OPT: ArgOpt = ALIAS.opt(); + pub const ALIAS: Arg = arg("alias"); + pub const ALLOW_DUPLICATE_IP: ArgFlag = flag("allow-duplicate-ip"); + pub const AMOUNT: Arg = arg("amount"); + pub const ARCHIVE_DIR: ArgOpt = arg_opt("archive-dir"); + pub const BALANCE_OWNER: ArgOpt = arg_opt("owner"); + pub const BASE_DIR: ArgDefault = arg_default( "base-dir", DefaultFn(|| match env::var("NAMADA_BASE_DIR") { - Ok(dir) => dir.into(), + Ok(dir) => PathBuf::from(dir), Err(_) => config::get_default_namada_folder(), }), ); - const BLOCK_HEIGHT: Arg = arg("block-height"); - // const BLOCK_HEIGHT_OPT: ArgOpt = arg_opt("height"); - const BROADCAST_ONLY: ArgFlag = flag("broadcast-only"); - const CHAIN_ID: Arg = arg("chain-id"); - const CHAIN_ID_OPT: ArgOpt = CHAIN_ID.opt(); - const CHAIN_ID_PREFIX: Arg = arg("chain-prefix"); - const CHANNEL_ID: Arg = arg("channel-id"); - const CODE_PATH: Arg = arg("code-path"); - const CODE_PATH_OPT: ArgOpt = CODE_PATH.opt(); - const COMMISSION_RATE: Arg = arg("commission-rate"); - const CONSENSUS_TIMEOUT_COMMIT: ArgDefault = arg_default( + pub const BLOCK_HEIGHT: Arg = arg("block-height"); + // pub const BLOCK_HEIGHT_OPT: ArgOpt = arg_opt("height"); + pub const BROADCAST_ONLY: ArgFlag = flag("broadcast-only"); + pub const CHAIN_ID: Arg = arg("chain-id"); + pub const CHAIN_ID_OPT: ArgOpt = CHAIN_ID.opt(); + pub const CHAIN_ID_PREFIX: Arg = arg("chain-prefix"); + pub const CHANNEL_ID: Arg = arg("channel-id"); + pub const CODE_PATH: Arg = arg("code-path"); + pub const CODE_PATH_OPT: ArgOpt = CODE_PATH.opt(); + pub const COMMISSION_RATE: Arg = arg("commission-rate"); + pub const CONSENSUS_TIMEOUT_COMMIT: ArgDefault = arg_default( "consensus-timeout-commit", DefaultFn(|| Timeout::from_str("1s").unwrap()), ); - const DATA_PATH_OPT: ArgOpt = arg_opt("data-path"); - const DATA_PATH: Arg = arg("data-path"); - const DECRYPT: ArgFlag = flag("decrypt"); - const DONT_ARCHIVE: ArgFlag = flag("dont-archive"); - const DRY_RUN_TX: ArgFlag = flag("dry-run"); - const DUMP_TX: ArgFlag = flag("dump-tx"); - const EPOCH: ArgOpt = arg_opt("epoch"); - const EXPIRATION_OPT: ArgOpt = arg_opt("expiration"); - const FORCE: ArgFlag = flag("force"); - const DONT_PREFETCH_WASM: ArgFlag = flag("dont-prefetch-wasm"); - const GAS_AMOUNT: ArgDefault = + pub const DATA_PATH_OPT: ArgOpt = arg_opt("data-path"); + pub const DATA_PATH: Arg = arg("data-path"); + pub const DECRYPT: ArgFlag = flag("decrypt"); + pub const DONT_ARCHIVE: ArgFlag = flag("dont-archive"); + pub const DRY_RUN_TX: ArgFlag = flag("dry-run"); + pub const DUMP_TX: ArgFlag = flag("dump-tx"); + pub const EPOCH: ArgOpt = arg_opt("epoch"); + pub const EXPIRATION_OPT: ArgOpt = arg_opt("expiration"); + pub const FORCE: ArgFlag = flag("force"); + pub const DONT_PREFETCH_WASM: ArgFlag = flag("dont-prefetch-wasm"); + pub const GAS_AMOUNT: ArgDefault = arg_default("gas-amount", DefaultFn(|| token::Amount::from(0))); - const GAS_LIMIT: ArgDefault = + pub const GAS_LIMIT: ArgDefault = arg_default("gas-limit", DefaultFn(|| token::Amount::from(0))); - const GAS_TOKEN: ArgDefaultFromCtx = - arg_default_from_ctx("gas-token", DefaultFn(|| "NAM".into())); - const GENESIS_PATH: Arg = arg("genesis-path"); - const GENESIS_VALIDATOR: ArgOpt = arg("genesis-validator").opt(); - const HALT_ACTION: ArgFlag = flag("halt"); - const HISTORIC: ArgFlag = flag("historic"); - const LEDGER_ADDRESS_ABOUT: &str = + pub const GAS_TOKEN: ArgDefaultFromCtx = + arg_default_from_ctx("gas-token", DefaultFn(|| "NAM".parse().unwrap())); + pub const GENESIS_PATH: Arg = arg("genesis-path"); + pub const GENESIS_VALIDATOR: ArgOpt = + arg("genesis-validator").opt(); + pub const HALT_ACTION: ArgFlag = flag("halt"); + pub const HISTORIC: ArgFlag = flag("historic"); + pub const LEDGER_ADDRESS_ABOUT: &str = "Address of a ledger node as \"{scheme}://{host}:{port}\". If the \ scheme is not supplied, it is assumed to be TCP."; - const LEDGER_ADDRESS_DEFAULT: ArgDefault = + pub const LEDGER_ADDRESS_DEFAULT: ArgDefault = LEDGER_ADDRESS.default(DefaultFn(|| { let raw = "127.0.0.1:26657"; TendermintAddress::from_str(raw).unwrap() })); - const LEDGER_ADDRESS: Arg = arg("node"); - const LOCALHOST: ArgFlag = flag("localhost"); - const MASP_VALUE: Arg = arg("value"); - const MAX_COMMISSION_RATE_CHANGE: Arg = + pub const LEDGER_ADDRESS: Arg = arg("node"); + pub const LOCALHOST: ArgFlag = flag("localhost"); + pub const MASP_VALUE: Arg = arg("value"); + pub const MAX_COMMISSION_RATE_CHANGE: Arg = arg("max-commission-rate-change"); - const MODE: ArgOpt = arg_opt("mode"); - const NET_ADDRESS: Arg = arg("net-address"); - const NAMADA_START_TIME: ArgOpt = arg_opt("time"); - const NO_CONVERSIONS: ArgFlag = flag("no-conversions"); - const OUT_FILE_PATH_OPT: ArgOpt = arg_opt("out-file-path"); - const OWNER: Arg = arg("owner"); - const OWNER_OPT: ArgOpt = OWNER.opt(); - const PIN: ArgFlag = flag("pin"); - const PORT_ID: ArgDefault = arg_default( + pub const MODE: ArgOpt = arg_opt("mode"); + pub const NET_ADDRESS: Arg = arg("net-address"); + pub const NAMADA_START_TIME: ArgOpt = arg_opt("time"); + pub const NO_CONVERSIONS: ArgFlag = flag("no-conversions"); + pub const OUT_FILE_PATH_OPT: ArgOpt = arg_opt("out-file-path"); + pub const OWNER: Arg = arg("owner"); + pub const OWNER_OPT: ArgOpt = OWNER.opt(); + pub const PIN: ArgFlag = flag("pin"); + pub const PORT_ID: ArgDefault = arg_default( "port-id", DefaultFn(|| PortId::from_str("transfer").unwrap()), ); - const PROPOSAL_OFFLINE: ArgFlag = flag("offline"); - const PROTOCOL_KEY: ArgOpt = arg_opt("protocol-key"); - const PRE_GENESIS_PATH: ArgOpt = arg_opt("pre-genesis-path"); - const PUBLIC_KEY: Arg = arg("public-key"); - const PROPOSAL_ID: Arg = arg("proposal-id"); - const PROPOSAL_ID_OPT: ArgOpt = arg_opt("proposal-id"); - const PROPOSAL_VOTE_PGF_OPT: ArgOpt = arg_opt("pgf"); - const PROPOSAL_VOTE_ETH_OPT: ArgOpt = arg_opt("eth"); - const PROPOSAL_VOTE: Arg = arg("vote"); - const RAW_ADDRESS: Arg
= arg("address"); - const RAW_ADDRESS_OPT: ArgOpt
= RAW_ADDRESS.opt(); - const RAW_PUBLIC_KEY: Arg = arg("public-key"); - const RAW_PUBLIC_KEY_OPT: ArgOpt = RAW_PUBLIC_KEY.opt(); - const RECEIVER: Arg = arg("receiver"); - const SCHEME: ArgDefault = + pub const PROPOSAL_OFFLINE: ArgFlag = flag("offline"); + pub const PROTOCOL_KEY: ArgOpt = arg_opt("protocol-key"); + pub const PRE_GENESIS_PATH: ArgOpt = arg_opt("pre-genesis-path"); + pub const PUBLIC_KEY: Arg = arg("public-key"); + pub const PROPOSAL_ID: Arg = arg("proposal-id"); + pub const PROPOSAL_ID_OPT: ArgOpt = arg_opt("proposal-id"); + pub const PROPOSAL_VOTE_PGF_OPT: ArgOpt = arg_opt("pgf"); + pub const PROPOSAL_VOTE_ETH_OPT: ArgOpt = arg_opt("eth"); + pub const PROPOSAL_VOTE: Arg = arg("vote"); + pub const RAW_ADDRESS: Arg
= arg("address"); + pub const RAW_ADDRESS_OPT: ArgOpt
= RAW_ADDRESS.opt(); + pub const RAW_PUBLIC_KEY: Arg = arg("public-key"); + pub const RAW_PUBLIC_KEY_OPT: ArgOpt = + arg_opt("public-key"); + pub const RECEIVER: Arg = arg("receiver"); + pub const SCHEME: ArgDefault = arg_default("scheme", DefaultFn(|| SchemeType::Ed25519)); - const SIGNER: ArgOpt = arg_opt("signer"); - const SIGNING_KEY_OPT: ArgOpt = SIGNING_KEY.opt(); - const SIGNING_KEY: Arg = arg("signing-key"); - const SOURCE: Arg = arg("source"); - const SOURCE_OPT: ArgOpt = SOURCE.opt(); - const STORAGE_KEY: Arg = arg("storage-key"); - const SUB_PREFIX: ArgOpt = arg_opt("sub-prefix"); - const SUSPEND_ACTION: ArgFlag = flag("suspend"); - const TENDERMINT_TX_INDEX: ArgFlag = flag("tx-index"); - const TIMEOUT_HEIGHT: ArgOpt = arg_opt("timeout-height"); - const TIMEOUT_SEC_OFFSET: ArgOpt = arg_opt("timeout-sec-offset"); - const TOKEN_OPT: ArgOpt = TOKEN.opt(); - const TOKEN: Arg = arg("token"); - const TRANSFER_SOURCE: Arg = arg("source"); - const TRANSFER_TARGET: Arg = arg("target"); - const TX_HASH: Arg = arg("tx-hash"); - const UNSAFE_DONT_ENCRYPT: ArgFlag = flag("unsafe-dont-encrypt"); - const UNSAFE_SHOW_SECRET: ArgFlag = flag("unsafe-show-secret"); - const VALIDATOR: Arg = arg("validator"); - const VALIDATOR_OPT: ArgOpt = VALIDATOR.opt(); - const VALIDATOR_ACCOUNT_KEY: ArgOpt = + pub const SIGNER: ArgOpt = arg_opt("signer"); + pub const SIGNING_KEY_OPT: ArgOpt = SIGNING_KEY.opt(); + pub const SIGNING_KEY: Arg = arg("signing-key"); + pub const SOURCE: Arg = arg("source"); + pub const SOURCE_OPT: ArgOpt = SOURCE.opt(); + pub const STORAGE_KEY: Arg = arg("storage-key"); + pub const SUB_PREFIX: ArgOpt = arg_opt("sub-prefix"); + pub const SUSPEND_ACTION: ArgFlag = flag("suspend"); + pub const TENDERMINT_TX_INDEX: ArgFlag = flag("tx-index"); + pub const TIMEOUT_HEIGHT: ArgOpt = arg_opt("timeout-height"); + pub const TIMEOUT_SEC_OFFSET: ArgOpt = arg_opt("timeout-sec-offset"); + pub const TOKEN_OPT: ArgOpt = TOKEN.opt(); + pub const TOKEN: Arg = arg("token"); + pub const TRANSFER_SOURCE: Arg = arg("source"); + pub const TRANSFER_TARGET: Arg = arg("target"); + pub const TX_HASH: Arg = arg("tx-hash"); + pub const UNSAFE_DONT_ENCRYPT: ArgFlag = flag("unsafe-dont-encrypt"); + pub const UNSAFE_SHOW_SECRET: ArgFlag = flag("unsafe-show-secret"); + pub const VALIDATOR: Arg = arg("validator"); + pub const VALIDATOR_OPT: ArgOpt = VALIDATOR.opt(); + pub const VALIDATOR_ACCOUNT_KEY: ArgOpt = arg_opt("account-key"); - const VALIDATOR_CONSENSUS_KEY: ArgOpt = + pub const VALIDATOR_CONSENSUS_KEY: ArgOpt = arg_opt("consensus-key"); - const VALIDATOR_CODE_PATH: ArgOpt = arg_opt("validator-code-path"); - const VALUE: ArgOpt = arg_opt("value"); - const VIEWING_KEY: Arg = arg("key"); - const WASM_CHECKSUMS_PATH: Arg = arg("wasm-checksums-path"); - const WASM_DIR: ArgOpt = arg_opt("wasm-dir"); + pub const VALIDATOR_CODE_PATH: ArgOpt = + arg_opt("validator-code-path"); + pub const VALUE: ArgOpt = arg_opt("value"); + pub const VIEWING_KEY: Arg = arg("key"); + pub const WASM_CHECKSUMS_PATH: Arg = arg("wasm-checksums-path"); + pub const WASM_DIR: ArgOpt = arg_opt("wasm-dir"); /// Global command arguments #[derive(Clone, Debug)] @@ -1949,16 +1973,20 @@ pub mod args { } } - /// Transaction associated results arguments - #[derive(Clone, Debug)] - pub struct QueryResult { - /// Common query args - pub query: Query, - /// Hash of transaction to lookup - pub tx_hash: String, + pub trait CliToSdk: Args { + fn to_sdk(self, ctx: &mut Context) -> X; } - impl Args for QueryResult { + impl CliToSdk> for QueryResult { + fn to_sdk(self, ctx: &mut Context) -> QueryResult { + QueryResult:: { + query: self.query.to_sdk(ctx), + tx_hash: self.tx_hash, + } + } + } + + impl Args for QueryResult { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let tx_hash = TX_HASH.parse(matches); @@ -1966,7 +1994,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::().arg( + app.add_args::>().arg( TX_HASH .def() .about("The hash of the transaction being looked up."), @@ -1974,18 +2002,20 @@ pub mod args { } } - /// Custom transaction arguments - #[derive(Clone, Debug)] - pub struct TxCustom { - /// Common tx arguments - pub tx: Tx, - /// Path to the tx WASM code file - pub code_path: PathBuf, - /// Path to the data file - pub data_path: Option, + impl CliToSdk> for TxCustom { + fn to_sdk(self, ctx: &mut Context) -> TxCustom { + TxCustom:: { + tx: self.tx.to_sdk(ctx), + code_path: ctx.read_wasm(self.code_path), + data_path: self.data_path.map(|data_path| { + std::fs::read(data_path) + .expect("Expected a file at given data path") + }), + } + } } - impl Args for TxCustom { + impl Args for TxCustom { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let code_path = CODE_PATH.parse(matches); @@ -1998,7 +2028,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg( CODE_PATH .def() @@ -2012,24 +2042,22 @@ pub mod args { } } - /// Transfer transaction arguments - #[derive(Clone, Debug)] - pub struct TxTransfer { - /// Common tx arguments - pub tx: Tx, - /// Transfer source address - pub source: WalletTransferSource, - /// Transfer target address - pub target: WalletTransferTarget, - /// Transferred token address - pub token: WalletAddress, - /// Transferred token address - pub sub_prefix: Option, - /// Transferred token amount - pub amount: token::Amount, - } - - impl Args for TxTransfer { + impl CliToSdk> for TxTransfer { + fn to_sdk(self, ctx: &mut Context) -> TxTransfer { + TxTransfer:: { + tx: self.tx.to_sdk(ctx), + source: ctx.get_cached(&self.source), + target: ctx.get(&self.target), + token: ctx.get(&self.token), + sub_prefix: self.sub_prefix, + amount: self.amount, + native_token: ctx.native_token.clone(), + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } + } + + impl Args for TxTransfer { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let source = TRANSFER_SOURCE.parse(matches); @@ -2037,6 +2065,7 @@ pub mod args { let token = TOKEN.parse(matches); let sub_prefix = SUB_PREFIX.parse(matches); let amount = AMOUNT.parse(matches); + let tx_code_path = PathBuf::from(TX_TRANSFER_WASM); Self { tx, source, @@ -2044,11 +2073,13 @@ pub mod args { token, sub_prefix, amount, + native_token: (), + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(TRANSFER_SOURCE.def().about( "The source account address. The source's key may be used \ to produce the signature.", @@ -2063,32 +2094,25 @@ pub mod args { } } - /// IBC transfer transaction arguments - #[derive(Clone, Debug)] - pub struct TxIbcTransfer { - /// Common tx arguments - pub tx: Tx, - /// Transfer source address - pub source: WalletAddress, - /// Transfer target address - pub receiver: String, - /// Transferred token address - pub token: WalletAddress, - /// Transferred token address - pub sub_prefix: Option, - /// Transferred token amount - pub amount: token::Amount, - /// Port ID - pub port_id: PortId, - /// Channel ID - pub channel_id: ChannelId, - /// Timeout height of the destination chain - pub timeout_height: Option, - /// Timeout timestamp offset - pub timeout_sec_offset: Option, - } - - impl Args for TxIbcTransfer { + impl CliToSdk> for TxIbcTransfer { + fn to_sdk(self, ctx: &mut Context) -> TxIbcTransfer { + TxIbcTransfer:: { + tx: self.tx.to_sdk(ctx), + source: ctx.get(&self.source), + receiver: self.receiver, + token: ctx.get(&self.token), + sub_prefix: self.sub_prefix, + amount: self.amount, + port_id: self.port_id, + channel_id: self.channel_id, + timeout_height: self.timeout_height, + timeout_sec_offset: self.timeout_sec_offset, + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } + } + + impl Args for TxIbcTransfer { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let source = SOURCE.parse(matches); @@ -2100,6 +2124,7 @@ pub mod args { let channel_id = CHANNEL_ID.parse(matches); let timeout_height = TIMEOUT_HEIGHT.parse(matches); let timeout_sec_offset = TIMEOUT_SEC_OFFSET.parse(matches); + let tx_code_path = PathBuf::from(TX_IBC_WASM); Self { tx, source, @@ -2111,11 +2136,12 @@ pub mod args { channel_id, timeout_height, timeout_sec_offset, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(SOURCE.def().about( "The source account address. The source's key is used to \ produce the signature.", @@ -2137,35 +2163,47 @@ pub mod args { } } - /// Transaction to initialize a new account - #[derive(Clone, Debug)] - pub struct TxInitAccount { - /// Common tx arguments - pub tx: Tx, - /// Address of the source account - pub source: WalletAddress, - /// Path to the VP WASM code file for the new account - pub vp_code_path: Option, - /// Public key for the new account - pub public_key: WalletPublicKey, + impl CliToSdk> for TxInitAccount { + fn to_sdk(self, ctx: &mut Context) -> TxInitAccount { + TxInitAccount:: { + tx: self.tx.to_sdk(ctx), + source: ctx.get(&self.source), + vp_code: ctx.read_wasm(self.vp_code), + vp_code_path: self + .vp_code_path + .as_path() + .to_str() + .unwrap() + .to_string() + .into_bytes(), + tx_code_path: ctx.read_wasm(self.tx_code_path), + public_key: ctx.get_cached(&self.public_key), + } + } } - impl Args for TxInitAccount { + impl Args for TxInitAccount { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let source = SOURCE.parse(matches); - let vp_code_path = CODE_PATH_OPT.parse(matches); + let vp_code_path = CODE_PATH_OPT + .parse(matches) + .unwrap_or_else(|| PathBuf::from(VP_USER_WASM)); + let vp_code = vp_code_path.clone(); + let tx_code_path = PathBuf::from(TX_INIT_ACCOUNT_WASM); let public_key = PUBLIC_KEY.parse(matches); Self { tx, source, + vp_code, vp_code_path, public_key, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(SOURCE.def().about( "The source account's address that signs the transaction.", )) @@ -2181,22 +2219,31 @@ pub mod args { } } - /// Transaction to initialize a new account - #[derive(Clone, Debug)] - pub struct TxInitValidator { - pub tx: Tx, - pub source: WalletAddress, - pub scheme: SchemeType, - pub account_key: Option, - pub consensus_key: Option, - pub protocol_key: Option, - pub commission_rate: Decimal, - pub max_commission_rate_change: Decimal, - pub validator_vp_code_path: Option, - pub unsafe_dont_encrypt: bool, + impl CliToSdk> for TxInitValidator { + fn to_sdk(self, ctx: &mut Context) -> TxInitValidator { + TxInitValidator:: { + tx: self.tx.to_sdk(ctx), + source: ctx.get(&self.source), + scheme: self.scheme, + account_key: self.account_key.map(|x| ctx.get_cached(&x)), + consensus_key: self.consensus_key.map(|x| ctx.get_cached(&x)), + protocol_key: self.protocol_key.map(|x| ctx.get_cached(&x)), + commission_rate: self.commission_rate, + max_commission_rate_change: self.max_commission_rate_change, + validator_vp_code_path: self + .validator_vp_code_path + .as_path() + .to_str() + .unwrap() + .to_string() + .into_bytes(), + unsafe_dont_encrypt: self.unsafe_dont_encrypt, + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } } - impl Args for TxInitValidator { + impl Args for TxInitValidator { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let source = SOURCE.parse(matches); @@ -2207,8 +2254,11 @@ pub mod args { let commission_rate = COMMISSION_RATE.parse(matches); let max_commission_rate_change = MAX_COMMISSION_RATE_CHANGE.parse(matches); - let validator_vp_code_path = VALIDATOR_CODE_PATH.parse(matches); + let validator_vp_code_path = VALIDATOR_CODE_PATH + .parse(matches) + .unwrap_or_else(|| PathBuf::from(VP_USER_WASM)); let unsafe_dont_encrypt = UNSAFE_DONT_ENCRYPT.parse(matches); + let tx_code_path = PathBuf::from(TX_INIT_VALIDATOR_WASM); Self { tx, source, @@ -2220,11 +2270,12 @@ pub mod args { max_commission_rate_change, validator_vp_code_path, unsafe_dont_encrypt, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(SOURCE.def().about( "The source account's address that signs the transaction.", )) @@ -2267,31 +2318,45 @@ pub mod args { } } - /// Transaction to update a VP arguments - #[derive(Clone, Debug)] - pub struct TxUpdateVp { - /// Common tx arguments - pub tx: Tx, - /// Path to the VP WASM code file - pub vp_code_path: PathBuf, - /// Address of the account whose VP is to be updated - pub addr: WalletAddress, + impl CliToSdk> for TxUpdateVp { + fn to_sdk(self, ctx: &mut Context) -> TxUpdateVp { + TxUpdateVp:: { + tx: self.tx.to_sdk(ctx), + vp_code_path: self + .vp_code_path + .as_path() + .to_str() + .unwrap() + .to_string() + .into_bytes(), + tx_code_path: self + .tx_code_path + .as_path() + .to_str() + .unwrap() + .to_string() + .into_bytes(), + addr: ctx.get(&self.addr), + } + } } - impl Args for TxUpdateVp { + impl Args for TxUpdateVp { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let vp_code_path = CODE_PATH.parse(matches); let addr = ADDRESS.parse(matches); + let tx_code_path = PathBuf::from(TX_UPDATE_VP_WASM); Self { tx, vp_code_path, addr, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg( CODE_PATH.def().about( "The path to the new validity predicate WASM code.", @@ -2304,36 +2369,38 @@ pub mod args { } } - /// Bond arguments - #[derive(Clone, Debug)] - pub struct Bond { - /// Common tx arguments - pub tx: Tx, - /// Validator address - pub validator: WalletAddress, - /// Amount of tokens to stake in a bond - pub amount: token::Amount, - /// Source address for delegations. For self-bonds, the validator is - /// also the source. - pub source: Option, + impl CliToSdk> for Bond { + fn to_sdk(self, ctx: &mut Context) -> Bond { + Bond:: { + tx: self.tx.to_sdk(ctx), + validator: ctx.get(&self.validator), + amount: self.amount, + source: self.source.map(|x| ctx.get(&x)), + native_token: ctx.native_token.clone(), + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } } - impl Args for Bond { + impl Args for Bond { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let validator = VALIDATOR.parse(matches); let amount = AMOUNT.parse(matches); let source = SOURCE_OPT.parse(matches); + let tx_code_path = PathBuf::from(TX_BOND_WASM); Self { tx, validator, amount, source, + native_token: (), + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(VALIDATOR.def().about("Validator address.")) .arg(AMOUNT.def().about("Amount of tokens to stake in a bond.")) .arg(SOURCE_OPT.def().about( @@ -2343,36 +2410,36 @@ pub mod args { } } - /// Unbond arguments - #[derive(Clone, Debug)] - pub struct Unbond { - /// Common tx arguments - pub tx: Tx, - /// Validator address - pub validator: WalletAddress, - /// Amount of tokens to unbond from a bond - pub amount: token::Amount, - /// Source address for unbonding from delegations. For unbonding from - /// self-bonds, the validator is also the source - pub source: Option, + impl CliToSdk> for Unbond { + fn to_sdk(self, ctx: &mut Context) -> Unbond { + Unbond:: { + tx: self.tx.to_sdk(ctx), + validator: ctx.get(&self.validator), + amount: self.amount, + source: self.source.map(|x| ctx.get(&x)), + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } } - impl Args for Unbond { + impl Args for Unbond { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let validator = VALIDATOR.parse(matches); let amount = AMOUNT.parse(matches); let source = SOURCE_OPT.parse(matches); + let tx_code_path = PathBuf::from(TX_UNBOND_WASM); Self { tx, validator, amount, source, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(VALIDATOR.def().about("Validator address.")) .arg( AMOUNT @@ -2386,32 +2453,50 @@ pub mod args { )) } } - #[derive(Clone, Debug)] - pub struct InitProposal { + pub struct InitProposal { /// Common tx arguments - pub tx: Tx, + pub tx: Tx, /// The proposal file path pub proposal_data: PathBuf, /// Flag if proposal should be run offline pub offline: bool, + /// Native token address + pub native_token: C::NativeAddress, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, + } + + impl CliToSdk> for InitProposal { + fn to_sdk(self, ctx: &mut Context) -> InitProposal { + InitProposal:: { + tx: self.tx.to_sdk(ctx), + proposal_data: self.proposal_data, + offline: self.offline, + native_token: ctx.native_token.clone(), + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } } - impl Args for InitProposal { + impl Args for InitProposal { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let proposal_data = DATA_PATH.parse(matches); let offline = PROPOSAL_OFFLINE.parse(matches); + let tx_code_path = PathBuf::from(TX_INIT_PROPOSAL); Self { tx, proposal_data, offline, + native_token: (), + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(DATA_PATH.def().about( "The data path file (json) that describes the proposal.", )) @@ -2424,9 +2509,9 @@ pub mod args { } #[derive(Clone, Debug)] - pub struct VoteProposal { + pub struct VoteProposal { /// Common tx arguments - pub tx: Tx, + pub tx: Tx, /// Proposal id pub proposal_id: Option, /// The vote @@ -2439,9 +2524,26 @@ pub mod args { pub offline: bool, /// The proposal file path pub proposal_data: Option, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, + } + + impl CliToSdk> for VoteProposal { + fn to_sdk(self, ctx: &mut Context) -> VoteProposal { + VoteProposal:: { + tx: self.tx.to_sdk(ctx), + proposal_id: self.proposal_id, + vote: self.vote, + offline: self.offline, + proposal_data: self.proposal_data, + tx_code_path: ctx.read_wasm(self.tx_code_path), + proposal_pgf: self.proposal_pgf, + proposal_eth: self.proposal_eth, + } + } } - impl Args for VoteProposal { + impl Args for VoteProposal { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let proposal_id = PROPOSAL_ID_OPT.parse(matches); @@ -2450,6 +2552,7 @@ pub mod args { let vote = PROPOSAL_VOTE.parse(matches); let offline = PROPOSAL_OFFLINE.parse(matches); let proposal_data = DATA_PATH_OPT.parse(matches); + let tx_code_path = PathBuf::from(TX_VOTE_PROPOSAL); Self { tx, @@ -2459,11 +2562,12 @@ pub mod args { proposal_eth, offline, proposal_data, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg( PROPOSAL_ID_OPT .def() @@ -2518,15 +2622,16 @@ pub mod args { } } - #[derive(Clone, Debug)] - pub struct RevealPk { - /// Common tx arguments - pub tx: Tx, - /// A public key to be revealed on-chain - pub public_key: WalletPublicKey, + impl CliToSdk> for RevealPk { + fn to_sdk(self, ctx: &mut Context) -> RevealPk { + RevealPk:: { + tx: self.tx.to_sdk(ctx), + public_key: ctx.get_cached(&self.public_key), + } + } } - impl Args for RevealPk { + impl Args for RevealPk { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let public_key = PUBLIC_KEY.parse(matches); @@ -2535,20 +2640,21 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(PUBLIC_KEY.def().about("A public key to reveal.")) } } - #[derive(Clone, Debug)] - pub struct QueryProposal { - /// Common query args - pub query: Query, - /// Proposal id - pub proposal_id: Option, + impl CliToSdk> for QueryProposal { + fn to_sdk(self, ctx: &mut Context) -> QueryProposal { + QueryProposal:: { + query: self.query.to_sdk(ctx), + proposal_id: self.proposal_id, + } + } } - impl Args for QueryProposal { + impl Args for QueryProposal { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let proposal_id = PROPOSAL_ID_OPT.parse(matches); @@ -2557,15 +2663,15 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(PROPOSAL_ID_OPT.def().about("The proposal identifier.")) } } #[derive(Clone, Debug)] - pub struct QueryProposalResult { + pub struct QueryProposalResult { /// Common query args - pub query: Query, + pub query: Query, /// Proposal id pub proposal_id: Option, /// Flag if proposal result should be run on offline data @@ -2574,7 +2680,18 @@ pub mod args { pub proposal_folder: Option, } - impl Args for QueryProposalResult { + impl CliToSdk> for QueryProposalResult { + fn to_sdk(self, ctx: &mut Context) -> QueryProposalResult { + QueryProposalResult:: { + query: self.query.to_sdk(ctx), + proposal_id: self.proposal_id, + offline: self.offline, + proposal_folder: self.proposal_folder, + } + } + } + + impl Args for QueryProposalResult { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let proposal_id = PROPOSAL_ID_OPT.parse(matches); @@ -2590,7 +2707,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(PROPOSAL_ID_OPT.def().about("The proposal identifier.")) .arg( PROPOSAL_OFFLINE @@ -2613,13 +2730,20 @@ pub mod args { } } - #[derive(Clone, Debug)] - pub struct QueryProtocolParameters { - /// Common query args - pub query: Query, + impl CliToSdk> + for QueryProtocolParameters + { + fn to_sdk( + self, + ctx: &mut Context, + ) -> QueryProtocolParameters { + QueryProtocolParameters:: { + query: self.query.to_sdk(ctx), + } + } } - impl Args for QueryProtocolParameters { + impl Args for QueryProtocolParameters { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); @@ -2627,36 +2751,37 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() } } - /// Withdraw arguments - #[derive(Clone, Debug)] - pub struct Withdraw { - /// Common tx arguments - pub tx: Tx, - /// Validator address - pub validator: WalletAddress, - /// Source address for withdrawing from delegations. For withdrawing - /// from self-bonds, the validator is also the source - pub source: Option, + impl CliToSdk> for Withdraw { + fn to_sdk(self, ctx: &mut Context) -> Withdraw { + Withdraw:: { + tx: self.tx.to_sdk(ctx), + validator: ctx.get(&self.validator), + source: self.source.map(|x| ctx.get(&x)), + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } } - impl Args for Withdraw { + impl Args for Withdraw { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let validator = VALIDATOR.parse(matches); let source = SOURCE_OPT.parse(matches); + let tx_code_path = PathBuf::from(TX_WITHDRAW_WASM); Self { tx, validator, source, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(VALIDATOR.def().about("Validator address.")) .arg(SOURCE_OPT.def().about( "Source address for withdrawing from delegations. For \ @@ -2666,18 +2791,17 @@ pub mod args { } } - /// Query asset conversions - #[derive(Clone, Debug)] - pub struct QueryConversions { - /// Common query args - pub query: Query, - /// Address of a token - pub token: Option, - /// Epoch of the asset - pub epoch: Option, + impl CliToSdk> for QueryConversions { + fn to_sdk(self, ctx: &mut Context) -> QueryConversions { + QueryConversions:: { + query: self.query.to_sdk(ctx), + token: self.token.map(|x| ctx.get(&x)), + epoch: self.epoch, + } + } } - impl Args for QueryConversions { + impl Args for QueryConversions { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let token = TOKEN_OPT.parse(matches); @@ -2690,7 +2814,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg( EPOCH .def() @@ -2704,22 +2828,19 @@ pub mod args { } } - /// Query token balance(s) - #[derive(Clone, Debug)] - pub struct QueryBalance { - /// Common query args - pub query: Query, - /// Address of an owner - pub owner: Option, - /// Address of a token - pub token: Option, - /// Whether not to convert balances - pub no_conversions: bool, - /// Sub prefix of an account - pub sub_prefix: Option, - } - - impl Args for QueryBalance { + impl CliToSdk> for QueryBalance { + fn to_sdk(self, ctx: &mut Context) -> QueryBalance { + QueryBalance:: { + query: self.query.to_sdk(ctx), + owner: self.owner.map(|x| ctx.get_cached(&x)), + token: self.token.map(|x| ctx.get(&x)), + no_conversions: self.no_conversions, + sub_prefix: self.sub_prefix, + } + } + } + + impl Args for QueryBalance { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let owner = BALANCE_OWNER.parse(matches); @@ -2736,7 +2857,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg( BALANCE_OWNER .def() @@ -2760,18 +2881,17 @@ pub mod args { } } - /// Query historical transfer(s) - #[derive(Clone, Debug)] - pub struct QueryTransfers { - /// Common query args - pub query: Query, - /// Address of an owner - pub owner: Option, - /// Address of a token - pub token: Option, + impl CliToSdk> for QueryTransfers { + fn to_sdk(self, ctx: &mut Context) -> QueryTransfers { + QueryTransfers:: { + query: self.query.to_sdk(ctx), + owner: self.owner.map(|x| ctx.get_cached(&x)), + token: self.token.map(|x| ctx.get(&x)), + } + } } - impl Args for QueryTransfers { + impl Args for QueryTransfers { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let owner = BALANCE_OWNER.parse(matches); @@ -2784,7 +2904,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(BALANCE_OWNER.def().about( "The account address that queried transfers must involve.", )) @@ -2794,18 +2914,17 @@ pub mod args { } } - /// Query PoS bond(s) - #[derive(Clone, Debug)] - pub struct QueryBonds { - /// Common query args - pub query: Query, - /// Address of an owner - pub owner: Option, - /// Address of a validator - pub validator: Option, + impl CliToSdk> for QueryBonds { + fn to_sdk(self, ctx: &mut Context) -> QueryBonds { + QueryBonds:: { + query: self.query.to_sdk(ctx), + owner: self.owner.map(|x| ctx.get(&x)), + validator: self.validator.map(|x| ctx.get(&x)), + } + } } - impl Args for QueryBonds { + impl Args for QueryBonds { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let owner = OWNER_OPT.parse(matches); @@ -2818,7 +2937,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg( OWNER_OPT.def().about( "The owner account address whose bonds to query.", @@ -2832,18 +2951,17 @@ pub mod args { } } - /// Query PoS bonded stake - #[derive(Clone, Debug)] - pub struct QueryBondedStake { - /// Common query args - pub query: Query, - /// Address of a validator - pub validator: Option, - /// Epoch in which to find bonded stake - pub epoch: Option, + impl CliToSdk> for QueryBondedStake { + fn to_sdk(self, ctx: &mut Context) -> QueryBondedStake { + QueryBondedStake:: { + query: self.query.to_sdk(ctx), + validator: self.validator.map(|x| ctx.get(&x)), + epoch: self.epoch, + } + } } - impl Args for QueryBondedStake { + impl Args for QueryBondedStake { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let validator = VALIDATOR_OPT.parse(matches); @@ -2856,7 +2974,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(VALIDATOR_OPT.def().about( "The validator's address whose bonded stake to query.", )) @@ -2867,31 +2985,35 @@ pub mod args { } } - #[derive(Clone, Debug)] - /// Commission rate change args - pub struct TxCommissionRateChange { - /// Common tx arguments - pub tx: Tx, - /// Validator address (should be self) - pub validator: WalletAddress, - /// Value to which the tx changes the commission rate - pub rate: Decimal, + impl CliToSdk> + for TxCommissionRateChange + { + fn to_sdk(self, ctx: &mut Context) -> TxCommissionRateChange { + TxCommissionRateChange:: { + tx: self.tx.to_sdk(ctx), + validator: ctx.get(&self.validator), + rate: self.rate, + tx_code_path: ctx.read_wasm(self.tx_code_path), + } + } } - impl Args for TxCommissionRateChange { + impl Args for TxCommissionRateChange { fn parse(matches: &ArgMatches) -> Self { let tx = Tx::parse(matches); let validator = VALIDATOR.parse(matches); let rate = COMMISSION_RATE.parse(matches); + let tx_code_path = PathBuf::from(TX_CHANGE_COMMISSION_WASM); Self { tx, validator, rate, + tx_code_path, } } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(VALIDATOR.def().about( "The validator's address whose commission rate to change.", )) @@ -2903,18 +3025,17 @@ pub mod args { } } - /// Query PoS commission rate - #[derive(Clone, Debug)] - pub struct QueryCommissionRate { - /// Common query args - pub query: Query, - /// Address of a validator - pub validator: WalletAddress, - /// Epoch in which to find commission rate - pub epoch: Option, + impl CliToSdk> for QueryCommissionRate { + fn to_sdk(self, ctx: &mut Context) -> QueryCommissionRate { + QueryCommissionRate:: { + query: self.query.to_sdk(ctx), + validator: ctx.get(&self.validator), + epoch: self.epoch, + } + } } - impl Args for QueryCommissionRate { + impl Args for QueryCommissionRate { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let validator = VALIDATOR.parse(matches); @@ -2927,7 +3048,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(VALIDATOR.def().about( "The validator's address whose commission rate to query.", )) @@ -2938,16 +3059,16 @@ pub mod args { } } - /// Query PoS slashes - #[derive(Clone, Debug)] - pub struct QuerySlashes { - /// Common query args - pub query: Query, - /// Address of a validator - pub validator: Option, + impl CliToSdk> for QuerySlashes { + fn to_sdk(self, ctx: &mut Context) -> QuerySlashes { + QuerySlashes:: { + query: self.query.to_sdk(ctx), + validator: self.validator.map(|x| ctx.get(&x)), + } + } } - impl Args for QuerySlashes { + impl Args for QuerySlashes { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let validator = VALIDATOR_OPT.parse(matches); @@ -2955,7 +3076,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::().arg( + app.add_args::>().arg( VALIDATOR_OPT .def() .about("The validator's address whose slashes to query."), @@ -2963,16 +3084,7 @@ pub mod args { } } - /// Query PoS delegations - #[derive(Clone, Debug)] - pub struct QueryDelegations { - /// Common query args - pub query: Query, - /// Address of an owner - pub owner: WalletAddress, - } - - impl Args for QueryDelegations { + impl Args for QueryDelegations { fn parse(matches: &ArgMatches) -> Self { let query = Query::parse(matches); let owner = OWNER.parse(matches); @@ -2980,7 +3092,7 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::().arg( + app.add_args::>().arg( OWNER.def().about( "The address of the owner of the delegations to find.", ), @@ -2988,16 +3100,25 @@ pub mod args { } } - /// Query the raw bytes of given storage key - #[derive(Clone, Debug)] - pub struct QueryRawBytes { - /// The storage key to query - pub storage_key: storage::Key, - /// Common query args - pub query: Query, + impl CliToSdk> for QueryDelegations { + fn to_sdk(self, ctx: &mut Context) -> QueryDelegations { + QueryDelegations:: { + query: self.query.to_sdk(ctx), + owner: ctx.get(&self.owner), + } + } + } + + impl CliToSdk> for QueryRawBytes { + fn to_sdk(self, ctx: &mut Context) -> QueryRawBytes { + QueryRawBytes:: { + query: self.query.to_sdk(ctx), + storage_key: self.storage_key, + } + } } - impl Args for QueryRawBytes { + impl Args for QueryRawBytes { fn parse(matches: &ArgMatches) -> Self { let storage_key = STORAGE_KEY.parse(matches); let query = Query::parse(matches); @@ -3005,41 +3126,51 @@ pub mod args { } fn def(app: App) -> App { - app.add_args::() + app.add_args::>() .arg(STORAGE_KEY.def().about("Storage key")) } } - /// Common transaction arguments - #[derive(Clone, Debug)] - pub struct Tx { - /// Simulate applying the transaction - pub dry_run: bool, - /// Dump the transaction bytes - pub dump_tx: bool, - /// Submit the transaction even if it doesn't pass client checks - pub force: bool, - /// Do not wait for the transaction to be added to the blockchain - pub broadcast_only: bool, - /// The address of the ledger node as host:port - pub ledger_address: TendermintAddress, - /// If any new account is initialized by the tx, use the given alias to - /// save it in the wallet. - pub initialized_account_alias: Option, - /// The amount being payed to include the transaction - pub fee_amount: token::Amount, - /// The token in which the fee is being paid - pub fee_token: WalletAddress, - /// The max amount of gas used to process tx - pub gas_limit: GasLimit, - /// The optional expiration of the transaction - pub expiration: Option, - /// Sign the tx with the key for the given alias from your wallet - pub signing_key: Option, - /// Sign the tx with the keypair of the public key of the given address - pub signer: Option, - } - - impl Args for Tx { + + /// The concrete types being used in the CLI + #[derive(Clone, Debug)] + pub struct CliTypes; + + impl NamadaTypes for CliTypes { + type Address = WalletAddress; + type BalanceOwner = WalletBalanceOwner; + type Data = PathBuf; + type Keypair = WalletKeypair; + type NativeAddress = (); + type PublicKey = WalletPublicKey; + type TendermintAddress = TendermintAddress; + type TransferSource = WalletTransferSource; + type TransferTarget = WalletTransferTarget; + type ViewingKey = WalletViewingKey; + } + + impl CliToSdk> for Tx { + fn to_sdk(self, ctx: &mut Context) -> Tx { + Tx:: { + dry_run: self.dry_run, + dump_tx: self.dump_tx, + force: self.force, + broadcast_only: self.broadcast_only, + ledger_address: (), + initialized_account_alias: self.initialized_account_alias, + fee_amount: self.fee_amount, + fee_token: ctx.get(&self.fee_token), + gas_limit: self.gas_limit, + signing_key: self.signing_key.map(|x| ctx.get_cached(&x)), + signer: self.signer.map(|x| ctx.get(&x)), + tx_code_path: ctx.read_wasm(self.tx_code_path), + password: self.password, + expiration: self.expiration, + chain_id: self.chain_id, + } + } + } + + impl Args for Tx { fn def(app: App) -> App { app.arg( DRY_RUN_TX @@ -3114,9 +3245,11 @@ pub mod args { let fee_token = GAS_TOKEN.parse(matches); let gas_limit = GAS_LIMIT.parse(matches).into(); let expiration = EXPIRATION_OPT.parse(matches); - let signing_key = SIGNING_KEY_OPT.parse(matches); let signer = SIGNER.parse(matches); + let tx_code_path = PathBuf::from(TX_REVEAL_PK); + let chain_id = CHAIN_ID_OPT.parse(matches); + let password = None; Self { dry_run, dump_tx, @@ -3130,18 +3263,20 @@ pub mod args { expiration, signing_key, signer, + tx_code_path, + password, + chain_id, } } } - /// Common query arguments - #[derive(Clone, Debug)] - pub struct Query { - /// The address of the ledger node as host:port - pub ledger_address: TendermintAddress, + impl CliToSdk> for Query { + fn to_sdk(self, _ctx: &mut Context) -> Query { + Query:: { ledger_address: () } + } } - impl Args for Query { + impl Args for Query { fn def(app: App) -> App { app.arg( LEDGER_ADDRESS_DEFAULT @@ -3158,17 +3293,6 @@ pub mod args { } } - /// MASP add key or address arguments - #[derive(Clone, Debug)] - pub struct MaspAddrKeyAdd { - /// Key alias - pub alias: String, - /// Any MASP value - pub value: MaspValue, - /// Don't encrypt the keypair - pub unsafe_dont_encrypt: bool, - } - impl Args for MaspAddrKeyAdd { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS.parse(matches); @@ -3199,15 +3323,6 @@ pub mod args { } } - /// MASP generate spending key arguments - #[derive(Clone, Debug)] - pub struct MaspSpendKeyGen { - /// Key alias - pub alias: String, - /// Don't encrypt the keypair - pub unsafe_dont_encrypt: bool, - } - impl Args for MaspSpendKeyGen { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS.parse(matches); @@ -3231,18 +3346,17 @@ pub mod args { } } - /// MASP generate payment address arguments - #[derive(Clone, Debug)] - pub struct MaspPayAddrGen { - /// Key alias - pub alias: String, - /// Viewing key - pub viewing_key: WalletViewingKey, - /// Pin - pub pin: bool, + impl CliToSdk> for MaspPayAddrGen { + fn to_sdk(self, ctx: &mut Context) -> MaspPayAddrGen { + MaspPayAddrGen:: { + alias: self.alias, + viewing_key: ctx.get_cached(&self.viewing_key), + pin: self.pin, + } + } } - impl Args for MaspPayAddrGen { + impl Args for MaspPayAddrGen { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS.parse(matches); let viewing_key = VIEWING_KEY.parse(matches); @@ -3268,17 +3382,6 @@ pub mod args { } } - /// Wallet generate key and implicit address arguments - #[derive(Clone, Debug)] - pub struct KeyAndAddressGen { - /// Scheme type - pub scheme: SchemeType, - /// Key alias - pub alias: Option, - /// Don't encrypt the keypair - pub unsafe_dont_encrypt: bool, - } - impl Args for KeyAndAddressGen { fn parse(matches: &ArgMatches) -> Self { let scheme = SCHEME.parse(matches); @@ -3308,15 +3411,6 @@ pub mod args { } } - /// Wallet key lookup arguments - #[derive(Clone, Debug)] - pub struct KeyFind { - pub public_key: Option, - pub alias: Option, - pub value: Option, - pub unsafe_show_secret: bool, - } - impl Args for KeyFind { fn parse(matches: &ArgMatches) -> Self { let public_key = RAW_PUBLIC_KEY_OPT.parse(matches); @@ -3358,13 +3452,6 @@ pub mod args { } } - /// Wallet find shielded address or key arguments - #[derive(Clone, Debug)] - pub struct AddrKeyFind { - pub alias: String, - pub unsafe_show_secret: bool, - } - impl Args for AddrKeyFind { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS.parse(matches); @@ -3385,13 +3472,6 @@ pub mod args { } } - /// Wallet list shielded keys arguments - #[derive(Clone, Debug)] - pub struct MaspKeysList { - pub decrypt: bool, - pub unsafe_show_secret: bool, - } - impl Args for MaspKeysList { fn parse(matches: &ArgMatches) -> Self { let decrypt = DECRYPT.parse(matches); @@ -3412,13 +3492,6 @@ pub mod args { } } - /// Wallet list keys arguments - #[derive(Clone, Debug)] - pub struct KeyList { - pub decrypt: bool, - pub unsafe_show_secret: bool, - } - impl Args for KeyList { fn parse(matches: &ArgMatches) -> Self { let decrypt = DECRYPT.parse(matches); @@ -3439,12 +3512,6 @@ pub mod args { } } - /// Wallet key export arguments - #[derive(Clone, Debug)] - pub struct KeyExport { - pub alias: String, - } - impl Args for KeyExport { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS.parse(matches); @@ -3461,13 +3528,6 @@ pub mod args { } } - /// Wallet address lookup arguments - #[derive(Clone, Debug)] - pub struct AddressOrAliasFind { - pub alias: Option, - pub address: Option
, - } - impl Args for AddressOrAliasFind { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS_OPT.parse(matches); @@ -3494,13 +3554,6 @@ pub mod args { } } - /// Wallet address add arguments - #[derive(Clone, Debug)] - pub struct AddressAdd { - pub alias: String, - pub address: Address, - } - impl Args for AddressAdd { fn parse(matches: &ArgMatches) -> Self { let alias = ALIAS.parse(matches); diff --git a/apps/src/lib/cli/context.rs b/apps/src/lib/cli/context.rs index dd3b5304e5..42c1bb6c94 100644 --- a/apps/src/lib/cli/context.rs +++ b/apps/src/lib/cli/context.rs @@ -7,17 +7,20 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; use color_eyre::eyre::Result; +use namada::ledger::masp::ShieldedContext; +use namada::ledger::wallet::store::AddressVpType; +use namada::ledger::wallet::Wallet; use namada::types::address::Address; use namada::types::chain::ChainId; use namada::types::key::*; use namada::types::masp::*; use super::args; -use crate::client::tx::ShieldedContext; +use crate::client::tx::CLIShieldedUtils; use crate::config::genesis::genesis_config; use crate::config::global::GlobalConfig; use crate::config::{self, Config}; -use crate::wallet::{AddressVpType, Wallet}; +use crate::wallet::CliWalletUtils; use crate::wasm_loader; /// Env. var to set chain ID @@ -67,13 +70,13 @@ pub struct Context { /// Global arguments pub global_args: args::Global, /// The wallet - pub wallet: Wallet, + pub wallet: Wallet, /// The global configuration pub global_config: GlobalConfig, /// The ledger configuration for a specific chain ID pub config: Config, /// The context fr shielded operations - pub shielded: ShieldedContext, + pub shielded: ShieldedContext, /// Native token's address pub native_token: Address, } @@ -99,8 +102,10 @@ impl Context { let native_token = genesis.native_token; let default_genesis = genesis_config::open_genesis_config(genesis_file_path)?; - let wallet = - Wallet::load_or_new_from_genesis(&chain_dir, default_genesis); + let wallet = crate::wallet::load_or_new_from_genesis( + &chain_dir, + default_genesis, + ); // If the WASM dir specified, put it in the config match global_args.wasm_dir.as_ref() { @@ -119,7 +124,7 @@ impl Context { wallet, global_config, config, - shielded: ShieldedContext::new(chain_dir), + shielded: CLIShieldedUtils::new(chain_dir), native_token, }) } @@ -349,7 +354,7 @@ impl ArgFromMutContext for common::SecretKey { FromStr::from_str(raw).or_else(|_parse_err| { // Or it can be an alias ctx.wallet - .find_key(raw) + .find_key(raw, None) .map_err(|_find_err| format!("Unknown key {}", raw)) }) } @@ -366,13 +371,13 @@ impl ArgFromMutContext for common::PublicKey { // Or it can be a public key hash in hex string FromStr::from_str(raw) .map(|pkh: PublicKeyHash| { - let key = ctx.wallet.find_key_by_pkh(&pkh).unwrap(); + let key = ctx.wallet.find_key_by_pkh(&pkh, None).unwrap(); key.ref_to() }) // Or it can be an alias that may be found in the wallet .or_else(|_parse_err| { ctx.wallet - .find_key(raw) + .find_key(raw, None) .map(|x| x.ref_to()) .map_err(|x| x.to_string()) }) @@ -390,7 +395,7 @@ impl ArgFromMutContext for ExtendedSpendingKey { FromStr::from_str(raw).or_else(|_parse_err| { // Or it is a stored alias of one ctx.wallet - .find_spending_key(raw) + .find_spending_key(raw, None) .map_err(|_find_err| format!("Unknown spending key {}", raw)) }) } diff --git a/apps/src/lib/client/mod.rs b/apps/src/lib/client/mod.rs index 9807ca6a30..57f3c5a043 100644 --- a/apps/src/lib/client/mod.rs +++ b/apps/src/lib/client/mod.rs @@ -1,5 +1,4 @@ pub mod rpc; pub mod signing; -pub mod tendermint_rpc_types; pub mod tx; pub mod utils; diff --git a/apps/src/lib/client/rpc.rs b/apps/src/lib/client/rpc.rs index f5e9fa8c57..109b0ffa2d 100644 --- a/apps/src/lib/client/rpc.rs +++ b/apps/src/lib/client/rpc.rs @@ -1,39 +1,42 @@ //! Client RPC queries use std::cmp::Ordering; -use std::collections::{BTreeMap, HashMap, HashSet}; -use std::convert::TryInto; +use std::collections::{HashMap, HashSet}; use std::fs::File; use std::io::{self, Write}; use std::iter::Iterator; use std::str::FromStr; +use std::time::Duration; use async_std::fs; use async_std::path::PathBuf; use async_std::prelude::*; use borsh::{BorshDeserialize, BorshSerialize}; use data_encoding::HEXLOWER; -use eyre::{eyre, Context as EyreContext}; +use itertools::Either; use masp_primitives::asset_type::AssetType; use masp_primitives::merkle_tree::MerklePath; use masp_primitives::primitives::ViewingKey; use masp_primitives::sapling::Node; use masp_primitives::transaction::components::Amount; use masp_primitives::zip32::ExtendedFullViewingKey; -#[cfg(not(feature = "mainnet"))] -use namada::core::ledger::testnet_pow; use namada::core::types::transaction::governance::ProposalType; use namada::ledger::events::Event; use namada::ledger::governance::parameters::GovParams; use namada::ledger::governance::storage as gov_storage; +use namada::ledger::masp::{ + Conversions, PinnedBalanceError, ShieldedContext, ShieldedUtils, +}; use namada::ledger::native_vp::governance::utils::{self, Votes}; use namada::ledger::parameters::{storage as param_storage, EpochDuration}; use namada::ledger::pos::{ self, BondId, BondsAndUnbondsDetail, CommissionPair, PosParams, Slash, }; -use namada::ledger::queries::{self, RPC}; +use namada::ledger::queries::RPC; +use namada::ledger::rpc::{query_epoch, TxResponse}; use namada::ledger::storage::ConversionState; -use namada::proto::{SignedTxData, Tx}; +use namada::ledger::wallet::{AddressVpType, Wallet}; +use namada::proof_of_stake::types::WeightedValidator; use namada::types::address::{masp, Address}; use namada::types::governance::{ OfflineProposal, OfflineVote, ProposalVote, VotePower, VoteType, @@ -41,279 +44,113 @@ use namada::types::governance::{ use namada::types::hash::Hash; use namada::types::key::*; use namada::types::masp::{BalanceOwner, ExtendedViewingKey, PaymentAddress}; -use namada::types::storage::{ - BlockHeight, BlockResults, Epoch, Key, KeySeg, PrefixValue, TxIndex, -}; -use namada::types::token::{balance_key, Transfer}; -use namada::types::transaction::{ - process_tx, AffineCurve, DecryptedTx, EllipticCurve, PairingEngine, TxType, - WrapperTx, -}; +use namada::types::storage::{BlockHeight, BlockResults, Epoch, Key, KeySeg}; use namada::types::{storage, token}; -use tokio::time::{Duration, Instant}; -use crate::cli::{self, args, Context}; -use crate::client::tendermint_rpc_types::TxResponse; -use crate::client::tx::{ - Conversions, PinnedBalanceError, TransactionDelta, TransferDelta, -}; +use crate::cli::{self, args}; use crate::facade::tendermint::merkle::proof::Proof; -use crate::facade::tendermint_config::net::Address as TendermintAddress; use crate::facade::tendermint_rpc::error::Error as TError; -use crate::facade::tendermint_rpc::query::Query; -use crate::facade::tendermint_rpc::{ - Client, HttpClient, Order, SubscriptionClient, WebSocketClient, -}; +use crate::wallet::CliWalletUtils; /// Query the status of a given transaction. /// /// If a response is not delivered until `deadline`, we exit the cli with an /// error. -pub async fn query_tx_status( - status: TxEventQuery<'_>, - address: TendermintAddress, - deadline: Instant, +pub async fn query_tx_status( + client: &C, + status: namada::ledger::rpc::TxEventQuery<'_>, + deadline: Duration, ) -> Event { - const ONE_SECOND: Duration = Duration::from_secs(1); - // sleep for the duration of `backoff`, - // and update the underlying value - async fn sleep_update(query: TxEventQuery<'_>, backoff: &mut Duration) { - tracing::debug!( - ?query, - duration = ?backoff, - "Retrying tx status query after timeout", - ); - // simple linear backoff - if an event is not available, - // increase the backoff duration by one second - tokio::time::sleep(*backoff).await; - *backoff += ONE_SECOND; - } - tokio::time::timeout_at(deadline, async move { - let client = HttpClient::new(address).unwrap(); - let mut backoff = ONE_SECOND; - - loop { - tracing::debug!(query = ?status, "Querying tx status"); - let maybe_event = match query_tx_events(&client, status).await { - Ok(response) => response, - Err(err) => { - tracing::debug!(%err, "ABCI query failed"); - sleep_update(status, &mut backoff).await; - continue; - } - }; - if let Some(e) = maybe_event { - break Ok(e); - } - sleep_update(status, &mut backoff).await; - } - }) - .await - .map_err(|_| { - eprintln!("Transaction status query deadline of {deadline:?} exceeded"); - }) - .and_then(|result| result) - .unwrap_or_else(|_| cli::safe_exit(1)) + namada::ledger::rpc::query_tx_status(client, status, deadline).await } /// Query and print the epoch of the last committed block -pub async fn query_and_print_epoch(args: args::Query) -> Epoch { - let client = HttpClient::new(args.ledger_address).unwrap(); - let epoch = unwrap_client_response(RPC.shell().epoch(&client).await); +pub async fn query_and_print_epoch< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, +) -> Epoch { + let epoch = namada::ledger::rpc::query_epoch(client).await; println!("Last committed epoch: {}", epoch); epoch } -/// Query the epoch of the last committed block -pub async fn query_epoch(client: &HttpClient) -> Epoch { - unwrap_client_response(RPC.shell().epoch(client).await) -} - /// Query the last committed block -pub async fn query_block( - args: args::Query, +pub async fn query_block( + client: &C, ) -> crate::facade::tendermint_rpc::endpoint::block::Response { - let client = HttpClient::new(args.ledger_address).unwrap(); - let response = client.latest_block().await.unwrap(); - println!( - "Last committed block ID: {}, height: {}, time: {}", - response.block_id, - response.block.header.height, - response.block.header.time - ); - response + namada::ledger::rpc::query_block(client).await } /// Query the results of the last committed block -pub async fn query_results(args: args::Query) -> Vec { - let client = HttpClient::new(args.ledger_address).unwrap(); - unwrap_client_response(RPC.shell().read_results(&client).await) -} - -/// Obtain the known effects of all accepted shielded and transparent -/// transactions. If an owner is specified, then restrict the set to only -/// transactions crediting/debiting the given owner. If token is specified, then -/// restrict set to only transactions involving the given token. -pub async fn query_tx_deltas( - ctx: &mut Context, - ledger_address: TendermintAddress, - query_owner: &Option, - query_token: &Option
, -) -> BTreeMap<(BlockHeight, TxIndex), (Epoch, TransferDelta, TransactionDelta)> -{ - const TXS_PER_PAGE: u8 = 100; - // Connect to the Tendermint server holding the transactions - let client = HttpClient::new(ledger_address.clone()).unwrap(); - // Build up the context that will be queried for transactions - let _ = ctx.shielded.load(); - let vks = ctx.wallet.get_viewing_keys(); - let fvks: Vec<_> = vks - .values() - .map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk) - .collect(); - ctx.shielded.fetch(&ledger_address, &[], &fvks).await; - // Save the update state so that future fetches can be short-circuited - let _ = ctx.shielded.save(); - // Required for filtering out rejected transactions from Tendermint - // responses - let block_results = query_results(args::Query { ledger_address }).await; - let mut transfers = ctx.shielded.get_tx_deltas().clone(); - // Construct the set of addresses relevant to user's query - let relevant_addrs = match &query_owner { - Some(BalanceOwner::Address(owner)) => vec![owner.clone()], - // MASP objects are dealt with outside of tx_search - Some(BalanceOwner::FullViewingKey(_viewing_key)) => vec![], - Some(BalanceOwner::PaymentAddress(_owner)) => vec![], - // Unspecified owner means all known addresses are considered relevant - None => ctx.wallet.get_addresses().into_values().collect(), - }; - // Find all transactions to or from the relevant address set - for addr in relevant_addrs { - for prop in ["transfer.source", "transfer.target"] { - // Query transactions involving the current address - let mut tx_query = Query::eq(prop, addr.encode()); - // Elaborate the query if requested by the user - if let Some(token) = &query_token { - tx_query = tx_query.and_eq("transfer.token", token.encode()); - } - for page in 1.. { - let txs = &client - .tx_search( - tx_query.clone(), - true, - page, - TXS_PER_PAGE, - Order::Ascending, - ) - .await - .expect("Unable to query for transactions") - .txs; - for response_tx in txs { - let height = BlockHeight(response_tx.height.value()); - let idx = TxIndex(response_tx.index); - // Only process yet unprocessed transactions which have been - // accepted by node VPs - let should_process = !transfers - .contains_key(&(height, idx)) - && block_results[u64::from(height) as usize] - .is_accepted(idx.0 as usize); - if !should_process { - continue; - } - let tx = Tx::try_from(response_tx.tx.as_ref()) - .expect("Ill-formed Tx"); - let mut wrapper = None; - let mut transfer = None; - extract_payload(tx, &mut wrapper, &mut transfer); - // Epoch data is not needed for transparent transactions - let epoch = Epoch::default(); - if let Some(transfer) = transfer { - // Skip MASP addresses as they are already handled by - // ShieldedContext - if transfer.source == masp() - || transfer.target == masp() - { - continue; - } - // Describe how a Transfer simply subtracts from one - // account and adds the same to another - let mut delta = TransferDelta::default(); - let tfer_delta = Amount::from_nonnegative( - transfer.token.clone(), - u64::from(transfer.amount), - ) - .expect("invalid value for amount"); - delta.insert( - transfer.source, - Amount::zero() - &tfer_delta, - ); - delta.insert(transfer.target, tfer_delta); - // No shielded accounts are affected by this Transfer - transfers.insert( - (height, idx), - (epoch, delta, TransactionDelta::new()), - ); - } - } - // An incomplete page signifies no more transactions - if (txs.len() as u8) < TXS_PER_PAGE { - break; - } - } - } - } - transfers +pub async fn query_results( + client: &C, + _args: args::Query, +) -> Vec { + unwrap_client_response::>( + RPC.shell().read_results(client).await, + ) } /// Query the specified accepted transfers from the ledger -pub async fn query_transfers(mut ctx: Context, args: args::QueryTransfers) { - let query_token = args.token.as_ref().map(|x| ctx.get(x)); - let query_owner = args.owner.as_ref().map(|x| ctx.get_cached(x)); +pub async fn query_transfers< + C: namada::ledger::queries::Client + Sync, + U: ShieldedUtils, +>( + client: &C, + wallet: &mut Wallet, + shielded: &mut ShieldedContext, + args: args::QueryTransfers, +) { + let query_token = args.token; + let query_owner = args.owner.map_or_else( + || Either::Right(wallet.get_addresses().into_values().collect()), + Either::Left, + ); + let _ = shielded.load(); // Obtain the effects of all shielded and transparent transactions - let transfers = query_tx_deltas( - &mut ctx, - args.query.ledger_address.clone(), - &query_owner, - &query_token, - ) - .await; - let vks = ctx.wallet.get_viewing_keys(); + let transfers = shielded + .query_tx_deltas( + client, + &query_owner, + &query_token, + &wallet.get_viewing_keys(), + ) + .await; + // To facilitate lookups of human-readable token names + let vks = wallet.get_viewing_keys(); // To enable ExtendedFullViewingKeys to be displayed instead of ViewingKeys let fvk_map: HashMap<_, _> = vks .values() .map(|fvk| (ExtendedFullViewingKey::from(*fvk).fvk.vk, fvk)) .collect(); - // Connect to the Tendermint server holding the transactions - let client = HttpClient::new(args.query.ledger_address.clone()).unwrap(); // Now display historical shielded and transparent transactions for ((height, idx), (epoch, tfer_delta, tx_delta)) in transfers { // Check if this transfer pertains to the supplied owner let mut relevant = match &query_owner { - Some(BalanceOwner::FullViewingKey(fvk)) => tx_delta + Either::Left(BalanceOwner::FullViewingKey(fvk)) => tx_delta .contains_key(&ExtendedFullViewingKey::from(*fvk).fvk.vk), - Some(BalanceOwner::Address(owner)) => { + Either::Left(BalanceOwner::Address(owner)) => { tfer_delta.contains_key(owner) } - Some(BalanceOwner::PaymentAddress(_owner)) => false, - None => true, + Either::Left(BalanceOwner::PaymentAddress(_owner)) => false, + Either::Right(_) => true, }; // Realize and decode the shielded changes to enable relevance check let mut shielded_accounts = HashMap::new(); for (acc, amt) in tx_delta { // Realize the rewards that would have been attained upon the // transaction's reception - let amt = ctx - .shielded + let amt = shielded .compute_exchanged_amount( - client.clone(), + client, amt, epoch, Conversions::new(), ) .await .0; - let dec = - ctx.shielded.decode_amount(client.clone(), amt, epoch).await; + let dec = shielded.decode_amount(client, amt, epoch).await; shielded_accounts.insert(acc, dec); } // Check if this transfer pertains to the supplied token @@ -334,7 +171,7 @@ pub async fn query_transfers(mut ctx: Context, args: args::QueryTransfers) { if account != masp() { print!(" {}:", account); for (addr, val) in amt.components() { - let token_alias = lookup_alias(&ctx, addr); + let token_alias = lookup_alias(wallet, addr); let sign = match val.cmp(&0) { Ordering::Greater => "+", Ordering::Less => "-", @@ -356,7 +193,7 @@ pub async fn query_transfers(mut ctx: Context, args: args::QueryTransfers) { if fvk_map.contains_key(&account) { print!(" {}:", fvk_map[&account]); for (addr, val) in amt.components() { - let token_alias = lookup_alias(&ctx, addr); + let token_alias = lookup_alias(wallet, addr); let sign = match val.cmp(&0) { Ordering::Greater => "+", Ordering::Less => "-", @@ -375,51 +212,14 @@ pub async fn query_transfers(mut ctx: Context, args: args::QueryTransfers) { } } -/// Extract the payload from the given Tx object -fn extract_payload( - tx: Tx, - wrapper: &mut Option, - transfer: &mut Option, -) { - match process_tx(tx) { - Ok(TxType::Wrapper(wrapper_tx)) => { - let privkey = ::G2Affine::prime_subgroup_generator(); - extract_payload( - Tx::from(match wrapper_tx.decrypt(privkey) { - Ok(tx) => DecryptedTx::Decrypted { - tx, - #[cfg(not(feature = "mainnet"))] - has_valid_pow: false, - }, - _ => DecryptedTx::Undecryptable(wrapper_tx.clone()), - }), - wrapper, - transfer, - ); - *wrapper = Some(wrapper_tx); - } - Ok(TxType::Decrypted(DecryptedTx::Decrypted { - tx, - #[cfg(not(feature = "mainnet"))] - has_valid_pow: _, - })) => { - let empty_vec = vec![]; - let tx_data = tx.data.as_ref().unwrap_or(&empty_vec); - let _ = SignedTxData::try_from_slice(tx_data).map(|signed| { - Transfer::try_from_slice(&signed.data.unwrap()[..]) - .map(|tfer| *transfer = Some(tfer)) - }); - } - _ => {} - } -} - /// Query the raw bytes of given storage key -pub async fn query_raw_bytes(_ctx: Context, args: args::QueryRawBytes) { - let client = HttpClient::new(args.query.ledger_address).unwrap(); - let response = unwrap_client_response( +pub async fn query_raw_bytes( + client: &C, + args: args::QueryRawBytes, +) { + let response = unwrap_client_response::( RPC.shell() - .storage_value(&client, None, None, false, &args.storage_key) + .storage_value(client, None, None, false, &args.storage_key) .await, ); if !response.data.is_empty() { @@ -430,41 +230,50 @@ pub async fn query_raw_bytes(_ctx: Context, args: args::QueryRawBytes) { } /// Query token balance(s) -pub async fn query_balance(mut ctx: Context, args: args::QueryBalance) { +pub async fn query_balance< + C: namada::ledger::queries::Client + Sync, + U: ShieldedUtils, +>( + client: &C, + wallet: &mut Wallet, + shielded: &mut ShieldedContext, + args: args::QueryBalance, +) { // Query the balances of shielded or transparent account types depending on // the CLI arguments - match args.owner.as_ref().map(|x| ctx.get_cached(x)) { + match &args.owner { Some(BalanceOwner::FullViewingKey(_viewing_key)) => { - query_shielded_balance(&mut ctx, args).await + query_shielded_balance(client, wallet, shielded, args).await } Some(BalanceOwner::Address(_owner)) => { - query_transparent_balance(&mut ctx, args).await + query_transparent_balance(client, wallet, args).await } Some(BalanceOwner::PaymentAddress(_owner)) => { - query_pinned_balance(&mut ctx, args).await + query_pinned_balance(client, wallet, shielded, args).await } None => { // Print pinned balance - query_pinned_balance(&mut ctx, args.clone()).await; + query_pinned_balance(client, wallet, shielded, args.clone()).await; // Print shielded balance - query_shielded_balance(&mut ctx, args.clone()).await; + query_shielded_balance(client, wallet, shielded, args.clone()) + .await; // Then print transparent balance - query_transparent_balance(&mut ctx, args).await; + query_transparent_balance(client, wallet, args).await; } }; } /// Query token balance(s) -pub async fn query_transparent_balance( - ctx: &mut Context, +pub async fn query_transparent_balance< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, + wallet: &mut Wallet, args: args::QueryBalance, ) { - let client = HttpClient::new(args.query.ledger_address).unwrap(); - let tokens = ctx.tokens(); + let tokens = wallet.get_addresses_with_vp_type(AddressVpType::Token); match (args.token, args.owner) { (Some(token), Some(owner)) => { - let token = ctx.get(&token); - let owner = ctx.get_cached(&owner); let key = match &args.sub_prefix { Some(sub_prefix) => { let sub_prefix = Key::parse(sub_prefix).unwrap(); @@ -477,8 +286,8 @@ pub async fn query_transparent_balance( } None => token::balance_key(&token, &owner.address().unwrap()), }; - let token_alias = lookup_alias(ctx, &token); - match query_storage_value::(&client, &key).await { + let token_alias = lookup_alias(wallet, &token); + match query_storage_value::(client, &key).await { Some(balance) => match &args.sub_prefix { Some(sub_prefix) => { println!( @@ -494,15 +303,14 @@ pub async fn query_transparent_balance( } } (None, Some(owner)) => { - let owner = ctx.get_cached(&owner); for token in tokens { let prefix = token.to_db_key().into(); let balances = - query_storage_prefix::(&client, &prefix) + query_storage_prefix::(client, &prefix) .await; if let Some(balances) = balances { print_balances( - ctx, + wallet, balances, &token, owner.address().as_ref(), @@ -511,21 +319,21 @@ pub async fn query_transparent_balance( } } (Some(token), None) => { - let token = ctx.get(&token); let prefix = token.to_db_key().into(); let balances = - query_storage_prefix::(&client, &prefix).await; + query_storage_prefix::(client, &prefix).await; if let Some(balances) = balances { - print_balances(ctx, balances, &token, None); + print_balances(wallet, balances, &token, None); } } (None, None) => { for token in tokens { let key = token::balance_prefix(&token); let balances = - query_storage_prefix::(&client, &key).await; + query_storage_prefix::(client, &key) + .await; if let Some(balances) = balances { - print_balances(ctx, balances, &token, None); + print_balances(wallet, balances, &token, None); } } } @@ -533,45 +341,42 @@ pub async fn query_transparent_balance( } /// Query the token pinned balance(s) -pub async fn query_pinned_balance(ctx: &mut Context, args: args::QueryBalance) { +pub async fn query_pinned_balance< + C: namada::ledger::queries::Client + Sync, + U: ShieldedUtils, +>( + client: &C, + wallet: &mut Wallet, + shielded: &mut ShieldedContext, + args: args::QueryBalance, +) { // Map addresses to token names - let tokens = ctx.tokens(); - let owners = if let Some(pa) = args - .owner - .and_then(|x| ctx.get_cached(&x).payment_address()) + let tokens = wallet.get_addresses_with_vp_type(AddressVpType::Token); + let owners = if let Some(pa) = args.owner.and_then(|x| x.payment_address()) { vec![pa] } else { - ctx.wallet + wallet .get_payment_addrs() .into_values() .filter(PaymentAddress::is_pinned) .collect() }; // Get the viewing keys with which to try note decryptions - let viewing_keys: Vec = ctx - .wallet + let viewing_keys: Vec = wallet .get_viewing_keys() .values() .map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk) .collect(); - // Build up the context that will be queried for asset decodings - let _ = ctx.shielded.load(); - // Establish connection with which to do exchange rate queries - let client = HttpClient::new(args.query.ledger_address.clone()).unwrap(); + let _ = shielded.load(); // Print the token balances by payment address for owner in owners { let mut balance = Err(PinnedBalanceError::InvalidViewingKey); // Find the viewing key that can recognize payments the current payment // address for vk in &viewing_keys { - balance = ctx - .shielded - .compute_exchanged_pinned_balance( - &args.query.ledger_address, - owner, - vk, - ) + balance = shielded + .compute_exchanged_pinned_balance(client, owner, vk) .await; if balance != Err(PinnedBalanceError::InvalidViewingKey) { break; @@ -592,13 +397,8 @@ pub async fn query_pinned_balance(ctx: &mut Context, args: args::QueryBalance) { }; let vk = ExtendedFullViewingKey::from(fvk).fvk.vk; // Use the given viewing key to decrypt pinned transaction data - balance = ctx - .shielded - .compute_exchanged_pinned_balance( - &args.query.ledger_address, - owner, - &vk, - ) + balance = shielded + .compute_exchanged_pinned_balance(client, owner, &vk) .await } // Now print out the received quantities according to CLI arguments @@ -611,11 +411,10 @@ pub async fn query_pinned_balance(ctx: &mut Context, args: args::QueryBalance) { println!("Payment address {} has not yet been consumed.", owner) } (Ok((balance, epoch)), Some(token)) => { - let token = ctx.get(token); // Extract and print only the specified token from the total let (_asset_type, balance) = value_by_address(&balance, token.clone(), epoch); - let token_alias = lookup_alias(ctx, &token); + let token_alias = lookup_alias(wallet, token); if balance == 0 { println!( "Payment address {} was consumed during epoch {}. \ @@ -634,10 +433,8 @@ pub async fn query_pinned_balance(ctx: &mut Context, args: args::QueryBalance) { (Ok((balance, epoch)), None) => { let mut found_any = false; // Print balances by human-readable token names - let balance = ctx - .shielded - .decode_amount(client.clone(), balance, epoch) - .await; + let balance = + shielded.decode_amount(client, balance, epoch).await; for (addr, value) in balance.components() { let asset_value = token::Amount::from(*value as u64); if !found_any { @@ -670,7 +467,7 @@ pub async fn query_pinned_balance(ctx: &mut Context, args: args::QueryBalance) { } fn print_balances( - ctx: &Context, + wallet: &Wallet, balances: impl Iterator, token: &Address, target: Option<&Address>, @@ -678,7 +475,7 @@ fn print_balances( let stdout = io::stdout(); let mut w = stdout.lock(); - let token_alias = lookup_alias(ctx, token); + let token_alias = lookup_alias(wallet, token); writeln!(w, "Token {}", token_alias).unwrap(); let print_num = balances @@ -690,7 +487,7 @@ fn print_balances( "with {}: {}, owned by {}", sub_prefix, balance, - lookup_alias(ctx, owner) + lookup_alias(wallet, owner) ), )), None => token::is_any_token_balance_key(&key).map(|owner| { @@ -699,7 +496,7 @@ fn print_balances( format!( ": {}, owned by {}", balance, - lookup_alias(ctx, owner) + lookup_alias(wallet, owner) ), ) }), @@ -718,7 +515,7 @@ fn print_balances( if print_num == 0 { match target { Some(t) => { - writeln!(w, "No balances owned by {}", lookup_alias(ctx, t)) + writeln!(w, "No balances owned by {}", lookup_alias(wallet, t)) .unwrap() } None => { @@ -729,9 +526,12 @@ fn print_balances( } /// Query Proposals -pub async fn query_proposal(_ctx: Context, args: args::QueryProposal) { - async fn print_proposal( - client: &HttpClient, +pub async fn query_proposal( + client: &C, + args: args::QueryProposal, +) { + async fn print_proposal( + client: &C, id: u64, current_epoch: Epoch, details: bool, @@ -742,25 +542,26 @@ pub async fn query_proposal(_ctx: Context, args: args::QueryProposal) { let proposal_type_key = gov_storage::get_proposal_type_key(id); let author = - query_storage_value::
(client, &author_key).await?; + query_storage_value::(client, &author_key).await?; let start_epoch = - query_storage_value::(client, &start_epoch_key).await?; + query_storage_value::(client, &start_epoch_key).await?; let end_epoch = - query_storage_value::(client, &end_epoch_key).await?; + query_storage_value::(client, &end_epoch_key).await?; let proposal_type = - query_storage_value::(client, &proposal_type_key) + query_storage_value::(client, &proposal_type_key) .await?; if details { let content_key = gov_storage::get_content_key(id); let grace_epoch_key = gov_storage::get_grace_epoch_key(id); - let content = query_storage_value::>( + let content = query_storage_value::>( client, &content_key, ) .await?; let grace_epoch = - query_storage_value::(client, &grace_epoch_key).await?; + query_storage_value::(client, &grace_epoch_key) + .await?; println!("Proposal: {}", id); println!("{:4}Type: {}", "", proposal_type); @@ -825,11 +626,10 @@ pub async fn query_proposal(_ctx: Context, args: args::QueryProposal) { Some(()) } - let client = HttpClient::new(args.query.ledger_address.clone()).unwrap(); - let current_epoch = query_and_print_epoch(args.query.clone()).await; + let current_epoch = query_and_print_epoch(client).await; match args.proposal_id { Some(id) => { - if print_proposal(&client, id, current_epoch, true) + if print_proposal::(client, id, current_epoch, true) .await .is_none() { @@ -839,12 +639,12 @@ pub async fn query_proposal(_ctx: Context, args: args::QueryProposal) { None => { let last_proposal_id_key = gov_storage::get_counter_key(); let last_proposal_id = - query_storage_value::(&client, &last_proposal_id_key) + query_storage_value::(client, &last_proposal_id_key) .await .unwrap(); for id in 0..last_proposal_id { - if print_proposal(&client, id, current_epoch, false) + if print_proposal::(client, id, current_epoch, false) .await .is_none() { @@ -873,40 +673,38 @@ pub fn value_by_address( } /// Query token shielded balance(s) -pub async fn query_shielded_balance( - ctx: &mut Context, +pub async fn query_shielded_balance< + C: namada::ledger::queries::Client + Sync, + U: ShieldedUtils, +>( + client: &C, + wallet: &mut Wallet, + shielded: &mut ShieldedContext, args: args::QueryBalance, ) { // Used to control whether balances for all keys or a specific key are // printed - let owner = args - .owner - .and_then(|x| ctx.get_cached(&x).full_viewing_key()); + let owner = args.owner.and_then(|x| x.full_viewing_key()); // Used to control whether conversions are automatically performed let no_conversions = args.no_conversions; // Viewing keys are used to query shielded balances. If a spending key is // provided, then convert to a viewing key first. let viewing_keys = match owner { Some(viewing_key) => vec![viewing_key], - None => ctx.wallet.get_viewing_keys().values().copied().collect(), + None => wallet.get_viewing_keys().values().copied().collect(), }; - // Build up the context that will be queried for balances - let _ = ctx.shielded.load(); + let _ = shielded.load(); let fvks: Vec<_> = viewing_keys .iter() .map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk) .collect(); - ctx.shielded - .fetch(&args.query.ledger_address, &[], &fvks) - .await; + shielded.fetch(client, &[], &fvks).await; // Save the update state so that future fetches can be short-circuited - let _ = ctx.shielded.save(); + let _ = shielded.save(); // The epoch is required to identify timestamped tokens - let epoch = query_and_print_epoch(args.query.clone()).await; - // Establish connection with which to do exchange rate queries - let client = HttpClient::new(args.query.ledger_address.clone()).unwrap(); + let epoch = query_and_print_epoch(client).await; // Map addresses to token names - let tokens = ctx.tokens(); + let tokens = wallet.get_addresses_with_vp_type(AddressVpType::Token); match (args.token, owner.is_some()) { // Here the user wants to know the balance for a specific token (Some(token), true) => { @@ -914,21 +712,17 @@ pub async fn query_shielded_balance( let viewing_key = ExtendedFullViewingKey::from(viewing_keys[0]).fvk.vk; let balance: Amount = if no_conversions { - ctx.shielded + shielded .compute_shielded_balance(&viewing_key) .expect("context should contain viewing key") } else { - ctx.shielded - .compute_exchanged_balance( - client.clone(), - &viewing_key, - epoch, - ) + shielded + .compute_exchanged_balance(client, &viewing_key, epoch) .await .expect("context should contain viewing key") }; // Compute the unique asset identifier from the token address - let token = ctx.get(&token); + let token = token; let asset_type = AssetType::new( (token.clone(), epoch.0) .try_to_vec() @@ -936,7 +730,7 @@ pub async fn query_shielded_balance( .as_ref(), ) .unwrap(); - let token_alias = lookup_alias(ctx, &token); + let token_alias = lookup_alias(wallet, &token); if balance[&asset_type] == 0 { println!( "No shielded {} balance found for given key", @@ -956,16 +750,12 @@ pub async fn query_shielded_balance( // Query the multi-asset balance at the given spending key let viewing_key = ExtendedFullViewingKey::from(fvk).fvk.vk; let balance = if no_conversions { - ctx.shielded + shielded .compute_shielded_balance(&viewing_key) .expect("context should contain viewing key") } else { - ctx.shielded - .compute_exchanged_balance( - client.clone(), - &viewing_key, - epoch, - ) + shielded + .compute_exchanged_balance(client, &viewing_key, epoch) .await .expect("context should contain viewing key") }; @@ -982,10 +772,8 @@ pub async fn query_shielded_balance( // Print non-zero balances whose asset types can be decoded for (asset_type, balances) in balances { // Decode the asset type - let decoded = ctx - .shielded - .decode_asset_type(client.clone(), asset_type) - .await; + let decoded = + shielded.decode_asset_type(client, asset_type).await; match decoded { Some((addr, asset_epoch)) if asset_epoch == epoch => { // Only assets with the current timestamp count @@ -1017,7 +805,7 @@ pub async fn query_shielded_balance( // Print zero balances for remaining assets for token in tokens { if !read_tokens.contains(&token) { - let token_alias = lookup_alias(ctx, &token); + let token_alias = lookup_alias(wallet, &token); println!("Shielded Token {}:", token_alias); println!( "No shielded {} balance found for any wallet key", @@ -1030,7 +818,7 @@ pub async fn query_shielded_balance( // users (Some(token), false) => { // Compute the unique asset identifier from the token address - let token = ctx.get(&token); + let token = token; let asset_type = AssetType::new( (token.clone(), epoch.0) .try_to_vec() @@ -1038,23 +826,19 @@ pub async fn query_shielded_balance( .as_ref(), ) .unwrap(); - let token_alias = lookup_alias(ctx, &token); + let token_alias = lookup_alias(wallet, &token); println!("Shielded Token {}:", token_alias); let mut found_any = false; for fvk in viewing_keys { // Query the multi-asset balance at the given spending key let viewing_key = ExtendedFullViewingKey::from(fvk).fvk.vk; let balance = if no_conversions { - ctx.shielded + shielded .compute_shielded_balance(&viewing_key) .expect("context should contain viewing key") } else { - ctx.shielded - .compute_exchanged_balance( - client.clone(), - &viewing_key, - epoch, - ) + shielded + .compute_exchanged_balance(client, &viewing_key, epoch) .await .expect("context should contain viewing key") }; @@ -1079,45 +863,35 @@ pub async fn query_shielded_balance( ExtendedFullViewingKey::from(viewing_keys[0]).fvk.vk; let balance; if no_conversions { - balance = ctx - .shielded + balance = shielded .compute_shielded_balance(&viewing_key) .expect("context should contain viewing key"); // Print balances by human-readable token names - let decoded_balance = ctx - .shielded - .decode_all_amounts(client.clone(), balance) - .await; - print_decoded_balance_with_epoch(ctx, decoded_balance); + let decoded_balance = + shielded.decode_all_amounts(client, balance).await; + print_decoded_balance_with_epoch(wallet, decoded_balance); } else { - balance = ctx - .shielded - .compute_exchanged_balance( - client.clone(), - &viewing_key, - epoch, - ) + balance = shielded + .compute_exchanged_balance(client, &viewing_key, epoch) .await .expect("context should contain viewing key"); // Print balances by human-readable token names - let decoded_balance = ctx - .shielded - .decode_amount(client.clone(), balance, epoch) - .await; - print_decoded_balance(ctx, decoded_balance); + let decoded_balance = + shielded.decode_amount(client, balance, epoch).await; + print_decoded_balance(wallet, decoded_balance); } } } } pub fn print_decoded_balance( - ctx: &mut Context, + wallet: &mut Wallet, decoded_balance: Amount
, ) { let mut found_any = false; for (addr, value) in decoded_balance.components() { let asset_value = token::Amount::from(*value as u64); - println!("{} : {}", lookup_alias(ctx, addr), asset_value); + println!("{} : {}", lookup_alias(wallet, addr), asset_value); found_any = true; } if !found_any { @@ -1126,10 +900,10 @@ pub fn print_decoded_balance( } pub fn print_decoded_balance_with_epoch( - ctx: &mut Context, + wallet: &mut Wallet, decoded_balance: Amount<(Address, Epoch)>, ) { - let tokens = ctx.tokens(); + let tokens = wallet.get_addresses_with_vp_type(AddressVpType::Token); let mut found_any = false; for ((addr, epoch), value) in decoded_balance.components() { let asset_value = token::Amount::from(*value as u64); @@ -1147,46 +921,45 @@ pub fn print_decoded_balance_with_epoch( } /// Query token amount of owner. -pub async fn get_token_balance( - client: &HttpClient, +pub async fn get_token_balance( + client: &C, token: &Address, owner: &Address, ) -> Option { - let balance_key = balance_key(token, owner); - query_storage_value(client, &balance_key).await + namada::ledger::rpc::get_token_balance(client, token, owner).await } -pub async fn query_proposal_result( - _ctx: Context, +pub async fn query_proposal_result< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, args: args::QueryProposalResult, ) { - let client = HttpClient::new(args.query.ledger_address.clone()).unwrap(); - let current_epoch = query_and_print_epoch(args.query.clone()).await; + let current_epoch = query_epoch(client).await; match args.proposal_id { Some(id) => { let end_epoch_key = gov_storage::get_voting_end_epoch_key(id); let end_epoch = - query_storage_value::(&client, &end_epoch_key).await; + query_storage_value::(client, &end_epoch_key).await; match end_epoch { Some(end_epoch) => { if current_epoch > end_epoch { let votes = - get_proposal_votes(&client, end_epoch, id).await; + get_proposal_votes(client, end_epoch, id).await; let proposal_type_key = gov_storage::get_proposal_type_key(id); - let proposal_type = - query_storage_value::( - &client, - &proposal_type_key, - ) - .await - .expect( - "Could not read proposal type from storage", - ); + let proposal_type = query_storage_value::< + C, + ProposalType, + >( + client, &proposal_type_key + ) + .await + .expect("Could not read proposal type from storage"); let total_stake = - get_total_staked_tokens(&client, end_epoch) + get_total_staked_tokens(client, end_epoch) .await .into(); println!("Proposal: {}", id); @@ -1273,12 +1046,10 @@ pub async fn query_proposal_result( "JSON was not well-formatted for proposal.", ); - let public_key = get_public_key( - &proposal.address, - args.query.ledger_address.clone(), - ) - .await - .expect("Public key should exist."); + let public_key = + get_public_key(client, &proposal.address) + .await + .expect("Public key should exist."); if !proposal.check_signature(&public_key) { eprintln!("Bad proposal signature."); @@ -1286,13 +1057,13 @@ pub async fn query_proposal_result( } let votes = get_proposal_offline_votes( - &client, + client, proposal.clone(), files, ) .await; let total_stake = get_total_staked_tokens( - &client, + client, proposal.tally_epoch, ) .await @@ -1328,18 +1099,18 @@ pub async fn query_proposal_result( } } -pub async fn query_protocol_parameters( - _ctx: Context, - args: args::QueryProtocolParameters, +pub async fn query_protocol_parameters< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, + _args: args::QueryProtocolParameters, ) { - let client = HttpClient::new(args.query.ledger_address).unwrap(); - - let gov_parameters = get_governance_parameters(&client).await; + let gov_parameters = get_governance_parameters(client).await; println!("Governance Parameters\n {:4}", gov_parameters); println!("Protocol parameters"); let key = param_storage::get_epoch_duration_storage_key(); - let epoch_duration = query_storage_value::(&client, &key) + let epoch_duration = query_storage_value::(client, &key) .await .expect("Parameter should be definied."); println!( @@ -1352,26 +1123,26 @@ pub async fn query_protocol_parameters( ); let key = param_storage::get_max_expected_time_per_block_key(); - let max_block_duration = query_storage_value::(&client, &key) + let max_block_duration = query_storage_value::(client, &key) .await .expect("Parameter should be defined."); println!("{:4}Max. block duration: {}", "", max_block_duration); let key = param_storage::get_tx_whitelist_storage_key(); - let vp_whitelist = query_storage_value::>(&client, &key) + let vp_whitelist = query_storage_value::>(client, &key) .await .expect("Parameter should be defined."); println!("{:4}VP whitelist: {:?}", "", vp_whitelist); let key = param_storage::get_tx_whitelist_storage_key(); - let tx_whitelist = query_storage_value::>(&client, &key) + let tx_whitelist = query_storage_value::>(client, &key) .await .expect("Parameter should be defined."); println!("{:4}Transactions whitelist: {:?}", "", tx_whitelist); println!("PoS parameters"); let key = pos::params_key(); - let pos_params = query_storage_value::(&client, &key) + let pos_params = query_storage_value::(client, &key) .await .expect("Parameter should be defined."); println!( @@ -1399,23 +1170,25 @@ pub async fn query_protocol_parameters( println!("{:4}Votes per token: {}", "", pos_params.tm_votes_per_token); } -pub async fn query_bond( - client: &HttpClient, +pub async fn query_bond( + client: &C, source: &Address, validator: &Address, epoch: Option, ) -> token::Amount { - unwrap_client_response( + unwrap_client_response::( RPC.vp().pos().bond(client, source, validator, &epoch).await, ) } -pub async fn query_unbond_with_slashing( - client: &HttpClient, +pub async fn query_unbond_with_slashing< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, source: &Address, validator: &Address, ) -> HashMap<(Epoch, Epoch), token::Amount> { - unwrap_client_response( + unwrap_client_response::>( RPC.vp() .pos() .unbond_with_slashing(client, source, validator) @@ -1423,8 +1196,10 @@ pub async fn query_unbond_with_slashing( ) } -pub async fn query_and_print_unbonds( - client: &HttpClient, +pub async fn query_and_print_unbonds< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, source: &Address, validator: &Address, ) { @@ -1456,13 +1231,15 @@ pub async fn query_and_print_unbonds( } } -pub async fn query_withdrawable_tokens( - client: &HttpClient, +pub async fn query_withdrawable_tokens< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, bond_source: &Address, validator: &Address, epoch: Option, ) -> token::Amount { - unwrap_client_response( + unwrap_client_response::( RPC.vp() .pos() .withdrawable_tokens(client, bond_source, validator, &epoch) @@ -1471,24 +1248,24 @@ pub async fn query_withdrawable_tokens( } /// Query PoS bond(s) and unbond(s) -pub async fn query_bonds( - ctx: Context, +pub async fn query_bonds( + client: &C, + _wallet: &mut Wallet, args: args::QueryBonds, ) -> std::io::Result<()> { - let _epoch = query_and_print_epoch(args.query.clone()).await; - let client = HttpClient::new(args.query.ledger_address).unwrap(); + let _epoch = query_and_print_epoch(client).await; - let source = args.owner.map(|owner| ctx.get(&owner)); - let validator = args.validator.map(|val| ctx.get(&val)); + let source = args.owner; + let validator = args.validator; let stdout = io::stdout(); let mut w = stdout.lock(); let bonds_and_unbonds: pos::types::BondsAndUnbondsDetails = - unwrap_client_response( + unwrap_client_response::( RPC.vp() .pos() - .bonds_and_unbonds(&client, &source, &validator) + .bonds_and_unbonds(client, &source, &validator) .await, ); let mut bonds_total: token::Amount = 0.into(); @@ -1580,18 +1357,20 @@ pub async fn query_bonds( } /// Query PoS bonded stake -pub async fn query_bonded_stake(ctx: Context, args: args::QueryBondedStake) { +pub async fn query_bonded_stake( + client: &C, + args: args::QueryBondedStake, +) { let epoch = match args.epoch { Some(epoch) => epoch, - None => query_and_print_epoch(args.query.clone()).await, + None => query_and_print_epoch(client).await, }; - let client = HttpClient::new(args.query.ledger_address).unwrap(); match args.validator { Some(validator) => { - let validator = ctx.get(&validator); + let validator = validator; // Find bonded stake for the given validator - let stake = get_validator_stake(&client, epoch, &validator).await; + let stake = get_validator_stake(client, epoch, &validator).await; match stake { Some(stake) => { // TODO: show if it's in consensus set, below capacity, or @@ -1604,18 +1383,20 @@ pub async fn query_bonded_stake(ctx: Context, args: args::QueryBondedStake) { } } None => { - let consensus = unwrap_client_response( - RPC.vp() - .pos() - .consensus_validator_set(&client, &Some(epoch)) - .await, - ); - let below_capacity = unwrap_client_response( - RPC.vp() - .pos() - .below_capacity_validator_set(&client, &Some(epoch)) - .await, - ); + let consensus = + unwrap_client_response::>( + RPC.vp() + .pos() + .consensus_validator_set(client, &Some(epoch)) + .await, + ); + let below_capacity = + unwrap_client_response::>( + RPC.vp() + .pos() + .below_capacity_validator_set(client, &Some(epoch)) + .await, + ); // Iterate all validators let stdout = io::stdout(); @@ -1641,18 +1422,20 @@ pub async fn query_bonded_stake(ctx: Context, args: args::QueryBondedStake) { } } - let total_staked_tokens = get_total_staked_tokens(&client, epoch).await; + let total_staked_tokens = get_total_staked_tokens(client, epoch).await; println!("Total bonded stake: {total_staked_tokens}"); } /// Query and return validator's commission rate and max commission rate change /// per epoch -pub async fn query_commission_rate( - client: &HttpClient, +pub async fn query_commission_rate< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, validator: &Address, epoch: Option, ) -> Option { - unwrap_client_response( + unwrap_client_response::>( RPC.vp() .pos() .validator_commission(client, validator, &epoch) @@ -1661,15 +1444,17 @@ pub async fn query_commission_rate( } /// Query PoS validator's commission rate information -pub async fn query_and_print_commission_rate( - ctx: Context, +pub async fn query_and_print_commission_rate< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, + _wallet: &mut Wallet, args: args::QueryCommissionRate, ) { - let client = HttpClient::new(args.query.ledger_address.clone()).unwrap(); - let validator = ctx.get(&args.validator); + let validator = args.validator; let info: Option = - query_commission_rate(&client, &validator, args.epoch).await; + query_commission_rate(client, &validator, args.epoch).await; match info { Some(CommissionPair { commission_rate: rate, @@ -1693,19 +1478,22 @@ pub async fn query_and_print_commission_rate( } /// Query PoS slashes -pub async fn query_slashes(ctx: Context, args: args::QuerySlashes) { - let client = HttpClient::new(args.query.ledger_address).unwrap(); +pub async fn query_slashes( + client: &C, + _wallet: &mut Wallet, + args: args::QuerySlashes, +) { let params_key = pos::params_key(); - let params = query_storage_value::(&client, ¶ms_key) + let params = query_storage_value::(client, ¶ms_key) .await .expect("Parameter should be defined."); match args.validator { Some(validator) => { - let validator = ctx.get(&validator); + let validator = validator; // Find slashes for the given validator - let slashes: Vec = unwrap_client_response( - RPC.vp().pos().validator_slashes(&client, &validator).await, + let slashes: Vec = unwrap_client_response::>( + RPC.vp().pos().validator_slashes(client, &validator).await, ); if !slashes.is_empty() { let stdout = io::stdout(); @@ -1726,7 +1514,9 @@ pub async fn query_slashes(ctx: Context, args: args::QuerySlashes) { } None => { let all_slashes: HashMap> = - unwrap_client_response(RPC.vp().pos().slashes(&client).await); + unwrap_client_response::>>( + RPC.vp().pos().slashes(client).await, + ); if !all_slashes.is_empty() { let stdout = io::stdout(); @@ -1753,11 +1543,14 @@ pub async fn query_slashes(ctx: Context, args: args::QuerySlashes) { } } -pub async fn query_delegations(ctx: Context, args: args::QueryDelegations) { - let client = HttpClient::new(args.query.ledger_address).unwrap(); - let owner = ctx.get(&args.owner); - let delegations = unwrap_client_response( - RPC.vp().pos().delegation_validators(&client, &owner).await, +pub async fn query_delegations( + client: &C, + _wallet: &mut Wallet, + args: args::QueryDelegations, +) { + let owner = args.owner; + let delegations = unwrap_client_response::>( + RPC.vp().pos().delegation_validators(client, &owner).await, ); if delegations.is_empty() { println!("No delegations found"); @@ -1770,116 +1563,75 @@ pub async fn query_delegations(ctx: Context, args: args::QueryDelegations) { } /// Dry run a transaction -pub async fn dry_run_tx(ledger_address: &TendermintAddress, tx_bytes: Vec) { - let client = HttpClient::new(ledger_address.clone()).unwrap(); - let (data, height, prove) = (Some(tx_bytes), None, false); - let result = unwrap_client_response( - RPC.shell().dry_run_tx(&client, data, height, prove).await, - ) - .data; - println!("Dry-run result: {}", result); +pub async fn dry_run_tx( + client: &C, + tx_bytes: Vec, +) { + println!( + "Dry-run result: {}", + namada::ledger::rpc::dry_run_tx(client, tx_bytes).await + ); } /// Get account's public key stored in its storage sub-space -pub async fn get_public_key( +pub async fn get_public_key( + client: &C, address: &Address, - ledger_address: TendermintAddress, ) -> Option { - let client = HttpClient::new(ledger_address).unwrap(); - let key = pk_key(address); - query_storage_value(&client, &key).await + namada::ledger::rpc::get_public_key(client, address).await } /// Check if the given address is a known validator. -pub async fn is_validator(client: &HttpClient, address: &Address) -> bool { - unwrap_client_response(RPC.vp().pos().is_validator(client, address).await) +pub async fn is_validator( + client: &C, + address: &Address, +) -> bool { + namada::ledger::rpc::is_validator(client, address).await } /// Check if a given address is a known delegator -pub async fn is_delegator(client: &HttpClient, address: &Address) -> bool { - unwrap_client_response( - RPC.vp().pos().is_delegator(client, address, &None).await, - ) +pub async fn is_delegator( + client: &C, + address: &Address, +) -> bool { + namada::ledger::rpc::is_delegator(client, address).await } -/// Check if a given address is a known delegator at a particular epoch -pub async fn is_delegator_at( - client: &HttpClient, +pub async fn is_delegator_at( + client: &C, address: &Address, epoch: Epoch, ) -> bool { - unwrap_client_response( - RPC.vp() - .pos() - .is_delegator(client, address, &Some(epoch)) - .await, - ) + namada::ledger::rpc::is_delegator_at(client, address, epoch).await } /// Check if the address exists on chain. Established address exists if it has a /// stored validity predicate. Implicit and internal addresses always return /// true. -pub async fn known_address( +pub async fn known_address( + client: &C, address: &Address, - ledger_address: TendermintAddress, ) -> bool { - let client = HttpClient::new(ledger_address).unwrap(); - match address { - Address::Established(_) => { - // Established account exists if it has a VP - let key = storage::Key::validity_predicate(address); - query_has_storage_key(&client, &key).await - } - Address::Implicit(_) | Address::Internal(_) => true, - } -} - -#[cfg(not(feature = "mainnet"))] -/// Check if the given address is a testnet faucet account address. -pub async fn is_faucet_account( - address: &Address, - ledger_address: TendermintAddress, -) -> bool { - let client = HttpClient::new(ledger_address).unwrap(); - unwrap_client_response(RPC.vp().is_faucet(&client, address).await) -} - -#[cfg(not(feature = "mainnet"))] -/// Get faucet account address, if any is setup for the network. -pub async fn get_faucet_address( - ledger_address: TendermintAddress, -) -> Option
{ - let client = HttpClient::new(ledger_address).unwrap(); - unwrap_client_response(RPC.vp().get_faucet_address(&client).await) -} - -#[cfg(not(feature = "mainnet"))] -/// Obtain a PoW challenge for a withdrawal from a testnet faucet account, if -/// any is setup for the network. -pub async fn get_testnet_pow_challenge( - source: Address, - ledger_address: TendermintAddress, -) -> testnet_pow::Challenge { - let client = HttpClient::new(ledger_address).unwrap(); - unwrap_client_response( - RPC.vp().testnet_pow_challenge(&client, source).await, - ) + namada::ledger::rpc::known_address(client, address).await } /// Query for all conversions. -pub async fn query_conversions(ctx: Context, args: args::QueryConversions) { +pub async fn query_conversions( + client: &C, + wallet: &mut Wallet, + args: args::QueryConversions, +) { // The chosen token type of the conversions - let target_token = args.token.as_ref().map(|x| ctx.get(x)); + let target_token = args.token; // To facilitate human readable token addresses - let tokens = ctx.tokens(); - let client = HttpClient::new(args.query.ledger_address).unwrap(); + let tokens = wallet.get_addresses_with_vp_type(AddressVpType::Token); let masp_addr = masp(); let key_prefix: Key = masp_addr.to_db_key().into(); let state_key = key_prefix .push(&(token::CONVERSION_KEY_PREFIX.to_owned())) .unwrap(); let conv_state = - query_storage_value::(&client, &state_key) + query_storage_value::(client, &state_key) .await .expect("Conversions should be defined"); // Track whether any non-sentinel conversions are found @@ -1928,8 +1680,8 @@ pub async fn query_conversions(ctx: Context, args: args::QueryConversions) { } /// Query a conversion. -pub async fn query_conversion( - client: HttpClient, +pub async fn query_conversion( + client: &C, asset_type: AssetType, ) -> Option<( Address, @@ -1937,289 +1689,98 @@ pub async fn query_conversion( masp_primitives::transaction::components::Amount, MerklePath, )> { - Some(unwrap_client_response( - RPC.shell().read_conversion(&client, &asset_type).await, - )) + namada::ledger::rpc::query_conversion(client, asset_type).await } /// Query a wasm code hash -pub async fn query_wasm_code_hash( +pub async fn query_wasm_code_hash( + client: &C, code_path: impl AsRef, - ledger_address: TendermintAddress, ) -> Option { - let client = HttpClient::new(ledger_address.clone()).unwrap(); - let hash_key = Key::wasm_hash(code_path.as_ref()); - match query_storage_value_bytes(&client, &hash_key, None, false) - .await - .0 - { - Some(hash) => { - Some(Hash::try_from(&hash[..]).expect("Invalid code hash")) - } - None => { - eprintln!( - "The corresponding wasm code of the code path {} doesn't \ - exist on chain.", - code_path.as_ref(), - ); - None - } - } + namada::ledger::rpc::query_wasm_code_hash(client, code_path).await } /// Query a storage value and decode it with [`BorshDeserialize`]. -pub async fn query_storage_value( - client: &HttpClient, +pub async fn query_storage_value( + client: &C, key: &storage::Key, ) -> Option where T: BorshDeserialize, { - // In case `T` is a unit (only thing that encodes to 0 bytes), we have to - // use `storage_has_key` instead of `storage_value`, because `storage_value` - // returns 0 bytes when the key is not found. - let maybe_unit = T::try_from_slice(&[]); - if let Ok(unit) = maybe_unit { - return if unwrap_client_response( - RPC.shell().storage_has_key(client, key).await, - ) { - Some(unit) - } else { - None - }; - } - - let response = unwrap_client_response( - RPC.shell() - .storage_value(client, None, None, false, key) - .await, - ); - if response.data.is_empty() { - return None; - } - T::try_from_slice(&response.data[..]) - .map(Some) - .unwrap_or_else(|err| { - eprintln!("Error decoding the value: {}", err); - cli::safe_exit(1) - }) + namada::ledger::rpc::query_storage_value(client, key).await } /// Query a storage value and the proof without decoding. -pub async fn query_storage_value_bytes( - client: &HttpClient, +pub async fn query_storage_value_bytes< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, key: &storage::Key, height: Option, prove: bool, ) -> (Option>, Option) { - let data = None; - let response = unwrap_client_response( - RPC.shell() - .storage_value(client, data, height, prove, key) - .await, - ); - if response.data.is_empty() { - (None, response.proof) - } else { - (Some(response.data), response.proof) - } + namada::ledger::rpc::query_storage_value_bytes(client, key, height, prove) + .await } /// Query a range of storage values with a matching prefix and decode them with /// [`BorshDeserialize`]. Returns an iterator of the storage keys paired with /// their associated values. -pub async fn query_storage_prefix( - client: &HttpClient, +pub async fn query_storage_prefix< + C: namada::ledger::queries::Client + Sync, + T, +>( + client: &C, key: &storage::Key, ) -> Option> where T: BorshDeserialize, { - let values = unwrap_client_response( - RPC.shell() - .storage_prefix(client, None, None, false, key) - .await, - ); - let decode = - |PrefixValue { key, value }: PrefixValue| match T::try_from_slice( - &value[..], - ) { - Err(err) => { - eprintln!( - "Skipping a value for key {}. Error in decoding: {}", - key, err - ); - None - } - Ok(value) => Some((key, value)), - }; - if values.data.is_empty() { - None - } else { - Some(values.data.into_iter().filter_map(decode)) - } + namada::ledger::rpc::query_storage_prefix(client, key).await } /// Query to check if the given storage key exists. -pub async fn query_has_storage_key( - client: &HttpClient, +pub async fn query_has_storage_key< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, key: &storage::Key, ) -> bool { - unwrap_client_response(RPC.shell().storage_has_key(client, key).await) -} - -/// Represents a query for an event pertaining to the specified transaction -#[derive(Debug, Copy, Clone)] -pub enum TxEventQuery<'a> { - Accepted(&'a str), - Applied(&'a str), -} - -impl<'a> TxEventQuery<'a> { - /// The event type to which this event query pertains - fn event_type(self) -> &'static str { - match self { - TxEventQuery::Accepted(_) => "accepted", - TxEventQuery::Applied(_) => "applied", - } - } - - /// The transaction to which this event query pertains - fn tx_hash(self) -> &'a str { - match self { - TxEventQuery::Accepted(tx_hash) => tx_hash, - TxEventQuery::Applied(tx_hash) => tx_hash, - } - } -} - -/// Transaction event queries are semantically a subset of general queries -impl<'a> From> for Query { - fn from(tx_query: TxEventQuery<'a>) -> Self { - match tx_query { - TxEventQuery::Accepted(tx_hash) => { - Query::default().and_eq("accepted.hash", tx_hash) - } - TxEventQuery::Applied(tx_hash) => { - Query::default().and_eq("applied.hash", tx_hash) - } - } - } + namada::ledger::rpc::query_has_storage_key(client, key).await } /// Call the corresponding `tx_event_query` RPC method, to fetch /// the current status of a transation. -pub async fn query_tx_events( - client: &HttpClient, - tx_event_query: TxEventQuery<'_>, -) -> eyre::Result> { - let tx_hash: Hash = tx_event_query.tx_hash().try_into()?; - match tx_event_query { - TxEventQuery::Accepted(_) => RPC - .shell() - .accepted(client, &tx_hash) - .await - .wrap_err_with(|| { - eyre!("Failed querying whether a transaction was accepted") - }), - TxEventQuery::Applied(_) => RPC - .shell() - .applied(client, &tx_hash) - .await - .wrap_err_with(|| { - eyre!("Error querying whether a transaction was applied") - }), - } +pub async fn query_tx_events( + client: &C, + tx_event_query: namada::ledger::rpc::TxEventQuery<'_>, +) -> std::result::Result< + Option, + ::Error, +> { + namada::ledger::rpc::query_tx_events(client, tx_event_query).await } /// Lookup the full response accompanying the specified transaction event // TODO: maybe remove this in favor of `query_tx_status` -pub async fn query_tx_response( - ledger_address: &TendermintAddress, - tx_query: TxEventQuery<'_>, +pub async fn query_tx_response( + client: &C, + tx_query: namada::ledger::rpc::TxEventQuery<'_>, ) -> Result { - // Connect to the Tendermint server holding the transactions - let (client, driver) = WebSocketClient::new(ledger_address.clone()).await?; - let driver_handle = tokio::spawn(async move { driver.run().await }); - // Find all blocks that apply a transaction with the specified hash - let blocks = &client - .block_search(tx_query.into(), 1, 255, Order::Ascending) - .await - .expect("Unable to query for transaction with given hash") - .blocks; - // Get the block results corresponding to a block to which - // the specified transaction belongs - let block = &blocks - .get(0) - .ok_or_else(|| { - TError::server( - "Unable to find a block applying the given transaction" - .to_string(), - ) - })? - .block; - let response_block_results = client - .block_results(block.header.height) - .await - .expect("Unable to retrieve block containing transaction"); - // Search for the event where the specified transaction is - // applied to the blockchain - let query_event_opt = - response_block_results.end_block_events.and_then(|events| { - events - .iter() - .find(|event| { - event.type_str == tx_query.event_type() - && event.attributes.iter().any(|tag| { - tag.key.as_ref() == "hash" - && tag.value.as_ref() == tx_query.tx_hash() - }) - }) - .cloned() - }); - let query_event = query_event_opt.ok_or_else(|| { - TError::server( - "Unable to find the event corresponding to the specified \ - transaction" - .to_string(), - ) - })?; - // Reformat the event attributes so as to ease value extraction - let event_map: std::collections::HashMap<&str, &str> = query_event - .attributes - .iter() - .map(|tag| (tag.key.as_ref(), tag.value.as_ref())) - .collect(); - // Summarize the transaction results that we were searching for - let result = TxResponse { - info: event_map["info"].to_string(), - log: event_map["log"].to_string(), - height: event_map["height"].to_string(), - hash: event_map["hash"].to_string(), - code: event_map["code"].to_string(), - gas_used: event_map["gas_used"].to_string(), - initialized_accounts: serde_json::from_str( - event_map["initialized_accounts"], - ) - .unwrap_or_default(), - }; - // Signal to the driver to terminate. - client.close()?; - // Await the driver's termination to ensure proper connection closure. - let _ = driver_handle.await.unwrap_or_else(|x| { - eprintln!("{}", x); - cli::safe_exit(1) - }); - Ok(result) + namada::ledger::rpc::query_tx_response(client, tx_query).await } /// Lookup the results of applying the specified transaction to the /// blockchain. -pub async fn query_result(_ctx: Context, args: args::QueryResult) { +pub async fn query_result( + client: &C, + args: args::QueryResult, +) { // First try looking up application event pertaining to given hash. let tx_response = query_tx_response( - &args.query.ledger_address, - TxEventQuery::Applied(&args.tx_hash), + client, + namada::ledger::rpc::TxEventQuery::Applied(&args.tx_hash), ) .await; match tx_response { @@ -2232,8 +1793,8 @@ pub async fn query_result(_ctx: Context, args: args::QueryResult) { Err(err1) => { // If this fails then instead look for an acceptance event. let tx_response = query_tx_response( - &args.query.ledger_address, - TxEventQuery::Accepted(&args.tx_hash), + client, + namada::ledger::rpc::TxEventQuery::Accepted(&args.tx_hash), ) .await; match tx_response { @@ -2251,70 +1812,18 @@ pub async fn query_result(_ctx: Context, args: args::QueryResult) { } } -pub async fn get_proposal_votes( - client: &HttpClient, +pub async fn get_proposal_votes( + client: &C, epoch: Epoch, proposal_id: u64, ) -> Votes { - let validators = get_all_validators(client, epoch).await; - - let vote_prefix_key = - gov_storage::get_proposal_vote_prefix_key(proposal_id); - let vote_iter = - query_storage_prefix::(client, &vote_prefix_key).await; - - let mut yay_validators: HashMap = - HashMap::new(); - let mut delegators: HashMap< - Address, - HashMap, - > = HashMap::new(); - - if let Some(vote_iter) = vote_iter { - for (key, vote) in vote_iter { - let voter_address = gov_storage::get_voter_address(&key) - .expect("Vote key should contain the voting address.") - .clone(); - if vote.is_yay() && validators.contains(&voter_address) { - let amount: VotePower = - get_validator_stake(client, epoch, &voter_address) - .await - .unwrap_or_default() - .into(); - yay_validators.insert(voter_address, (amount, vote)); - } else if !validators.contains(&voter_address) { - let validator_address = - gov_storage::get_vote_delegation_address(&key) - .expect( - "Vote key should contain the delegation address.", - ) - .clone(); - let delegator_token_amount = get_bond_amount_at( - client, - &voter_address, - &validator_address, - epoch, - ) - .await; - if let Some(amount) = delegator_token_amount { - let entry = delegators.entry(voter_address).or_default(); - entry.insert( - validator_address, - (VotePower::from(amount), vote), - ); - } - } - } - } - - Votes { - yay_validators, - delegators, - } + namada::ledger::rpc::get_proposal_votes(client, epoch, proposal_id).await } -pub async fn get_proposal_offline_votes( - client: &HttpClient, +pub async fn get_proposal_offline_votes< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, proposal: OfflineProposal, files: HashSet, ) -> Votes { @@ -2347,7 +1856,7 @@ pub async fn get_proposal_offline_votes( if proposal_vote.vote.is_yay() // && validators.contains(&proposal_vote.address) - && unwrap_client_response( + && unwrap_client_response::( RPC.vp().pos().is_validator(client, &proposal_vote.address).await, ) { @@ -2373,7 +1882,7 @@ pub async fn get_proposal_offline_votes( // TODO: decide whether to do this with `bond_with_slashing` RPC // endpoint or with `bonds_and_unbonds` let bonds_and_unbonds: pos::types::BondsAndUnbondsDetails = - unwrap_client_response( + unwrap_client_response::( RPC.vp() .pos() .bonds_and_unbonds( @@ -2495,52 +2004,44 @@ pub async fn get_proposal_offline_votes( } } -pub async fn get_bond_amount_at( - client: &HttpClient, +pub async fn get_bond_amount_at( + client: &C, delegator: &Address, validator: &Address, epoch: Epoch, ) -> Option { - let (_total, total_active) = unwrap_client_response( - RPC.vp() - .pos() - .bond_with_slashing(client, delegator, validator, &Some(epoch)) - .await, - ); + let (_total, total_active) = + unwrap_client_response::( + RPC.vp() + .pos() + .bond_with_slashing(client, delegator, validator, &Some(epoch)) + .await, + ); Some(total_active) } -pub async fn get_all_validators( - client: &HttpClient, +pub async fn get_all_validators( + client: &C, epoch: Epoch, ) -> HashSet
{ - unwrap_client_response( - RPC.vp() - .pos() - .validator_addresses(client, &Some(epoch)) - .await, - ) + namada::ledger::rpc::get_all_validators(client, epoch).await } -pub async fn get_total_staked_tokens( - client: &HttpClient, +pub async fn get_total_staked_tokens< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, epoch: Epoch, ) -> token::Amount { - unwrap_client_response( - RPC.vp().pos().total_stake(client, &Some(epoch)).await, - ) + namada::ledger::rpc::get_total_staked_tokens(client, epoch).await } -/// Get the total stake of a validator at the given epoch. The total stake is a -/// sum of validator's self-bonds and delegations to their address. -/// Returns `None` when the given address is not a validator address. For a -/// validator with `0` stake, this returns `Ok(token::Amount::default())`. -async fn get_validator_stake( - client: &HttpClient, +async fn get_validator_stake( + client: &C, epoch: Epoch, validator: &Address, ) -> Option { - unwrap_client_response( + unwrap_client_response::>( RPC.vp() .pos() .validator_stake(client, validator, &Some(epoch)) @@ -2548,70 +2049,38 @@ async fn get_validator_stake( ) } -pub async fn get_delegators_delegation( - client: &HttpClient, +pub async fn get_delegators_delegation< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, address: &Address, ) -> HashSet
{ - unwrap_client_response( - RPC.vp().pos().delegation_validators(client, address).await, - ) + namada::ledger::rpc::get_delegators_delegation(client, address).await } -pub async fn get_governance_parameters(client: &HttpClient) -> GovParams { - use namada::types::token::Amount; - let key = gov_storage::get_max_proposal_code_size_key(); - let max_proposal_code_size = query_storage_value::(client, &key) - .await - .expect("Parameter should be definied."); - - let key = gov_storage::get_max_proposal_content_key(); - let max_proposal_content_size = query_storage_value::(client, &key) - .await - .expect("Parameter should be definied."); - - let key = gov_storage::get_min_proposal_fund_key(); - let min_proposal_fund = query_storage_value::(client, &key) - .await - .expect("Parameter should be definied."); - - let key = gov_storage::get_min_proposal_grace_epoch_key(); - let min_proposal_grace_epochs = query_storage_value::(client, &key) - .await - .expect("Parameter should be definied."); - - let key = gov_storage::get_min_proposal_period_key(); - let min_proposal_period = query_storage_value::(client, &key) - .await - .expect("Parameter should be definied."); - - let key = gov_storage::get_max_proposal_period_key(); - let max_proposal_period = query_storage_value::(client, &key) - .await - .expect("Parameter should be definied."); - - GovParams { - min_proposal_fund: u64::from(min_proposal_fund), - max_proposal_code_size, - min_proposal_period, - max_proposal_period, - max_proposal_content_size, - min_proposal_grace_epochs, - } +pub async fn get_governance_parameters< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, +) -> GovParams { + namada::ledger::rpc::get_governance_parameters(client).await } /// Try to find an alias for a given address from the wallet. If not found, /// formats the address into a string. -fn lookup_alias(ctx: &Context, addr: &Address) -> String { - match ctx.wallet.find_alias(addr) { +fn lookup_alias(wallet: &Wallet, addr: &Address) -> String { + match wallet.find_alias(addr) { Some(alias) => format!("{}", alias), None => format!("{}", addr), } } /// A helper to unwrap client's response. Will shut down process on error. -fn unwrap_client_response(response: Result) -> T { - response.unwrap_or_else(|err| { - eprintln!("Error in the query {}", err); +fn unwrap_client_response( + response: Result, +) -> T { + response.unwrap_or_else(|_err| { + eprintln!("Error in the query"); cli::safe_exit(1) }) } diff --git a/apps/src/lib/client/signing.rs b/apps/src/lib/client/signing.rs index cb5f28aee7..eec89b4f80 100644 --- a/apps/src/lib/client/signing.rs +++ b/apps/src/lib/client/signing.rs @@ -1,140 +1,46 @@ //! Helpers for making digital signatures using cryptographic keys from the //! wallet. -use borsh::BorshSerialize; -use namada::ledger::parameters::storage as parameter_storage; -use namada::proof_of_stake::Epoch; +use namada::ledger::rpc::TxBroadcastData; +use namada::ledger::signing::TxSigningKey; +use namada::ledger::tx; +use namada::ledger::wallet::{Wallet, WalletUtils}; use namada::proto::Tx; -use namada::types::address::{Address, ImplicitAddress}; -use namada::types::hash::Hash; +use namada::types::address::Address; use namada::types::key::*; -use namada::types::token; -use namada::types::token::Amount; -use namada::types::transaction::{hash_tx, Fee, WrapperTx, MIN_FEE}; +use namada::types::storage::Epoch; -use super::rpc; -use crate::cli::context::{WalletAddress, WalletKeypair}; -use crate::cli::{self, args, Context}; -use crate::client::tendermint_rpc_types::TxBroadcastData; -use crate::facade::tendermint_config::net::Address as TendermintAddress; -use crate::facade::tendermint_rpc::HttpClient; -use crate::wallet::Wallet; +use crate::cli::args; /// Find the public key for the given address and try to load the keypair /// for it from the wallet. Panics if the key cannot be found or loaded. -pub async fn find_keypair( - wallet: &mut Wallet, +pub async fn find_keypair< + C: namada::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, addr: &Address, - ledger_address: TendermintAddress, -) -> common::SecretKey { - match addr { - Address::Established(_) => { - println!( - "Looking-up public key of {} from the ledger...", - addr.encode() - ); - let public_key = rpc::get_public_key(addr, ledger_address) - .await - .unwrap_or_else(|| { - eprintln!( - "No public key found for the address {}", - addr.encode() - ); - cli::safe_exit(1); - }); - wallet.find_key_by_pk(&public_key).unwrap_or_else(|err| { - eprintln!( - "Unable to load the keypair from the wallet for public \ - key {}. Failed with: {}", - public_key, err - ); - cli::safe_exit(1) - }) - } - Address::Implicit(ImplicitAddress(pkh)) => { - wallet.find_key_by_pkh(pkh).unwrap_or_else(|err| { - eprintln!( - "Unable to load the keypair from the wallet for the \ - implicit address {}. Failed with: {}", - addr.encode(), - err - ); - cli::safe_exit(1) - }) - } - Address::Internal(_) => { - eprintln!( - "Internal address {} doesn't have any signing keys.", - addr - ); - cli::safe_exit(1) - } - } -} - -/// Carries types that can be directly/indirectly used to sign a transaction. -#[allow(clippy::large_enum_variant)] -#[derive(Clone)] -pub enum TxSigningKey { - // Do not sign any transaction - None, - // Obtain the actual keypair from wallet and use that to sign - WalletKeypair(WalletKeypair), - // Obtain the keypair corresponding to given address from wallet and sign - WalletAddress(WalletAddress), - // Directly use the given secret key to sign transactions - SecretKey(common::SecretKey), +) -> Result { + namada::ledger::signing::find_keypair::(client, wallet, addr, None) + .await } /// Given CLI arguments and some defaults, determine the rightful transaction /// signer. Return the given signing key or public key of the given signer if /// possible. If no explicit signer given, use the `default`. If no `default` /// is given, panics. -pub async fn tx_signer( - ctx: &mut Context, +pub async fn tx_signer< + C: namada::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, args: &args::Tx, - mut default: TxSigningKey, -) -> common::SecretKey { - // Override the default signing key source if possible - if let Some(signing_key) = &args.signing_key { - default = TxSigningKey::WalletKeypair(signing_key.clone()); - } else if let Some(signer) = &args.signer { - default = TxSigningKey::WalletAddress(signer.clone()); - } - // Now actually fetch the signing key and apply it - match default { - TxSigningKey::WalletKeypair(signing_key) => { - ctx.get_cached(&signing_key) - } - TxSigningKey::WalletAddress(signer) => { - let signer = ctx.get(&signer); - let signing_key = find_keypair( - &mut ctx.wallet, - &signer, - args.ledger_address.clone(), - ) - .await; - // Check if the signer is implicit account that needs to reveal its - // PK first - if matches!(signer, Address::Implicit(_)) { - let pk: common::PublicKey = signing_key.ref_to(); - super::tx::reveal_pk_if_needed(ctx, &pk, args).await; - } - signing_key - } - TxSigningKey::SecretKey(signing_key) => { - // Check if the signing key needs to reveal its PK first - let pk: common::PublicKey = signing_key.ref_to(); - super::tx::reveal_pk_if_needed(ctx, &pk, args).await; - signing_key - } - TxSigningKey::None => { - panic!( - "All transactions must be signed; please either specify the \ - key or the address from which to look up the signing key." - ); - } - } + default: TxSigningKey, +) -> Result { + namada::ledger::signing::tx_signer::(client, wallet, args, default) + .await } /// Sign a transaction with a given signing key or public key of a given signer. @@ -145,174 +51,48 @@ pub async fn tx_signer( /// hashes needed for monitoring the tx on chain. /// /// If it is a dry run, it is not put in a wrapper, but returned as is. -pub async fn sign_tx( - mut ctx: Context, +pub async fn sign_tx< + C: namada::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, tx: Tx, args: &args::Tx, default: TxSigningKey, #[cfg(not(feature = "mainnet"))] requires_pow: bool, -) -> (Context, TxBroadcastData) { - if args.dump_tx { - dump_tx_helper(&ctx, &tx, "unsigned", None); - } - - let keypair = tx_signer(&mut ctx, args, default).await; - let tx = tx.sign(&keypair); - if args.dump_tx { - dump_tx_helper(&ctx, &tx, "signed", None); - } - - let epoch = rpc::query_and_print_epoch(args::Query { - ledger_address: args.ledger_address.clone(), - }) - .await; - let broadcast_data = if args.dry_run { - TxBroadcastData::DryRun(tx) - } else { - sign_wrapper( - &ctx, - args, - epoch, - tx, - &keypair, - #[cfg(not(feature = "mainnet"))] - requires_pow, - ) - .await - }; - - if args.dump_tx && !args.dry_run { - let (wrapper_tx, wrapper_hash) = match broadcast_data { - TxBroadcastData::DryRun(_) => panic!( - "somehow created a dry run transaction without --dry-run" - ), - TxBroadcastData::Wrapper { - ref tx, - ref wrapper_hash, - decrypted_hash: _, - } => (tx, wrapper_hash), - }; - - dump_tx_helper(&ctx, wrapper_tx, "wrapper", Some(wrapper_hash)); - } - - (ctx, broadcast_data) -} - -pub fn dump_tx_helper( - ctx: &Context, - tx: &Tx, - extension: &str, - precomputed_hash: Option<&String>, -) { - let chain_dir = ctx.config.ledger.chain_dir(); - let hash = match precomputed_hash { - Some(hash) => hash.to_owned(), - None => { - let hash: Hash = tx - .hash() - .as_ref() - .try_into() - .expect("expected hash of dumped tx to be a hash"); - format!("{}", hash) - } - }; - let filename = chain_dir.join(hash).with_extension(extension); - let tx_bytes = tx.to_bytes(); - - std::fs::write(filename, tx_bytes) - .expect("expected to be able to write tx dump file"); +) -> Result { + namada::ledger::signing::sign_tx::( + client, + wallet, + tx, + args, + default, + #[cfg(not(feature = "mainnet"))] + requires_pow, + ) + .await } /// Create a wrapper tx from a normal tx. Get the hash of the /// wrapper and its payload which is needed for monitoring its /// progress on chain. -pub async fn sign_wrapper( - ctx: &Context, +pub async fn sign_wrapper( + client: &C, args: &args::Tx, epoch: Epoch, tx: Tx, keypair: &common::SecretKey, #[cfg(not(feature = "mainnet"))] requires_pow: bool, ) -> TxBroadcastData { - let client = HttpClient::new(args.ledger_address.clone()).unwrap(); - - let fee_amount = if cfg!(feature = "mainnet") { - Amount::whole(MIN_FEE) - } else { - let wrapper_tx_fees_key = parameter_storage::get_wrapper_tx_fees_key(); - rpc::query_storage_value::(&client, &wrapper_tx_fees_key) - .await - .unwrap_or_default() - }; - let fee_token = ctx.get(&args.fee_token); - let source = Address::from(&keypair.ref_to()); - let balance_key = token::balance_key(&fee_token, &source); - let balance = - rpc::query_storage_value::(&client, &balance_key) - .await - .unwrap_or_default(); - if balance < fee_amount { - eprintln!( - "The wrapper transaction source doesn't have enough balance to \ - pay fee {fee_amount}, got {balance}." - ); - if !args.force && cfg!(feature = "mainnet") { - cli::safe_exit(1); - } - } - - #[cfg(not(feature = "mainnet"))] - // A PoW solution can be used to allow zero-fee testnet transactions - let pow_solution: Option = { - // If the address derived from the keypair doesn't have enough balance - // to pay for the fee, allow to find a PoW solution instead. - if requires_pow || balance < fee_amount { - println!( - "The transaction requires the completion of a PoW challenge." - ); - // Obtain a PoW challenge for faucet withdrawal - let challenge = rpc::get_testnet_pow_challenge( - source, - args.ledger_address.clone(), - ) - .await; - - // Solve the solution, this blocks until a solution is found - let solution = challenge.solve(); - Some(solution) - } else { - None - } - }; - - let tx = { - WrapperTx::new( - Fee { - amount: fee_amount, - token: fee_token, - }, - keypair, - epoch, - args.gas_limit.clone(), - tx, - // TODO: Actually use the fetched encryption key - Default::default(), - #[cfg(not(feature = "mainnet"))] - pow_solution, - ) - }; - - // We use this to determine when the wrapper tx makes it on-chain - let wrapper_hash = hash_tx(&tx.try_to_vec().unwrap()).to_string(); - // We use this to determine when the decrypted inner tx makes it - // on-chain - let decrypted_hash = tx.tx_hash.to_string(); - TxBroadcastData::Wrapper { - tx: tx - .sign(keypair, ctx.config.ledger.chain_id.clone(), args.expiration) - .expect("Wrapper tx signing keypair should be correct"), - wrapper_hash, - decrypted_hash, - } + namada::ledger::signing::sign_wrapper( + client, + args, + epoch, + tx, + keypair, + #[cfg(not(feature = "mainnet"))] + requires_pow, + ) + .await } diff --git a/apps/src/lib/client/tendermint_rpc_types.rs b/apps/src/lib/client/tendermint_rpc_types.rs deleted file mode 100644 index 537cca243f..0000000000 --- a/apps/src/lib/client/tendermint_rpc_types.rs +++ /dev/null @@ -1,100 +0,0 @@ -use std::convert::TryFrom; - -use namada::ledger::events::Event; -use namada::proto::Tx; -use namada::types::address::Address; -use serde::Serialize; - -use crate::cli::safe_exit; - -/// Data needed for broadcasting a tx and -/// monitoring its progress on chain -/// -/// Txs may be either a dry run or else -/// they should be encrypted and included -/// in a wrapper. -#[derive(Debug, Clone)] -pub enum TxBroadcastData { - DryRun(Tx), - Wrapper { - tx: Tx, - wrapper_hash: String, - decrypted_hash: String, - }, -} - -/// A parsed event from tendermint relating to a transaction -#[derive(Debug, Serialize)] -pub struct TxResponse { - pub info: String, - pub log: String, - pub height: String, - pub hash: String, - pub code: String, - pub gas_used: String, - pub initialized_accounts: Vec
, -} - -impl TryFrom for TxResponse { - type Error = String; - - fn try_from(event: Event) -> Result { - fn missing_field_err(field: &str) -> String { - format!("Field \"{field}\" not present in event") - } - - let hash = event - .get("hash") - .ok_or_else(|| missing_field_err("hash"))? - .clone(); - let info = event - .get("info") - .ok_or_else(|| missing_field_err("info"))? - .clone(); - let log = event - .get("log") - .ok_or_else(|| missing_field_err("log"))? - .clone(); - let height = event - .get("height") - .ok_or_else(|| missing_field_err("height"))? - .clone(); - let code = event - .get("code") - .ok_or_else(|| missing_field_err("code"))? - .clone(); - let gas_used = event - .get("gas_used") - .ok_or_else(|| missing_field_err("gas_used"))? - .clone(); - let initialized_accounts = event - .get("initialized_accounts") - .map(String::as_str) - // TODO: fix finalize block, to return initialized accounts, - // even when we reject a tx? - .map_or(Ok(vec![]), |initialized_accounts| { - serde_json::from_str(initialized_accounts) - .map_err(|err| format!("JSON decode error: {err}")) - })?; - - Ok(TxResponse { - hash, - info, - log, - height, - code, - gas_used, - initialized_accounts, - }) - } -} - -impl TxResponse { - /// Convert an [`Event`] to a [`TxResponse`], or error out. - pub fn from_event(event: Event) -> Self { - event.try_into().unwrap_or_else(|err| { - eprintln!("Error fetching TxResponse: {err}"); - safe_exit(1); - }) - } -} diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs index 70762443ca..70cdf870ce 100644 --- a/apps/src/lib/client/tx.rs +++ b/apps/src/lib/client/tx.rs @@ -1,244 +1,84 @@ -use std::borrow::Cow; -use std::collections::hash_map::Entry; -use std::collections::{BTreeMap, HashMap, HashSet}; +use std::collections::HashSet; use std::env; use std::fmt::Debug; use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; use std::path::PathBuf; -use std::str::FromStr; +use async_std::io; use async_std::io::prelude::WriteExt; -use async_std::io::{self}; use borsh::{BorshDeserialize, BorshSerialize}; use data_encoding::HEXLOWER_PERMISSIVE; -use itertools::Either::*; -use masp_primitives::asset_type::AssetType; -use masp_primitives::consensus::{BranchId, TestNetwork}; -use masp_primitives::convert::AllowedConversion; -use masp_primitives::ff::PrimeField; -use masp_primitives::group::cofactor::CofactorGroup; -use masp_primitives::keys::FullViewingKey; -use masp_primitives::legacy::TransparentAddress; -use masp_primitives::merkle_tree::{ - CommitmentTree, IncrementalWitness, MerklePath, -}; -use masp_primitives::note_encryption::*; -use masp_primitives::primitives::{Diversifier, Note, ViewingKey}; -use masp_primitives::sapling::Node; -use masp_primitives::transaction::builder::{self, secp256k1, *}; -use masp_primitives::transaction::components::{Amount, OutPoint, TxOut}; -use masp_primitives::transaction::Transaction; -use masp_primitives::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}; use masp_proofs::prover::LocalTxProver; -use namada::ibc::applications::transfer::msgs::transfer::MsgTransfer; -use namada::ibc::core::ics04_channel::timeout::TimeoutHeight; -use namada::ibc::signer::Signer; -use namada::ibc::timestamp::Timestamp as IbcTimestamp; -use namada::ibc::tx_msg::Msg; -use namada::ibc::Height as IbcHeight; -use namada::ibc_proto::cosmos::base::v1beta1::Coin; use namada::ledger::governance::storage as gov_storage; -use namada::ledger::masp; -use namada::ledger::pos::{CommissionPair, PosParams}; +use namada::ledger::rpc::{TxBroadcastData, TxResponse}; +use namada::ledger::signing::TxSigningKey; +use namada::ledger::wallet::{Wallet, WalletUtils}; +use namada::ledger::{masp, tx}; use namada::proto::Tx; -use namada::types::address::{masp, masp_tx_key, Address}; +use namada::types::address::Address; use namada::types::governance::{ OfflineProposal, OfflineVote, Proposal, ProposalVote, VoteType, }; use namada::types::key::*; -use namada::types::masp::{PaymentAddress, TransferTarget}; -use namada::types::storage::{ - BlockHeight, Epoch, Key, KeySeg, TxIndex, RESERVED_ADDRESS_PREFIX, -}; -use namada::types::time::DateTimeUtc; -use namada::types::token::{ - Transfer, HEAD_TX_KEY, PIN_KEY_PREFIX, TX_KEY_PREFIX, -}; +use namada::types::storage::{Epoch, Key}; +use namada::types::token; use namada::types::transaction::governance::{ InitProposalData, ProposalType, VoteProposalData, }; -use namada::types::transaction::{pos, InitAccount, InitValidator, UpdateVp}; -use namada::types::{storage, token}; -use rand_core::{CryptoRng, OsRng, RngCore}; +use namada::types::transaction::InitValidator; use rust_decimal::Decimal; -use sha2::Digest; -use tokio::time::{Duration, Instant}; +use tendermint_rpc::HttpClient; use super::rpc; use crate::cli::context::WalletAddress; use crate::cli::{args, safe_exit, Context}; -use crate::client::rpc::{ - query_conversion, query_epoch, query_storage_value, query_wasm_code_hash, -}; -use crate::client::signing::{find_keypair, sign_tx, tx_signer, TxSigningKey}; -use crate::client::tendermint_rpc_types::{TxBroadcastData, TxResponse}; -use crate::facade::tendermint_config::net::Address as TendermintAddress; +use crate::client::rpc::query_wasm_code_hash; +use crate::client::signing::find_keypair; use crate::facade::tendermint_rpc::endpoint::broadcast::tx_sync::Response; -use crate::facade::tendermint_rpc::error::Error as RpcError; -use crate::facade::tendermint_rpc::{Client, HttpClient}; use crate::node::ledger::tendermint_node; +use crate::wallet::{gen_validator_keys, read_and_confirm_pwd, CliWalletUtils}; -const TX_INIT_ACCOUNT_WASM: &str = "tx_init_account.wasm"; -const TX_INIT_VALIDATOR_WASM: &str = "tx_init_validator.wasm"; -const TX_INIT_PROPOSAL: &str = "tx_init_proposal.wasm"; -const TX_VOTE_PROPOSAL: &str = "tx_vote_proposal.wasm"; -const TX_REVEAL_PK: &str = "tx_reveal_pk.wasm"; -const TX_UPDATE_VP_WASM: &str = "tx_update_vp.wasm"; -const TX_TRANSFER_WASM: &str = "tx_transfer.wasm"; -const TX_IBC_WASM: &str = "tx_ibc.wasm"; -const VP_USER_WASM: &str = "vp_user.wasm"; -const TX_BOND_WASM: &str = "tx_bond.wasm"; -const TX_UNBOND_WASM: &str = "tx_unbond.wasm"; -const TX_WITHDRAW_WASM: &str = "tx_withdraw.wasm"; -const TX_CHANGE_COMMISSION_WASM: &str = "tx_change_validator_commission.wasm"; - -/// Timeout for requests to the `/accepted` and `/applied` -/// ABCI query endpoints. -const ENV_VAR_NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS: &str = - "NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS"; - -/// Default timeout in seconds for requests to the `/accepted` -/// and `/applied` ABCI query endpoints. -const DEFAULT_NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS: u64 = 60; - -pub async fn submit_custom(ctx: Context, args: args::TxCustom) { - let code_path = args.code_path.file_name().unwrap().to_str().unwrap(); - let tx_code_hash = - query_wasm_code_hash(code_path, args.tx.ledger_address.clone()) - .await - .unwrap(); - let data = args.data_path.map(|data_path| { - std::fs::read(data_path).expect("Expected a file at given data path") - }); - let tx = Tx::new( - tx_code_hash.to_vec(), - data, - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - let (ctx, result) = process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::None, - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; - save_initialized_accounts(ctx, &args.tx, result.initialized_accounts()) - .await; +pub async fn submit_custom( + client: &C, + ctx: &mut Context, + mut args: args::TxCustom, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_custom::(client, &mut ctx.wallet, args).await } -pub async fn submit_update_vp(ctx: Context, args: args::TxUpdateVp) { - let addr = ctx.get(&args.addr); - - // Check that the address is established and exists on chain - match &addr { - Address::Established(_) => { - let exists = - rpc::known_address(&addr, args.tx.ledger_address.clone()).await; - if !exists { - eprintln!("The address {} doesn't exist on chain.", addr); - if !args.tx.force { - safe_exit(1) - } - } - } - Address::Implicit(_) => { - eprintln!( - "A validity predicate of an implicit address cannot be \ - directly updated. You can use an established address for \ - this purpose." - ); - if !args.tx.force { - safe_exit(1) - } - } - Address::Internal(_) => { - eprintln!( - "A validity predicate of an internal address cannot be \ - directly updated." - ); - if !args.tx.force { - safe_exit(1) - } - } - } - - let vp_code_path = args.vp_code_path.file_name().unwrap().to_str().unwrap(); - let vp_code_hash = - query_wasm_code_hash(vp_code_path, args.tx.ledger_address.clone()) - .await - .unwrap(); - - let tx_code_hash = - query_wasm_code_hash(TX_UPDATE_VP_WASM, args.tx.ledger_address.clone()) - .await - .unwrap(); - - let data = UpdateVp { addr, vp_code_hash }; - let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); - - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(args.addr), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; +pub async fn submit_update_vp( + client: &C, + ctx: &mut Context, + mut args: args::TxUpdateVp, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_update_vp::(client, &mut ctx.wallet, args).await } -pub async fn submit_init_account(mut ctx: Context, args: args::TxInitAccount) { - let public_key = ctx.get_cached(&args.public_key); - let vp_code_path = match &args.vp_code_path { - Some(path) => path.file_name().unwrap().to_str().unwrap(), - None => VP_USER_WASM, - }; - let vp_code_hash = - query_wasm_code_hash(vp_code_path, args.tx.ledger_address.clone()) - .await - .unwrap(); - let tx_code_hash = query_wasm_code_hash( - TX_INIT_ACCOUNT_WASM, - args.tx.ledger_address.clone(), - ) - .await - .unwrap(); - let data = InitAccount { - public_key, - vp_code_hash, - }; - let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); - - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - let (ctx, result) = process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(args.source), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; - save_initialized_accounts(ctx, &args.tx, result.initialized_accounts()) - .await; +pub async fn submit_init_account( + client: &C, + ctx: &mut Context, + mut args: args::TxInitAccount, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_init_account::(client, &mut ctx.wallet, args).await } -pub async fn submit_init_validator( +pub async fn submit_init_validator< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, mut ctx: Context, args::TxInitValidator { tx: tx_args, @@ -251,8 +91,16 @@ pub async fn submit_init_validator( max_commission_rate_change, validator_vp_code_path, unsafe_dont_encrypt, + tx_code_path: _, }: args::TxInitValidator, ) { + let tx_args = args::Tx { + chain_id: tx_args + .clone() + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())), + ..tx_args.clone() + }; let alias = tx_args .initialized_account_alias .as_ref() @@ -261,20 +109,16 @@ pub async fn submit_init_validator( let validator_key_alias = format!("{}-key", alias); let consensus_key_alias = format!("{}-consensus-key", alias); - let account_key = ctx.get_opt_cached(&account_key).unwrap_or_else(|| { + let account_key = account_key.unwrap_or_else(|| { println!("Generating validator account key..."); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); ctx.wallet - .gen_key( - scheme, - Some(validator_key_alias.clone()), - unsafe_dont_encrypt, - ) + .gen_key(scheme, Some(validator_key_alias.clone()), password) .1 .ref_to() }); - let consensus_key = ctx - .get_opt_cached(&consensus_key) + let consensus_key = consensus_key .map(|key| match key { common::SecretKey::Ed25519(_) => key, common::SecretKey::Secp256k1(_) => { @@ -284,24 +128,25 @@ pub async fn submit_init_validator( }) .unwrap_or_else(|| { println!("Generating consensus key..."); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); ctx.wallet .gen_key( // Note that TM only allows ed25519 for consensus key SchemeType::Ed25519, Some(consensus_key_alias.clone()), - unsafe_dont_encrypt, + password, ) .1 }); - let protocol_key = ctx.get_opt_cached(&protocol_key); + let protocol_key = protocol_key; if protocol_key.is_none() { println!("Generating protocol signing key..."); } // Generate the validator keys let validator_keys = - ctx.wallet.gen_validator_keys(protocol_key, scheme).unwrap(); + gen_validator_keys(&mut ctx.wallet, protocol_key, scheme).unwrap(); let protocol_key = validator_keys.get_protocol_keypair().ref_to(); let dkg_key = validator_keys .dkg_keypair @@ -309,14 +154,9 @@ pub async fn submit_init_validator( .expect("DKG sessions keys should have been created") .public(); - ctx.wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); - - let vp_code_path = match &validator_vp_code_path { - Some(path) => path.file_name().unwrap().to_str().unwrap(), - None => VP_USER_WASM, - }; + let vp_code_path = String::from_utf8(validator_vp_code_path).unwrap(); let validator_vp_code_hash = - query_wasm_code_hash(vp_code_path, tx_args.ledger_address.clone()) + query_wasm_code_hash::(client, vp_code_path) .await .unwrap(); @@ -341,12 +181,10 @@ pub async fn submit_init_validator( safe_exit(1) } } - let tx_code_hash = query_wasm_code_hash( - TX_INIT_VALIDATOR_WASM, - tx_args.ledger_address.clone(), - ) - .await - .unwrap(); + let tx_code_hash = + query_wasm_code_hash(client, args::TX_INIT_VALIDATOR_WASM) + .await + .unwrap(); let data = InitValidator { account_key, @@ -361,10 +199,11 @@ pub async fn submit_init_validator( let tx = Tx::new( tx_code_hash.to_vec(), Some(data), - ctx.config.ledger.chain_id.clone(), + tx_args.chain_id.clone().unwrap(), tx_args.expiration, ); let (mut ctx, result) = process_tx( + client, ctx, &tx_args, tx, @@ -372,11 +211,11 @@ pub async fn submit_init_validator( #[cfg(not(feature = "mainnet"))] false, ) - .await; + .await + .expect("expected process_tx to work"); + if !tx_args.dry_run { - let (validator_address_alias, validator_address) = match &result - .initialized_accounts()[..] - { + let (validator_address_alias, validator_address) = match &result[..] { // There should be 1 account for the validator itself [validator_address] => { let validator_address_alias = match tx_args @@ -421,7 +260,8 @@ pub async fn submit_init_validator( // add validator address and keys to the wallet ctx.wallet .add_validator_data(validator_address, validator_keys); - ctx.wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); + crate::wallet::save(&ctx.wallet) + .unwrap_or_else(|err| eprintln!("{}", err)); let tendermint_home = ctx.config.ledger.tendermint_dir(); tendermint_node::write_validator_key(&tendermint_home, &consensus_key); @@ -443,149 +283,84 @@ pub async fn submit_init_validator( } } -/// Make a ViewingKey that can view notes encrypted by given ExtendedSpendingKey -pub fn to_viewing_key(esk: &ExtendedSpendingKey) -> FullViewingKey { - ExtendedFullViewingKey::from(esk).fvk +/// Shielded context file name +const FILE_NAME: &str = "shielded.dat"; +const TMP_FILE_NAME: &str = "shielded.tmp"; + +#[derive(Debug, BorshSerialize, BorshDeserialize, Clone)] +pub struct CLIShieldedUtils { + #[borsh_skip] + context_dir: PathBuf, } -/// Generate a valid diversifier, i.e. one that has a diversified base. Return -/// also this diversified base. -pub fn find_valid_diversifier( - rng: &mut R, -) -> (Diversifier, masp_primitives::jubjub::SubgroupPoint) { - let mut diversifier; - let g_d; - // Keep generating random diversifiers until one has a diversified base - loop { - let mut d = [0; 11]; - rng.fill_bytes(&mut d); - diversifier = Diversifier(d); - if let Some(val) = diversifier.g_d() { - g_d = val; - break; +impl CLIShieldedUtils { + /// Initialize a shielded transaction context that identifies notes + /// decryptable by any viewing key in the given set + pub fn new(context_dir: PathBuf) -> masp::ShieldedContext { + // Make sure that MASP parameters are downloaded to enable MASP + // transaction building and verification later on + let params_dir = masp::get_params_dir(); + let spend_path = params_dir.join(masp::SPEND_NAME); + let convert_path = params_dir.join(masp::CONVERT_NAME); + let output_path = params_dir.join(masp::OUTPUT_NAME); + if !(spend_path.exists() + && convert_path.exists() + && output_path.exists()) + { + println!("MASP parameters not present, downloading..."); + masp_proofs::download_parameters() + .expect("MASP parameters not present or downloadable"); + println!("MASP parameter download complete, resuming execution..."); + } + // Finally initialize a shielded context with the supplied directory + let utils = Self { context_dir }; + masp::ShieldedContext { + utils, + ..Default::default() } } - (diversifier, g_d) } -/// Determine if using the current note would actually bring us closer to our -/// target -pub fn is_amount_required(src: Amount, dest: Amount, delta: Amount) -> bool { - if delta > Amount::zero() { - let gap = dest - src; - for (asset_type, value) in gap.components() { - if *value > 0 && delta[asset_type] > 0 { - return true; - } +impl Default for CLIShieldedUtils { + fn default() -> Self { + Self { + context_dir: PathBuf::from(FILE_NAME), } } - false -} - -/// An extension of Option's cloned method for pair types -fn cloned_pair((a, b): (&T, &U)) -> (T, U) { - (a.clone(), b.clone()) -} - -/// Errors that can occur when trying to retrieve pinned transaction -#[derive(PartialEq, Eq)] -pub enum PinnedBalanceError { - /// No transaction has yet been pinned to the given payment address - NoTransactionPinned, - /// The supplied viewing key does not recognize payments to given address - InvalidViewingKey, -} - -/// Represents the amount used of different conversions -pub type Conversions = - HashMap, i64)>; - -/// Represents the changes that were made to a list of transparent accounts -pub type TransferDelta = HashMap>; - -/// Represents the changes that were made to a list of shielded accounts -pub type TransactionDelta = HashMap; - -/// Represents the current state of the shielded pool from the perspective of -/// the chosen viewing keys. -#[derive(BorshSerialize, BorshDeserialize, Debug)] -pub struct ShieldedContext { - /// Location where this shielded context is saved - #[borsh_skip] - context_dir: PathBuf, - /// The last transaction index to be processed in this context - last_txidx: u64, - /// The commitment tree produced by scanning all transactions up to tx_pos - tree: CommitmentTree, - /// Maps viewing keys to applicable note positions - pos_map: HashMap>, - /// Maps a nullifier to the note position to which it applies - nf_map: HashMap<[u8; 32], usize>, - /// Maps note positions to their corresponding notes - note_map: HashMap, - /// Maps note positions to their corresponding memos - memo_map: HashMap, - /// Maps note positions to the diversifier of their payment address - div_map: HashMap, - /// Maps note positions to their witness (used to make merkle paths) - witness_map: HashMap>, - /// Tracks what each transaction does to various account balances - delta_map: BTreeMap< - (BlockHeight, TxIndex), - (Epoch, TransferDelta, TransactionDelta), - >, - /// The set of note positions that have been spent - spents: HashSet, - /// Maps asset types to their decodings - asset_types: HashMap, - /// Maps note positions to their corresponding viewing keys - vk_map: HashMap, } -/// Shielded context file name -const FILE_NAME: &str = "shielded.dat"; -const TMP_FILE_NAME: &str = "shielded.tmp"; +impl masp::ShieldedUtils for CLIShieldedUtils { + type C = tendermint_rpc::HttpClient; -/// Default implementation to ease construction of TxContexts. Derive cannot be -/// used here due to CommitmentTree not implementing Default. -impl Default for ShieldedContext { - fn default() -> ShieldedContext { - ShieldedContext { - context_dir: PathBuf::from(FILE_NAME), - last_txidx: u64::default(), - tree: CommitmentTree::empty(), - pos_map: HashMap::default(), - nf_map: HashMap::default(), - note_map: HashMap::default(), - memo_map: HashMap::default(), - div_map: HashMap::default(), - witness_map: HashMap::default(), - spents: HashSet::default(), - delta_map: BTreeMap::default(), - asset_types: HashMap::default(), - vk_map: HashMap::default(), + fn local_tx_prover(&self) -> LocalTxProver { + if let Ok(params_dir) = env::var(masp::ENV_VAR_MASP_PARAMS_DIR) { + let params_dir = PathBuf::from(params_dir); + let spend_path = params_dir.join(masp::SPEND_NAME); + let convert_path = params_dir.join(masp::CONVERT_NAME); + let output_path = params_dir.join(masp::OUTPUT_NAME); + LocalTxProver::new(&spend_path, &output_path, &convert_path) + } else { + LocalTxProver::with_default_location() + .expect("unable to load MASP Parameters") } } -} -impl ShieldedContext { /// Try to load the last saved shielded context from the given context /// directory. If this fails, then leave the current context unchanged. - pub fn load(&mut self) -> std::io::Result<()> { + fn load(self) -> std::io::Result> { // Try to load shielded context from file let mut ctx_file = File::open(self.context_dir.join(FILE_NAME))?; let mut bytes = Vec::new(); ctx_file.read_to_end(&mut bytes)?; - let mut new_ctx = Self::deserialize(&mut &bytes[..])?; + let mut new_ctx = masp::ShieldedContext::deserialize(&mut &bytes[..])?; // Associate the originating context directory with the // shielded context under construction - new_ctx.context_dir = self.context_dir.clone(); - *self = new_ctx; - Ok(()) + new_ctx.utils = self; + Ok(new_ctx) } /// Save this shielded context into its associated context directory - pub fn save(&self) -> std::io::Result<()> { + fn save(&self, ctx: &masp::ShieldedContext) -> std::io::Result<()> { // TODO: use mktemp crate? let tmp_path = self.context_dir.join(TMP_FILE_NAME); { @@ -599,7 +374,7 @@ impl ShieldedContext { .create_new(true) .open(tmp_path.clone())?; let mut bytes = Vec::new(); - self.serialize(&mut bytes) + ctx.serialize(&mut bytes) .expect("cannot serialize shielded context"); ctx_file.write_all(&bytes[..])?; } @@ -612,1325 +387,131 @@ impl ShieldedContext { std::fs::remove_file(tmp_path)?; Ok(()) } +} - /// Merge data from the given shielded context into the current shielded - /// context. It must be the case that the two shielded contexts share the - /// same last transaction ID and share identical commitment trees. - pub fn merge(&mut self, new_ctx: ShieldedContext) { - debug_assert_eq!(self.last_txidx, new_ctx.last_txidx); - // Merge by simply extending maps. Identical keys should contain - // identical values, so overwriting should not be problematic. - self.pos_map.extend(new_ctx.pos_map); - self.nf_map.extend(new_ctx.nf_map); - self.note_map.extend(new_ctx.note_map); - self.memo_map.extend(new_ctx.memo_map); - self.div_map.extend(new_ctx.div_map); - self.witness_map.extend(new_ctx.witness_map); - self.spents.extend(new_ctx.spents); - self.asset_types.extend(new_ctx.asset_types); - self.vk_map.extend(new_ctx.vk_map); - // The deltas are the exception because different keys can reveal - // different parts of the same transaction. Hence each delta needs to be - // merged separately. - for ((height, idx), (ep, ntfer_delta, ntx_delta)) in new_ctx.delta_map { - let (_ep, tfer_delta, tx_delta) = self - .delta_map - .entry((height, idx)) - .or_insert((ep, TransferDelta::new(), TransactionDelta::new())); - tfer_delta.extend(ntfer_delta); - tx_delta.extend(ntx_delta); - } - } +pub async fn submit_transfer( + client: &HttpClient, + mut ctx: Context, + mut args: args::TxTransfer, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_transfer(client, &mut ctx.wallet, &mut ctx.shielded, args).await +} - /// Fetch the current state of the multi-asset shielded pool into a - /// ShieldedContext - pub async fn fetch( - &mut self, - ledger_address: &TendermintAddress, - sks: &[ExtendedSpendingKey], - fvks: &[ViewingKey], - ) { - // First determine which of the keys requested to be fetched are new. - // Necessary because old transactions will need to be scanned for new - // keys. - let mut unknown_keys = Vec::new(); - for esk in sks { - let vk = to_viewing_key(esk).vk; - if !self.pos_map.contains_key(&vk) { - unknown_keys.push(vk); - } - } - for vk in fvks { - if !self.pos_map.contains_key(vk) { - unknown_keys.push(*vk); - } - } +pub async fn submit_ibc_transfer( + client: &C, + mut ctx: Context, + mut args: args::TxIbcTransfer, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_ibc_transfer::(client, &mut ctx.wallet, args).await +} - // If unknown keys are being used, we need to scan older transactions - // for any unspent notes - let (txs, mut tx_iter); - if !unknown_keys.is_empty() { - // Load all transactions accepted until this point - txs = Self::fetch_shielded_transfers(ledger_address, 0).await; - tx_iter = txs.iter(); - // Do this by constructing a shielding context only for unknown keys - let mut tx_ctx = ShieldedContext::new(self.context_dir.clone()); - for vk in unknown_keys { - tx_ctx.pos_map.entry(vk).or_insert_with(HashSet::new); - } - // Update this unknown shielded context until it is level with self - while tx_ctx.last_txidx != self.last_txidx { - if let Some(((height, idx), (epoch, tx))) = tx_iter.next() { - tx_ctx.scan_tx(*height, *idx, *epoch, tx); - } else { - break; - } - } - // Merge the context data originating from the unknown keys into the - // current context - self.merge(tx_ctx); - } else { - // Load only transactions accepted from last_txid until this point - txs = - Self::fetch_shielded_transfers(ledger_address, self.last_txidx) - .await; - tx_iter = txs.iter(); - } - // Now that we possess the unspent notes corresponding to both old and - // new keys up until tx_pos, proceed to scan the new transactions. - for ((height, idx), (epoch, tx)) in &mut tx_iter { - self.scan_tx(*height, *idx, *epoch, tx); - } - } +pub async fn submit_init_proposal( + client: &C, + mut ctx: Context, + mut args: args::InitProposal, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + let file = File::open(&args.proposal_data).expect("File must exist."); + let proposal: Proposal = + serde_json::from_reader(file).expect("JSON was not well-formatted"); - /// Initialize a shielded transaction context that identifies notes - /// decryptable by any viewing key in the given set - pub fn new(context_dir: PathBuf) -> ShieldedContext { - // Make sure that MASP parameters are downloaded to enable MASP - // transaction building and verification later on - let params_dir = masp::get_params_dir(); - let spend_path = params_dir.join(masp::SPEND_NAME); - let convert_path = params_dir.join(masp::CONVERT_NAME); - let output_path = params_dir.join(masp::OUTPUT_NAME); - if !(spend_path.exists() - && convert_path.exists() - && output_path.exists()) - { - println!("MASP parameters not present, downloading..."); - masp_proofs::download_parameters() - .expect("MASP parameters not present or downloadable"); - println!("MASP parameter download complete, resuming execution..."); + let signer = WalletAddress::new(proposal.clone().author.to_string()); + let governance_parameters = rpc::get_governance_parameters(client).await; + let current_epoch = rpc::query_and_print_epoch(client).await; + + if proposal.voting_start_epoch <= current_epoch + || proposal.voting_start_epoch.0 + % governance_parameters.min_proposal_period + != 0 + { + println!("{}", proposal.voting_start_epoch <= current_epoch); + println!( + "{}", + proposal.voting_start_epoch.0 + % governance_parameters.min_proposal_period + == 0 + ); + eprintln!( + "Invalid proposal start epoch: {} must be greater than current \ + epoch {} and a multiple of {}", + proposal.voting_start_epoch, + current_epoch, + governance_parameters.min_proposal_period + ); + if !args.tx.force { + safe_exit(1) } - // Finally initialize a shielded context with the supplied directory - Self { - context_dir, - ..Default::default() + } else if proposal.voting_end_epoch <= proposal.voting_start_epoch + || proposal.voting_end_epoch.0 - proposal.voting_start_epoch.0 + < governance_parameters.min_proposal_period + || proposal.voting_end_epoch.0 - proposal.voting_start_epoch.0 + > governance_parameters.max_proposal_period + || proposal.voting_end_epoch.0 % 3 != 0 + { + eprintln!( + "Invalid proposal end epoch: difference between proposal start \ + and end epoch must be at least {} and at max {} and end epoch \ + must be a multiple of {}", + governance_parameters.min_proposal_period, + governance_parameters.max_proposal_period, + governance_parameters.min_proposal_period + ); + if !args.tx.force { + safe_exit(1) } - } - - /// Obtain a chronologically-ordered list of all accepted shielded - /// transactions from the ledger. The ledger conceptually stores - /// transactions as a vector. More concretely, the HEAD_TX_KEY location - /// stores the index of the last accepted transaction and each transaction - /// is stored at a key derived from its index. - pub async fn fetch_shielded_transfers( - ledger_address: &TendermintAddress, - last_txidx: u64, - ) -> BTreeMap<(BlockHeight, TxIndex), (Epoch, Transfer)> { - let client = HttpClient::new(ledger_address.clone()).unwrap(); - // The address of the MASP account - let masp_addr = masp(); - // Construct the key where last transaction pointer is stored - let head_tx_key = Key::from(masp_addr.to_db_key()) - .push(&HEAD_TX_KEY.to_owned()) - .expect("Cannot obtain a storage key"); - // Query for the index of the last accepted transaction - let head_txidx = query_storage_value::(&client, &head_tx_key) - .await - .unwrap_or(0); - let mut shielded_txs = BTreeMap::new(); - // Fetch all the transactions we do not have yet - for i in last_txidx..head_txidx { - // Construct the key for where the current transaction is stored - let current_tx_key = Key::from(masp_addr.to_db_key()) - .push(&(TX_KEY_PREFIX.to_owned() + &i.to_string())) - .expect("Cannot obtain a storage key"); - // Obtain the current transaction - let (tx_epoch, tx_height, tx_index, current_tx) = - query_storage_value::<(Epoch, BlockHeight, TxIndex, Transfer)>( - &client, - ¤t_tx_key, - ) - .await - .unwrap(); - // Collect the current transaction - shielded_txs.insert((tx_height, tx_index), (tx_epoch, current_tx)); + } else if proposal.grace_epoch <= proposal.voting_end_epoch + || proposal.grace_epoch.0 - proposal.voting_end_epoch.0 + < governance_parameters.min_proposal_grace_epochs + { + eprintln!( + "Invalid proposal grace epoch: difference between proposal grace \ + and end epoch must be at least {}", + governance_parameters.min_proposal_grace_epochs + ); + if !args.tx.force { + safe_exit(1) } - shielded_txs } - /// Applies the given transaction to the supplied context. More precisely, - /// the shielded transaction's outputs are added to the commitment tree. - /// Newly discovered notes are associated to the supplied viewing keys. Note - /// nullifiers are mapped to their originating notes. Note positions are - /// associated to notes, memos, and diversifiers. And the set of notes that - /// we have spent are updated. The witness map is maintained to make it - /// easier to construct note merkle paths in other code. See - /// - pub fn scan_tx( - &mut self, - height: BlockHeight, - index: TxIndex, - epoch: Epoch, - tx: &Transfer, - ) { - // Ignore purely transparent transactions - let shielded = if let Some(shielded) = &tx.shielded { - shielded - } else { - return; - }; - // For tracking the account changes caused by this Transaction - let mut transaction_delta = TransactionDelta::new(); - // Listen for notes sent to our viewing keys - for so in &shielded.shielded_outputs { - // Create merkle tree leaf node from note commitment - let node = Node::new(so.cmu.to_repr()); - // Update each merkle tree in the witness map with the latest - // addition - for (_, witness) in self.witness_map.iter_mut() { - witness.append(node).expect("note commitment tree is full"); - } - let note_pos = self.tree.size(); - self.tree - .append(node) - .expect("note commitment tree is full"); - // Finally, make it easier to construct merkle paths to this new - // note - let witness = IncrementalWitness::::from_tree(&self.tree); - self.witness_map.insert(note_pos, witness); - // Let's try to see if any of our viewing keys can decrypt latest - // note - for (vk, notes) in self.pos_map.iter_mut() { - let decres = try_sapling_note_decryption::( - 0, - &vk.ivk().0, - &so.ephemeral_key.into_subgroup().unwrap(), - &so.cmu, - &so.enc_ciphertext, + if args.offline { + let signer = ctx.get(&signer); + let signing_key = + find_keypair::(client, &mut ctx.wallet, &signer) + .await?; + let offline_proposal = + OfflineProposal::new(proposal, signer, &signing_key); + let proposal_filename = args + .proposal_data + .parent() + .expect("No parent found") + .join("proposal"); + let out = File::create(&proposal_filename).unwrap(); + match serde_json::to_writer_pretty(out, &offline_proposal) { + Ok(_) => { + println!( + "Proposal created: {}.", + proposal_filename.to_string_lossy() ); - // So this current viewing key does decrypt this current note... - if let Some((note, pa, memo)) = decres { - // Add this note to list of notes decrypted by this viewing - // key - notes.insert(note_pos); - // Compute the nullifier now to quickly recognize when spent - let nf = note.nf(vk, note_pos.try_into().unwrap()); - self.note_map.insert(note_pos, note); - self.memo_map.insert(note_pos, memo); - // The payment address' diversifier is required to spend - // note - self.div_map.insert(note_pos, *pa.diversifier()); - self.nf_map.insert(nf.0, note_pos); - // Note the account changes - let balance = transaction_delta - .entry(*vk) - .or_insert_with(Amount::zero); - *balance += - Amount::from_nonnegative(note.asset_type, note.value) - .expect( - "found note with invalid value or asset type", - ); - self.vk_map.insert(note_pos, *vk); - break; - } } - } - // Cancel out those of our notes that have been spent - for ss in &shielded.shielded_spends { - // If the shielded spend's nullifier is in our map, then target note - // is rendered unusable - if let Some(note_pos) = self.nf_map.get(&ss.nullifier) { - self.spents.insert(*note_pos); - // Note the account changes - let balance = transaction_delta - .entry(self.vk_map[note_pos]) - .or_insert_with(Amount::zero); - let note = self.note_map[note_pos]; - *balance -= - Amount::from_nonnegative(note.asset_type, note.value) - .expect("found note with invalid value or asset type"); + Err(e) => { + eprintln!("Error while creating proposal file: {}.", e); + safe_exit(1) } } - // Record the changes to the transparent accounts - let transparent_delta = - Amount::from_nonnegative(tx.token.clone(), u64::from(tx.amount)) - .expect("invalid value for amount"); - let mut transfer_delta = TransferDelta::new(); - transfer_delta - .insert(tx.source.clone(), Amount::zero() - &transparent_delta); - transfer_delta.insert(tx.target.clone(), transparent_delta); - self.delta_map.insert( - (height, index), - (epoch, transfer_delta, transaction_delta), - ); - self.last_txidx += 1; - } - - /// Summarize the effects on shielded and transparent accounts of each - /// Transfer in this context - pub fn get_tx_deltas( - &self, - ) -> &BTreeMap< - (BlockHeight, TxIndex), - (Epoch, TransferDelta, TransactionDelta), - > { - &self.delta_map - } - - /// Compute the total unspent notes associated with the viewing key in the - /// context. If the key is not in the context, then we do not know the - /// balance and hence we return None. - pub fn compute_shielded_balance(&self, vk: &ViewingKey) -> Option { - // Cannot query the balance of a key that's not in the map - if !self.pos_map.contains_key(vk) { - return None; - } - let mut val_acc = Amount::zero(); - // Retrieve the notes that can be spent by this key - if let Some(avail_notes) = self.pos_map.get(vk) { - for note_idx in avail_notes { - // Spent notes cannot contribute a new transaction's pool - if self.spents.contains(note_idx) { - continue; - } - // Get note associated with this ID - let note = self.note_map.get(note_idx).unwrap(); - // Finally add value to multi-asset accumulator - val_acc += - Amount::from_nonnegative(note.asset_type, note.value) - .expect("found note with invalid value or asset type"); - } - } - Some(val_acc) - } - - /// Query the ledger for the decoding of the given asset type and cache it - /// if it is found. - pub async fn decode_asset_type( - &mut self, - client: HttpClient, - asset_type: AssetType, - ) -> Option<(Address, Epoch)> { - // Try to find the decoding in the cache - if let decoded @ Some(_) = self.asset_types.get(&asset_type) { - return decoded.cloned(); - } - // Query for the ID of the last accepted transaction - let (addr, ep, _conv, _path): (Address, _, Amount, MerklePath) = - query_conversion(client, asset_type).await?; - self.asset_types.insert(asset_type, (addr.clone(), ep)); - Some((addr, ep)) - } - - /// Query the ledger for the conversion that is allowed for the given asset - /// type and cache it. - async fn query_allowed_conversion<'a>( - &'a mut self, - client: HttpClient, - asset_type: AssetType, - conversions: &'a mut Conversions, - ) -> Option<&'a mut (AllowedConversion, MerklePath, i64)> { - match conversions.entry(asset_type) { - Entry::Occupied(conv_entry) => Some(conv_entry.into_mut()), - Entry::Vacant(conv_entry) => { - // Query for the ID of the last accepted transaction - let (addr, ep, conv, path): (Address, _, _, _) = - query_conversion(client, asset_type).await?; - self.asset_types.insert(asset_type, (addr, ep)); - // If the conversion is 0, then we just have a pure decoding - if conv == Amount::zero() { - None - } else { - Some(conv_entry.insert((Amount::into(conv), path, 0))) - } - } - } - } - - /// Compute the total unspent notes associated with the viewing key in the - /// context and express that value in terms of the currently timestamped - /// asset types. If the key is not in the context, then we do not know the - /// balance and hence we return None. - pub async fn compute_exchanged_balance( - &mut self, - client: HttpClient, - vk: &ViewingKey, - target_epoch: Epoch, - ) -> Option { - // First get the unexchanged balance - if let Some(balance) = self.compute_shielded_balance(vk) { - // And then exchange balance into current asset types - Some( - self.compute_exchanged_amount( - client, - balance, - target_epoch, - HashMap::new(), - ) - .await - .0, - ) - } else { - None - } - } - - /// Try to convert as much of the given asset type-value pair using the - /// given allowed conversion. usage is incremented by the amount of the - /// conversion used, the conversions are applied to the given input, and - /// the trace amount that could not be converted is moved from input to - /// output. - fn apply_conversion( - conv: AllowedConversion, - asset_type: AssetType, - value: i64, - usage: &mut i64, - input: &mut Amount, - output: &mut Amount, - ) { - // If conversion if possible, accumulate the exchanged amount - let conv: Amount = conv.into(); - // The amount required of current asset to qualify for conversion - let threshold = -conv[&asset_type]; - if threshold == 0 { - eprintln!( - "Asset threshold of selected conversion for asset type {} is \ - 0, this is a bug, please report it.", - asset_type - ); - } - // We should use an amount of the AllowedConversion that almost - // cancels the original amount - let required = value / threshold; - // Forget about the trace amount left over because we cannot - // realize its value - let trace = Amount::from_pair(asset_type, value % threshold).unwrap(); - // Record how much more of the given conversion has been used - *usage += required; - // Apply the conversions to input and move the trace amount to output - *input += conv * required - &trace; - *output += trace; - } - - /// Convert the given amount into the latest asset types whilst making a - /// note of the conversions that were used. Note that this function does - /// not assume that allowed conversions from the ledger are expressed in - /// terms of the latest asset types. - pub async fn compute_exchanged_amount( - &mut self, - client: HttpClient, - mut input: Amount, - target_epoch: Epoch, - mut conversions: Conversions, - ) -> (Amount, Conversions) { - // Where we will store our exchanged value - let mut output = Amount::zero(); - // Repeatedly exchange assets until it is no longer possible - while let Some((asset_type, value)) = - input.components().next().map(cloned_pair) - { - let target_asset_type = self - .decode_asset_type(client.clone(), asset_type) - .await - .map(|(addr, _epoch)| make_asset_type(target_epoch, &addr)) - .unwrap_or(asset_type); - let at_target_asset_type = asset_type == target_asset_type; - if let (Some((conv, _wit, usage)), false) = ( - self.query_allowed_conversion( - client.clone(), - asset_type, - &mut conversions, - ) - .await, - at_target_asset_type, - ) { - println!( - "converting current asset type to latest asset type..." - ); - // Not at the target asset type, not at the latest asset type. - // Apply conversion to get from current asset type to the latest - // asset type. - Self::apply_conversion( - conv.clone(), - asset_type, - value, - usage, - &mut input, - &mut output, - ); - } else if let (Some((conv, _wit, usage)), false) = ( - self.query_allowed_conversion( - client.clone(), - target_asset_type, - &mut conversions, - ) - .await, - at_target_asset_type, - ) { - println!( - "converting latest asset type to target asset type..." - ); - // Not at the target asset type, yes at the latest asset type. - // Apply inverse conversion to get from latest asset type to - // the target asset type. - Self::apply_conversion( - conv.clone(), - asset_type, - value, - usage, - &mut input, - &mut output, - ); - } else { - // At the target asset type. Then move component over to output. - let comp = input.project(asset_type); - output += ∁ - // Strike from input to avoid repeating computation - input -= comp; - } - } - (output, conversions) - } - - /// Collect enough unspent notes in this context to exceed the given amount - /// of the specified asset type. Return the total value accumulated plus - /// notes and the corresponding diversifiers/merkle paths that were used to - /// achieve the total value. - pub async fn collect_unspent_notes( - &mut self, - ledger_address: TendermintAddress, - vk: &ViewingKey, - target: Amount, - target_epoch: Epoch, - ) -> ( - Amount, - Vec<(Diversifier, Note, MerklePath)>, - Conversions, - ) { - // Establish connection with which to do exchange rate queries - let client = HttpClient::new(ledger_address.clone()).unwrap(); - let mut conversions = HashMap::new(); - let mut val_acc = Amount::zero(); - let mut notes = Vec::new(); - // Retrieve the notes that can be spent by this key - if let Some(avail_notes) = self.pos_map.get(vk).cloned() { - for note_idx in &avail_notes { - // No more transaction inputs are required once we have met - // the target amount - if val_acc >= target { - break; - } - // Spent notes cannot contribute a new transaction's pool - if self.spents.contains(note_idx) { - continue; - } - // Get note, merkle path, diversifier associated with this ID - let note = *self.note_map.get(note_idx).unwrap(); - - // The amount contributed by this note before conversion - let pre_contr = Amount::from_pair(note.asset_type, note.value) - .expect("received note has invalid value or asset type"); - let (contr, proposed_convs) = self - .compute_exchanged_amount( - client.clone(), - pre_contr, - target_epoch, - conversions.clone(), - ) - .await; - - // Use this note only if it brings us closer to our target - if is_amount_required( - val_acc.clone(), - target.clone(), - contr.clone(), - ) { - // Be sure to record the conversions used in computing - // accumulated value - val_acc += contr; - // Commit the conversions that were used to exchange - conversions = proposed_convs; - let merkle_path = - self.witness_map.get(note_idx).unwrap().path().unwrap(); - let diversifier = self.div_map.get(note_idx).unwrap(); - // Commit this note to our transaction - notes.push((*diversifier, note, merkle_path)); - } - } - } - (val_acc, notes, conversions) - } - - /// Compute the combined value of the output notes of the transaction pinned - /// at the given payment address. This computation uses the supplied viewing - /// keys to try to decrypt the output notes. If no transaction is pinned at - /// the given payment address fails with - /// `PinnedBalanceError::NoTransactionPinned`. - pub async fn compute_pinned_balance( - ledger_address: &TendermintAddress, - owner: PaymentAddress, - viewing_key: &ViewingKey, - ) -> Result<(Amount, Epoch), PinnedBalanceError> { - // Check that the supplied viewing key corresponds to given payment - // address - let counter_owner = viewing_key.to_payment_address( - *masp_primitives::primitives::PaymentAddress::diversifier( - &owner.into(), - ), - ); - match counter_owner { - Some(counter_owner) if counter_owner == owner.into() => {} - _ => return Err(PinnedBalanceError::InvalidViewingKey), - } - let client = HttpClient::new(ledger_address.clone()).unwrap(); - // The address of the MASP account - let masp_addr = masp(); - // Construct the key for where the transaction ID would be stored - let pin_key = Key::from(masp_addr.to_db_key()) - .push(&(PIN_KEY_PREFIX.to_owned() + &owner.hash())) - .expect("Cannot obtain a storage key"); - // Obtain the transaction pointer at the key - let txidx = query_storage_value::(&client, &pin_key) - .await - .ok_or(PinnedBalanceError::NoTransactionPinned)?; - // Construct the key for where the pinned transaction is stored - let tx_key = Key::from(masp_addr.to_db_key()) - .push(&(TX_KEY_PREFIX.to_owned() + &txidx.to_string())) - .expect("Cannot obtain a storage key"); - // Obtain the pointed to transaction - let (tx_epoch, _tx_height, _tx_index, tx) = - query_storage_value::<(Epoch, BlockHeight, TxIndex, Transfer)>( - &client, &tx_key, - ) - .await - .expect("Ill-formed epoch, transaction pair"); - // Accumulate the combined output note value into this Amount - let mut val_acc = Amount::zero(); - let tx = tx - .shielded - .expect("Pinned Transfers should have shielded part"); - for so in &tx.shielded_outputs { - // Let's try to see if our viewing key can decrypt current note - let decres = try_sapling_note_decryption::( - 0, - &viewing_key.ivk().0, - &so.ephemeral_key.into_subgroup().unwrap(), - &so.cmu, - &so.enc_ciphertext, - ); - match decres { - // So the given viewing key does decrypt this current note... - Some((note, pa, _memo)) if pa == owner.into() => { - val_acc += - Amount::from_nonnegative(note.asset_type, note.value) - .expect( - "found note with invalid value or asset type", - ); - break; - } - _ => {} - } - } - Ok((val_acc, tx_epoch)) - } - - /// Compute the combined value of the output notes of the pinned transaction - /// at the given payment address if there's any. The asset types may be from - /// the epoch of the transaction or even before, so exchange all these - /// amounts to the epoch of the transaction in order to get the value that - /// would have been displayed in the epoch of the transaction. - pub async fn compute_exchanged_pinned_balance( - &mut self, - ledger_address: &TendermintAddress, - owner: PaymentAddress, - viewing_key: &ViewingKey, - ) -> Result<(Amount, Epoch), PinnedBalanceError> { - // Obtain the balance that will be exchanged - let (amt, ep) = - Self::compute_pinned_balance(ledger_address, owner, viewing_key) - .await?; - // Establish connection with which to do exchange rate queries - let client = HttpClient::new(ledger_address.clone()).unwrap(); - // Finally, exchange the balance to the transaction's epoch - Ok(( - self.compute_exchanged_amount(client, amt, ep, HashMap::new()) - .await - .0, - ep, - )) - } - - /// Convert an amount whose units are AssetTypes to one whose units are - /// Addresses that they decode to. All asset types not corresponding to - /// the given epoch are ignored. - pub async fn decode_amount( - &mut self, - client: HttpClient, - amt: Amount, - target_epoch: Epoch, - ) -> Amount
{ - let mut res = Amount::zero(); - for (asset_type, val) in amt.components() { - // Decode the asset type - let decoded = - self.decode_asset_type(client.clone(), *asset_type).await; - // Only assets with the target timestamp count - match decoded { - Some((addr, epoch)) if epoch == target_epoch => { - res += &Amount::from_pair(addr, *val).unwrap() - } - _ => {} - } - } - res - } - - /// Convert an amount whose units are AssetTypes to one whose units are - /// Addresses that they decode to. - pub async fn decode_all_amounts( - &mut self, - client: HttpClient, - amt: Amount, - ) -> Amount<(Address, Epoch)> { - let mut res = Amount::zero(); - for (asset_type, val) in amt.components() { - // Decode the asset type - let decoded = - self.decode_asset_type(client.clone(), *asset_type).await; - // Only assets with the target timestamp count - if let Some((addr, epoch)) = decoded { - res += &Amount::from_pair((addr, epoch), *val).unwrap() - } - } - res - } -} - -/// Make asset type corresponding to given address and epoch -fn make_asset_type(epoch: Epoch, token: &Address) -> AssetType { - // Typestamp the chosen token with the current epoch - let token_bytes = (token, epoch.0) - .try_to_vec() - .expect("token should serialize"); - // Generate the unique asset identifier from the unique token address - AssetType::new(token_bytes.as_ref()).expect("unable to create asset type") -} - -/// Convert Namada amount and token type to MASP equivalents -fn convert_amount( - epoch: Epoch, - token: &Address, - val: token::Amount, -) -> (AssetType, Amount) { - let asset_type = make_asset_type(epoch, token); - // Combine the value and unit into one amount - let amount = Amount::from_nonnegative(asset_type, u64::from(val)) - .expect("invalid value for amount"); - (asset_type, amount) -} - -/// Make shielded components to embed within a Transfer object. If no shielded -/// payment address nor spending key is specified, then no shielded components -/// are produced. Otherwise a transaction containing nullifiers and/or note -/// commitments are produced. Dummy transparent UTXOs are sometimes used to make -/// transactions balanced, but it is understood that transparent account changes -/// are effected only by the amounts and signatures specified by the containing -/// Transfer object. -async fn gen_shielded_transfer( - ctx: &mut Context, - client: &HttpClient, - args: &args::TxTransfer, - shielded_gas: bool, -) -> Result, builder::Error> { - // No shielded components are needed when neither source nor destination - // are shielded - let spending_key = ctx.get_cached(&args.source).spending_key(); - let payment_address = ctx.get(&args.target).payment_address(); - // No shielded components are needed when neither source nor - // destination are shielded - if spending_key.is_none() && payment_address.is_none() { - return Ok(None); - } - // We want to fund our transaction solely from supplied spending key - let spending_key = spending_key.map(|x| x.into()); - let spending_keys: Vec<_> = spending_key.into_iter().collect(); - // Load the current shielded context given the spending key we - // possess - let _ = ctx.shielded.load(); - ctx.shielded - .fetch(&args.tx.ledger_address, &spending_keys, &[]) - .await; - // Save the update state so that future fetches can be - // short-circuited - let _ = ctx.shielded.save(); - - // Determine epoch in which to submit potential shielded transaction - let epoch = query_epoch(client).await; - // Context required for storing which notes are in the source's possesion - let consensus_branch_id = BranchId::Sapling; - let amt: u64 = args.amount.into(); - let memo: Option = None; - - // Now we build up the transaction within this object - let mut builder = Builder::::new(0u32); - // Convert transaction amount into MASP types - let (asset_type, amount) = - convert_amount(epoch, &ctx.get(&args.token), args.amount); - - // If there are shielded inputs - if let Some(sk) = spending_key { - // Transaction fees need to match the amount in the wrapper Transfer - // when MASP source is used - let (_, fee) = convert_amount( - epoch, - &ctx.get(&args.tx.fee_token), - args.tx.fee_amount, - ); - builder.set_fee(fee.clone())?; - // If the gas is coming from the shielded pool, then our shielded inputs - // must also cover the gas fee - let required_amt = if shielded_gas { amount + fee } else { amount }; - // Locate unspent notes that can help us meet the transaction amount - let (_, unspent_notes, used_convs) = ctx - .shielded - .collect_unspent_notes( - args.tx.ledger_address.clone(), - &to_viewing_key(&sk).vk, - required_amt, - epoch, - ) - .await; - // Commit the notes found to our transaction - for (diversifier, note, merkle_path) in unspent_notes { - builder.add_sapling_spend(sk, diversifier, note, merkle_path)?; - } - // Commit the conversion notes used during summation - for (conv, wit, value) in used_convs.values() { - if *value > 0 { - builder.add_convert( - conv.clone(), - *value as u64, - wit.clone(), - )?; - } - } - } else { - // No transfer fees come from the shielded transaction for non-MASP - // sources - builder.set_fee(Amount::zero())?; - // We add a dummy UTXO to our transaction, but only the source of the - // parent Transfer object is used to validate fund availability - let secp_sk = - secp256k1::SecretKey::from_slice(&[0xcd; 32]).expect("secret key"); - let secp_ctx = secp256k1::Secp256k1::::gen_new(); - let secp_pk = - secp256k1::PublicKey::from_secret_key(&secp_ctx, &secp_sk) - .serialize(); - let hash = - ripemd160::Ripemd160::digest(&sha2::Sha256::digest(&secp_pk)); - let script = TransparentAddress::PublicKey(hash.into()).script(); - builder.add_transparent_input( - secp_sk, - OutPoint::new([0u8; 32], 0), - TxOut { - asset_type, - value: amt, - script_pubkey: script, - }, - )?; - } - // Now handle the outputs of this transaction - // If there is a shielded output - if let Some(pa) = payment_address { - let ovk_opt = spending_key.map(|x| x.expsk.ovk); - builder.add_sapling_output( - ovk_opt, - pa.into(), - asset_type, - amt, - memo.clone(), - )?; - } else { - // Embed the transparent target address into the shielded transaction so - // that it can be signed - let target = ctx.get(&args.target); - let target_enc = target - .address() - .expect("target address should be transparent") - .try_to_vec() - .expect("target address encoding"); - let hash = ripemd160::Ripemd160::digest(&sha2::Sha256::digest( - target_enc.as_ref(), - )); - builder.add_transparent_output( - &TransparentAddress::PublicKey(hash.into()), - asset_type, - amt, - )?; - } - let prover = if let Ok(params_dir) = env::var(masp::ENV_VAR_MASP_PARAMS_DIR) - { - let params_dir = PathBuf::from(params_dir); - let spend_path = params_dir.join(masp::SPEND_NAME); - let convert_path = params_dir.join(masp::CONVERT_NAME); - let output_path = params_dir.join(masp::OUTPUT_NAME); - LocalTxProver::new(&spend_path, &output_path, &convert_path) - } else { - LocalTxProver::with_default_location() - .expect("unable to load MASP Parameters") - }; - // Build and return the constructed transaction - builder - .build(consensus_branch_id, &prover) - .map(|(a, b)| Some((a, b, epoch))) -} - -/// Unzip an option of a pair into a pair of options -/// TODO: use `Option::unzip` stabilized in Rust 1.66.0 -fn unzip_option(opt: Option<(T, U)>) -> (Option, Option) { - match opt { - Some((a, b)) => (Some(a), Some(b)), - None => (None, None), - } -} - -pub async fn submit_transfer(mut ctx: Context, args: args::TxTransfer) { - let source = ctx.get_cached(&args.source).effective_address(); - let target = ctx.get(&args.target).effective_address(); - // Check that the source address exists on chain - let source_exists = - rpc::known_address(&source, args.tx.ledger_address.clone()).await; - if !source_exists { - eprintln!("The source address {} doesn't exist on chain.", source); - if !args.tx.force { - safe_exit(1) - } - } - // Check that the target address exists on chain - let target_exists = - rpc::known_address(&target, args.tx.ledger_address.clone()).await; - if !target_exists { - eprintln!("The target address {} doesn't exist on chain.", target); - if !args.tx.force { - safe_exit(1) - } - } - let token = ctx.get(&args.token); - // Check that the token address exists on chain - let token_exists = - rpc::known_address(&token, args.tx.ledger_address.clone()).await; - if !token_exists { - eprintln!("The token address {} doesn't exist on chain.", token); - if !args.tx.force { - safe_exit(1) - } - } - // Check source balance - let (sub_prefix, balance_key) = match &args.sub_prefix { - Some(sub_prefix) => { - let sub_prefix = storage::Key::parse(sub_prefix).unwrap(); - let prefix = token::multitoken_balance_prefix(&token, &sub_prefix); - ( - Some(sub_prefix), - token::multitoken_balance_key(&prefix, &source), - ) - } - None => (None, token::balance_key(&token, &source)), - }; - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - match rpc::query_storage_value::(&client, &balance_key).await - { - Some(balance) => { - if balance < args.amount { - eprintln!( - "The balance of the source {} of token {} is lower than \ - the amount to be transferred. Amount to transfer is {} \ - and the balance is {}.", - source, token, args.amount, balance - ); - if !args.tx.force { - safe_exit(1) - } - } - } - None => { - eprintln!( - "No balance found for the source {} of token {}", - source, token - ); - if !args.tx.force { - safe_exit(1) - } - } - }; - - let masp_addr = masp(); - // For MASP sources, use a special sentinel key recognized by VPs as default - // signer. Also, if the transaction is shielded, redact the amount and token - // types by setting the transparent value to 0 and token type to a constant. - // This has no side-effect because transaction is to self. - let (default_signer, amount, token) = - if source == masp_addr && target == masp_addr { - // TODO Refactor me, we shouldn't rely on any specific token here. - ( - TxSigningKey::SecretKey(masp_tx_key()), - 0.into(), - ctx.native_token.clone(), - ) - } else if source == masp_addr { - ( - TxSigningKey::SecretKey(masp_tx_key()), - args.amount, - token.clone(), - ) - } else { - ( - TxSigningKey::WalletAddress(args.source.to_address()), - args.amount, - token, - ) - }; - // If our chosen signer is the MASP sentinel key, then our shielded inputs - // will need to cover the gas fees. - let chosen_signer = tx_signer(&mut ctx, &args.tx, default_signer.clone()) - .await - .ref_to(); - let shielded_gas = masp_tx_key().ref_to() == chosen_signer; - // Determine whether to pin this transaction to a storage key - let key = match ctx.get(&args.target) { - TransferTarget::PaymentAddress(pa) if pa.is_pinned() => Some(pa.hash()), - _ => None, - }; - - #[cfg(not(feature = "mainnet"))] - let is_source_faucet = - rpc::is_faucet_account(&source, args.tx.ledger_address.clone()).await; - - let signing_address = TxSigningKey::WalletAddress(args.source.to_address()); - let tx_code_hash = - query_wasm_code_hash(TX_TRANSFER_WASM, args.tx.ledger_address.clone()) - .await - .unwrap(); - - // Loop twice in case the first submission attempt fails - for _ in 0..2 { - // Construct the shielded part of the transaction, if any - let stx_result = - gen_shielded_transfer(&mut ctx, &client, &args, shielded_gas).await; - - let (shielded, shielded_tx_epoch) = match stx_result { - Ok(stx) => unzip_option(stx.map(|x| (x.0, x.2))), - Err(builder::Error::ChangeIsNegative(_)) => { - eprintln!( - "The balance of the source {} is lower than the amount to \ - be transferred and fees. Amount to transfer is {} {} and \ - fees are {} {}.", - source.clone(), - args.amount, - token, - args.tx.fee_amount, - ctx.get(&args.tx.fee_token), - ); - safe_exit(1) - } - Err(err) => panic!("{}", err), - }; - - // Construct the transparent part of the transaction - let transfer = token::Transfer { - source: source.clone(), - target: target.clone(), - token: token.clone(), - sub_prefix: sub_prefix.clone(), - amount, - key: key.clone(), - shielded, - }; - tracing::debug!("Transfer data {:?}", transfer); - let data = transfer - .try_to_vec() - .expect("Encoding tx data shouldn't fail"); - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - - // Dry-run/broadcast/submit the transaction - let (new_ctx, result) = process_tx( - ctx, - &args.tx, - tx, - signing_address.clone(), - #[cfg(not(feature = "mainnet"))] - is_source_faucet, - ) - .await; - ctx = new_ctx; - - // Query the epoch in which the transaction was probably submitted - let submission_epoch = rpc::query_epoch(&client).await; - - match result { - ProcessTxResponse::Applied(resp) if - // If a transaction is shielded - shielded_tx_epoch.is_some() && - // And it is rejected by a VP - resp.code == 1.to_string() && - // And the its submission epoch doesn't match construction epoch - shielded_tx_epoch.unwrap() != submission_epoch => - { - // Then we probably straddled an epoch boundary. Let's retry... - eprintln!( - "MASP transaction rejected and this may be due to the \ - epoch changing. Attempting to resubmit transaction.", - ); - continue; - }, - // Otherwise either the transaction was successful or it will not - // benefit from resubmission - _ => break, - } - } -} - -pub async fn submit_ibc_transfer(ctx: Context, args: args::TxIbcTransfer) { - let source = ctx.get(&args.source); - // Check that the source address exists on chain - let source_exists = - rpc::known_address(&source, args.tx.ledger_address.clone()).await; - if !source_exists { - eprintln!("The source address {} doesn't exist on chain.", source); - if !args.tx.force { - safe_exit(1) - } - } - - // We cannot check the receiver - - let token = ctx.get(&args.token); - // Check that the token address exists on chain - let token_exists = - rpc::known_address(&token, args.tx.ledger_address.clone()).await; - if !token_exists { - eprintln!("The token address {} doesn't exist on chain.", token); - if !args.tx.force { - safe_exit(1) - } - } - // Check source balance - let (sub_prefix, balance_key) = match args.sub_prefix { - Some(sub_prefix) => { - let sub_prefix = storage::Key::parse(sub_prefix).unwrap(); - let prefix = token::multitoken_balance_prefix(&token, &sub_prefix); - ( - Some(sub_prefix), - token::multitoken_balance_key(&prefix, &source), - ) - } - None => (None, token::balance_key(&token, &source)), - }; - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - match rpc::query_storage_value::(&client, &balance_key).await - { - Some(balance) => { - if balance < args.amount { - eprintln!( - "The balance of the source {} of token {} is lower than \ - the amount to be transferred. Amount to transfer is {} \ - and the balance is {}.", - source, token, args.amount, balance - ); - if !args.tx.force { - safe_exit(1) - } - } - } - None => { - eprintln!( - "No balance found for the source {} of token {}", - source, token - ); - if !args.tx.force { - safe_exit(1) - } - } - } - let tx_code_hash = - query_wasm_code_hash(TX_IBC_WASM, args.tx.ledger_address.clone()) - .await - .unwrap(); - - let denom = match sub_prefix { - // To parse IbcToken address, remove the address prefix - Some(sp) => sp.to_string().replace(RESERVED_ADDRESS_PREFIX, ""), - None => token.to_string(), - }; - let token = Coin { - denom, - amount: args.amount.to_string(), - }; - - // this height should be that of the destination chain, not this chain - let timeout_height = match args.timeout_height { - Some(h) => { - TimeoutHeight::At(IbcHeight::new(0, h).expect("invalid height")) - } - None => TimeoutHeight::Never, - }; - - let now: namada::tendermint::Time = DateTimeUtc::now().try_into().unwrap(); - let now: IbcTimestamp = now.into(); - let timeout_timestamp = if let Some(offset) = args.timeout_sec_offset { - (now + Duration::new(offset, 0)).unwrap() - } else if timeout_height == TimeoutHeight::Never { - // we cannot set 0 to both the height and the timestamp - (now + Duration::new(3600, 0)).unwrap() + Ok(()) } else { - IbcTimestamp::none() - }; - - let msg = MsgTransfer { - port_id_on_a: args.port_id, - chan_id_on_a: args.channel_id, - token, - sender: Signer::from_str(&source.to_string()).expect("invalid signer"), - receiver: Signer::from_str(&args.receiver).expect("invalid signer"), - timeout_height_on_b: timeout_height, - timeout_timestamp_on_b: timeout_timestamp, - }; - tracing::debug!("IBC transfer message {:?}", msg); - let any_msg = msg.to_any(); - let mut data = vec![]; - prost::Message::encode(&any_msg, &mut data) - .expect("Encoding tx data shouldn't fail"); - - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(args.source), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; -} - -pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { - let file = File::open(&args.proposal_data).expect("File must exist."); - let proposal: Proposal = - serde_json::from_reader(file).expect("JSON was not well-formatted"); - - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - - let signer = WalletAddress::new(proposal.clone().author.to_string()); - let governance_parameters = rpc::get_governance_parameters(&client).await; - let current_epoch = rpc::query_and_print_epoch(args::Query { - ledger_address: args.tx.ledger_address.clone(), - }) - .await; - - if proposal.voting_start_epoch <= current_epoch - || proposal.voting_start_epoch.0 - % governance_parameters.min_proposal_period - != 0 - { - println!("{}", proposal.voting_start_epoch <= current_epoch); - println!( - "{}", - proposal.voting_start_epoch.0 - % governance_parameters.min_proposal_period - == 0 - ); - eprintln!( - "Invalid proposal start epoch: {} must be greater than current \ - epoch {} and a multiple of {}", - proposal.voting_start_epoch, - current_epoch, - governance_parameters.min_proposal_period - ); - if !args.tx.force { - safe_exit(1) - } - } else if proposal.voting_end_epoch <= proposal.voting_start_epoch - || proposal.voting_end_epoch.0 - proposal.voting_start_epoch.0 - < governance_parameters.min_proposal_period - || proposal.voting_end_epoch.0 - proposal.voting_start_epoch.0 - > governance_parameters.max_proposal_period - || proposal.voting_end_epoch.0 % 3 != 0 - { - eprintln!( - "Invalid proposal end epoch: difference between proposal start \ - and end epoch must be at least {} and at max {} and end epoch \ - must be a multiple of {}", - governance_parameters.min_proposal_period, - governance_parameters.max_proposal_period, - governance_parameters.min_proposal_period - ); - if !args.tx.force { - safe_exit(1) - } - } else if proposal.grace_epoch <= proposal.voting_end_epoch - || proposal.grace_epoch.0 - proposal.voting_end_epoch.0 - < governance_parameters.min_proposal_grace_epochs - { - eprintln!( - "Invalid proposal grace epoch: difference between proposal grace \ - and end epoch must be at least {}", - governance_parameters.min_proposal_grace_epochs - ); - if !args.tx.force { - safe_exit(1) - } - } - - if args.offline { let signer = ctx.get(&signer); - let signing_key = find_keypair( - &mut ctx.wallet, - &signer, - args.tx.ledger_address.clone(), - ) - .await; - let offline_proposal = - OfflineProposal::new(proposal, signer, &signing_key); - let proposal_filename = args - .proposal_data - .parent() - .expect("No parent found") - .join("proposal"); - let out = File::create(&proposal_filename).unwrap(); - match serde_json::to_writer_pretty(out, &offline_proposal) { - Ok(_) => { - println!( - "Proposal created: {}.", - proposal_filename.to_string_lossy() - ); - } - Err(e) => { - eprintln!("Error while creating proposal file: {}.", e); - safe_exit(1) - } - } - } else { let tx_data: Result = proposal.clone().try_into(); let init_proposal_data = if let Ok(data) = tx_data { data @@ -1940,8 +521,8 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { }; let balance = rpc::get_token_balance( - &client, - &ctx.native_token, + client, + &args.native_token, &proposal.author, ) .await @@ -1966,12 +547,9 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { let data = init_proposal_data .try_to_vec() .expect("Encoding proposal data shouldn't fail"); - let tx_code_hash = query_wasm_code_hash( - TX_INIT_PROPOSAL, - args.tx.ledger_address.clone(), - ) - .await - .unwrap(); + let tx_code_hash = query_wasm_code_hash(client, args::TX_INIT_PROPOSAL) + .await + .unwrap(); let tx = Tx::new( tx_code_hash.to_vec(), Some(data), @@ -1979,7 +557,8 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { args.tx.expiration, ); - process_tx( + process_tx::( + client, ctx, &args.tx, tx, @@ -1987,11 +566,20 @@ pub async fn submit_init_proposal(mut ctx: Context, args: args::InitProposal) { #[cfg(not(feature = "mainnet"))] false, ) - .await; + .await?; + Ok(()) } } -pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { +pub async fn submit_vote_proposal( + client: &C, + mut ctx: Context, + mut args: args::VoteProposal, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); let signer = if let Some(addr) = &args.tx.signer { addr } else { @@ -2060,31 +648,23 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { ); safe_exit(1); } - let signer = ctx.get(signer); let proposal_file_path = args.proposal_data.expect("Proposal file should exist."); let file = File::open(&proposal_file_path).expect("File must exist."); let proposal: OfflineProposal = serde_json::from_reader(file).expect("JSON was not well-formatted"); - let public_key = rpc::get_public_key( - &proposal.address, - args.tx.ledger_address.clone(), - ) - .await - .expect("Public key should exist."); + let public_key = rpc::get_public_key(client, &proposal.address) + .await + .expect("Public key should exist."); if !proposal.check_signature(&public_key) { eprintln!("Proposal signature mismatch!"); safe_exit(1) } - let signing_key = find_keypair( - &mut ctx.wallet, - &signer, - args.tx.ledger_address.clone(), - ) - .await; - + let signing_key = + find_keypair::(client, &mut ctx.wallet, signer) + .await?; let offline_vote = OfflineVote::new( &proposal, proposal_vote, @@ -2103,6 +683,7 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { "Proposal vote created: {}.", proposal_vote_filename.to_string_lossy() ); + Ok(()) } Err(e) => { eprintln!("Error while creating proposal vote file: {}.", e); @@ -2110,33 +691,28 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { } } } else { - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - let current_epoch = rpc::query_and_print_epoch(args::Query { - ledger_address: args.tx.ledger_address.clone(), - }) - .await; + let current_epoch = rpc::query_and_print_epoch(client).await; - let voter_address = ctx.get(signer); + let voter_address = signer.clone(); let proposal_id = args.proposal_id.unwrap(); let proposal_start_epoch_key = gov_storage::get_voting_start_epoch_key(proposal_id); - let proposal_start_epoch = rpc::query_storage_value::( - &client, + let proposal_start_epoch = rpc::query_storage_value::( + client, &proposal_start_epoch_key, ) .await; // Check vote type and memo let proposal_type_key = gov_storage::get_proposal_type_key(proposal_id); - let proposal_type: ProposalType = - rpc::query_storage_value(&client, &proposal_type_key) - .await - .unwrap_or_else(|| { - panic!( - "Didn't find type of proposal id {} in storage", - proposal_id - ) - }); + let proposal_type: ProposalType = rpc::query_storage_value::< + C, + ProposalType, + >(client, &proposal_type_key) + .await + .unwrap_or_else(|| { + panic!("Didn't find type of proposal id {} in storage", proposal_id) + }); if let ProposalVote::Yay(ref vote_type) = proposal_vote { if &proposal_type != vote_type { @@ -2152,7 +728,7 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { match address { Address::Established(_) => { let vp_key = Key::validity_predicate(address); - if !rpc::query_has_storage_key(&client, &vp_key) + if !rpc::query_has_storage_key::(client, &vp_key) .await { eprintln!( @@ -2190,7 +766,7 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { } } let mut delegations = - rpc::get_delegators_delegation(&client, &voter_address) + rpc::get_delegators_delegation(client, &voter_address) .await; // Optimize by quering if a vote from a validator @@ -2200,16 +776,10 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { // validator changing his vote and, effectively, invalidating // the delgator's vote if !args.tx.force - && is_safe_voting_window( - args.tx.ledger_address.clone(), - &client, - proposal_id, - epoch, - ) - .await + && is_safe_voting_window(client, proposal_id, epoch).await? { delegations = filter_delegations( - &client, + client, delegations, proposal_id, &proposal_vote, @@ -2224,23 +794,16 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { delegations: delegations.into_iter().collect(), }; + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; let data = tx_data .try_to_vec() .expect("Encoding proposal data shouldn't fail"); - let tx_code_hash = query_wasm_code_hash( - TX_VOTE_PROPOSAL, - args.tx.ledger_address.clone(), - ) - .await - .unwrap(); - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); + let tx_code = args.tx_code_path; + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); - process_tx( + process_tx::( + client, ctx, &args.tx, tx, @@ -2248,184 +811,88 @@ pub async fn submit_vote_proposal(mut ctx: Context, args: args::VoteProposal) { #[cfg(not(feature = "mainnet"))] false, ) - .await; + .await?; + Ok(()) } None => { eprintln!( "Proposal start epoch for proposal id {} is not definied.", proposal_id ); - if !args.tx.force { - safe_exit(1) - } + if !args.tx.force { safe_exit(1) } else { Ok(()) } } } } } -pub async fn submit_reveal_pk(mut ctx: Context, args: args::RevealPk) { - let args::RevealPk { - tx: args, - public_key, - } = args; - let public_key = ctx.get_cached(&public_key); - if !reveal_pk_if_needed(&mut ctx, &public_key, &args).await { - let addr: Address = (&public_key).into(); - println!("PK for {addr} is already revealed, nothing to do."); - } +pub async fn submit_reveal_pk( + client: &C, + ctx: &mut Context, + mut args: args::RevealPk, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_reveal_pk::(client, &mut ctx.wallet, args).await } -pub async fn reveal_pk_if_needed( +pub async fn reveal_pk_if_needed( + client: &C, ctx: &mut Context, public_key: &common::PublicKey, args: &args::Tx, -) -> bool { - let addr: Address = public_key.into(); - // Check if PK revealed - if args.force || !has_revealed_pk(&addr, args.ledger_address.clone()).await - { - // If not, submit it - submit_reveal_pk_aux(ctx, public_key, args).await; - true - } else { - false - } +) -> Result { + let args = args::Tx { + chain_id: args + .clone() + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())), + ..args.clone() + }; + tx::reveal_pk_if_needed::(client, &mut ctx.wallet, public_key, &args) + .await } -pub async fn has_revealed_pk( +pub async fn has_revealed_pk( + client: &C, addr: &Address, - ledger_address: TendermintAddress, ) -> bool { - rpc::get_public_key(addr, ledger_address).await.is_some() + tx::has_revealed_pk(client, addr).await } -pub async fn submit_reveal_pk_aux( +pub async fn submit_reveal_pk_aux( + client: &C, ctx: &mut Context, public_key: &common::PublicKey, args: &args::Tx, -) { - let addr: Address = public_key.into(); - println!("Submitting a tx to reveal the public key for address {addr}..."); - let tx_data = public_key - .try_to_vec() - .expect("Encoding a public key shouldn't fail"); - let tx_code_hash = - query_wasm_code_hash(TX_REVEAL_PK, args.ledger_address.clone()) - .await - .unwrap(); - let chain_id = ctx.config.ledger.chain_id.clone(); - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(tx_data), - chain_id, - args.expiration, - ); - - // submit_tx without signing the inner tx - let keypair = if let Some(signing_key) = &args.signing_key { - ctx.get_cached(signing_key) - } else if let Some(signer) = args.signer.as_ref() { - let signer = ctx.get(signer); - find_keypair(&mut ctx.wallet, &signer, args.ledger_address.clone()) - .await - } else { - find_keypair(&mut ctx.wallet, &addr, args.ledger_address.clone()).await +) -> Result<(), tx::Error> { + let args = args::Tx { + chain_id: args + .clone() + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())), + ..args.clone() }; - let epoch = rpc::query_and_print_epoch(args::Query { - ledger_address: args.ledger_address.clone(), - }) - .await; - let to_broadcast = if args.dry_run { - TxBroadcastData::DryRun(tx) - } else { - super::signing::sign_wrapper( - ctx, - args, - epoch, - tx, - &keypair, - #[cfg(not(feature = "mainnet"))] - false, - ) + tx::submit_reveal_pk_aux::(client, &mut ctx.wallet, public_key, &args) .await - }; - - if args.dry_run { - if let TxBroadcastData::DryRun(tx) = to_broadcast { - rpc::dry_run_tx(&args.ledger_address, tx.to_bytes()).await; - } else { - panic!( - "Expected a dry-run transaction, received a wrapper \ - transaction instead" - ); - } - } else { - // Either broadcast or submit transaction and collect result into - // sum type - let result = if args.broadcast_only { - Left(broadcast_tx(args.ledger_address.clone(), &to_broadcast).await) - } else { - Right(submit_tx(args.ledger_address.clone(), to_broadcast).await) - }; - // Return result based on executed operation, otherwise deal with - // the encountered errors uniformly - match result { - Right(Err(err)) => { - eprintln!( - "Encountered error while broadcasting transaction: {}", - err - ); - safe_exit(1) - } - Left(Err(err)) => { - eprintln!( - "Encountered error while broadcasting transaction: {}", - err - ); - safe_exit(1) - } - _ => {} - } - } } /// Check if current epoch is in the last third of the voting period of the -/// proposal. This ensures that it is safe to optimize the vote writing to -/// storage. -async fn is_safe_voting_window( - ledger_address: TendermintAddress, - client: &HttpClient, - proposal_id: u64, - proposal_start_epoch: Epoch, -) -> bool { - let current_epoch = - rpc::query_and_print_epoch(args::Query { ledger_address }).await; - - let proposal_end_epoch_key = - gov_storage::get_voting_end_epoch_key(proposal_id); - let proposal_end_epoch = - rpc::query_storage_value::(client, &proposal_end_epoch_key) - .await; - - match proposal_end_epoch { - Some(proposal_end_epoch) => { - !namada::ledger::native_vp::governance::utils::is_valid_validator_voting_period( - current_epoch, - proposal_start_epoch, - proposal_end_epoch, - ) - } - None => { - eprintln!("Proposal end epoch is not in the storage."); - safe_exit(1) - } - } +/// proposal. This ensures that it is safe to optimize the vote writing to +/// storage. +async fn is_safe_voting_window( + client: &C, + proposal_id: u64, + proposal_start_epoch: Epoch, +) -> Result { + tx::is_safe_voting_window(client, proposal_id, proposal_start_epoch).await } /// Removes validators whose vote corresponds to that of the delegator (needless /// vote) -async fn filter_delegations( - client: &HttpClient, +async fn filter_delegations( + client: &C, delegations: HashSet
, proposal_id: u64, delegator_vote: &ProposalVote, @@ -2444,8 +911,10 @@ async fn filter_delegations( ); if let Some(validator_vote) = - rpc::query_storage_value::(client, &vote_key) - .await + rpc::query_storage_value::( + client, &vote_key, + ) + .await { if &validator_vote == delegator_vote { return None; @@ -2459,572 +928,106 @@ async fn filter_delegations( delegations.into_iter().flatten().collect() } -pub async fn submit_bond(ctx: Context, args: args::Bond) { - let validator = ctx.get(&args.validator); - - // Check that the validator address exists on chain - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - let is_validator = rpc::is_validator(&client, &validator).await; - if !is_validator { - eprintln!( - "The address {} doesn't belong to any known validator account.", - validator - ); - if !args.tx.force { - safe_exit(1) - } - } - let source = ctx.get_opt(&args.source); - // Check that the source address exists on chain - if let Some(source) = &source { - let source_exists = - rpc::known_address(source, args.tx.ledger_address.clone()).await; - if !source_exists { - eprintln!("The source address {} doesn't exist on chain.", source); - if !args.tx.force { - safe_exit(1) - } - } - if source != &validator && rpc::is_validator(&client, source).await { - eprintln!( - "Cannot bond from a validator account {source} to another \ - validator {validator}." - ); - if !args.tx.force { - safe_exit(1) - } - } - } - // Check bond's source (source for delegation or validator for self-bonds) - // balance - let bond_source = source.as_ref().unwrap_or(&validator); - let balance_key = token::balance_key(&ctx.native_token, bond_source); - match rpc::query_storage_value::(&client, &balance_key).await - { - Some(balance) => { - println!("Found source balance {}", balance); - if balance < args.amount { - eprintln!( - "The balance of the source {} is lower than the amount to \ - be transferred. Amount to transfer is {} and the balance \ - is {}.", - bond_source, args.amount, balance - ); - if !args.tx.force { - safe_exit(1) - } - } - } - None => { - eprintln!("No balance found for the source {}", bond_source); - if !args.tx.force { - safe_exit(1) - } - } - } - let tx_code_hash = - query_wasm_code_hash(TX_BOND_WASM, args.tx.ledger_address.clone()) - .await - .unwrap(); - let bond = pos::Bond { - validator, - amount: args.amount, - source, - }; - let data = bond.try_to_vec().expect("Encoding tx data shouldn't fail"); - - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - let default_signer = args.source.unwrap_or(args.validator); - process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(default_signer), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; +pub async fn submit_bond( + client: &C, + ctx: &mut Context, + mut args: args::Bond, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_bond::(client, &mut ctx.wallet, args).await } -pub async fn submit_unbond(ctx: Context, args: args::Unbond) { - let validator = ctx.get(&args.validator); - let source = ctx.get_opt(&args.source); - - // Check that the validator address exists on chain - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - let is_validator = rpc::is_validator(&client, &validator).await; - if !is_validator { - eprintln!( - "The address {} doesn't belong to any known validator account.", - validator - ); - if !args.tx.force { - safe_exit(1) - } - } - - // Check the source's current bond amount - let bond_source = source.clone().unwrap_or_else(|| validator.clone()); - let bond_amount = - rpc::query_bond(&client, &bond_source, &validator, None).await; - println!("Bond amount available for unbonding: {} NAM", bond_amount); - - if args.amount > bond_amount { - eprintln!( - "The total bonds of the source {} is lower than the amount to be \ - unbonded. Amount to unbond is {} and the total bonds is {}.", - bond_source, args.amount, bond_amount - ); - if !args.tx.force { - safe_exit(1) - } - } - - // Query the unbonds before submitting the tx - let unbonds = - rpc::query_unbond_with_slashing(&client, &bond_source, &validator) - .await; - let mut withdrawable = BTreeMap::::new(); - for ((_start_epoch, withdraw_epoch), amount) in unbonds.into_iter() { - let to_withdraw = withdrawable.entry(withdraw_epoch).or_default(); - *to_withdraw += amount; - } - let latest_withdrawal_pre = withdrawable.into_iter().last(); - - let data = pos::Unbond { - validator: validator.clone(), - amount: args.amount, - source: Some(bond_source.clone()), - }; - let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); - - let tx_code_hash = - query_wasm_code_hash(TX_UNBOND_WASM, args.tx.ledger_address.clone()) - .await - .unwrap(); - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - let default_signer = args.source.unwrap_or(args.validator); - let (_ctx, _) = process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(default_signer), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; - - // Query the unbonds post-tx - let unbonds = - rpc::query_unbond_with_slashing(&client, &bond_source, &validator) - .await; - let mut withdrawable = BTreeMap::::new(); - for ((_start_epoch, withdraw_epoch), amount) in unbonds.into_iter() { - let to_withdraw = withdrawable.entry(withdraw_epoch).or_default(); - *to_withdraw += amount; - } - let (latest_withdraw_epoch_post, latest_withdraw_amount_post) = - withdrawable.into_iter().last().unwrap(); - - if let Some((latest_withdraw_epoch_pre, latest_withdraw_amount_pre)) = - latest_withdrawal_pre - { - match latest_withdraw_epoch_post.cmp(&latest_withdraw_epoch_pre) { - std::cmp::Ordering::Less => { - eprintln!( - "Unexpected behavior reading the unbonds data has occurred" - ); - if !args.tx.force { - safe_exit(1) - } - } - std::cmp::Ordering::Equal => { - println!( - "Amount {} withdrawable starting from epoch {}", - latest_withdraw_amount_post - latest_withdraw_amount_pre, - latest_withdraw_epoch_post - ); - } - std::cmp::Ordering::Greater => { - println!( - "Amount {} withdrawable starting from epoch {}", - latest_withdraw_amount_post, latest_withdraw_epoch_post - ); - } - } - } else { - println!( - "Amount {} withdrawable starting from epoch {}", - latest_withdraw_amount_post, latest_withdraw_epoch_post - ); - } +pub async fn submit_unbond( + client: &C, + ctx: &mut Context, + mut args: args::Unbond, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_unbond::(client, &mut ctx.wallet, args).await } -pub async fn submit_withdraw(ctx: Context, args: args::Withdraw) { - let validator = ctx.get(&args.validator); - let source = ctx.get_opt(&args.source); - - let epoch = rpc::query_and_print_epoch(args::Query { - ledger_address: args.tx.ledger_address.clone(), - }) - .await; - - // Check that the validator address exists on chain - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - let is_validator = rpc::is_validator(&client, &validator).await; - if !is_validator { - eprintln!( - "The address {} doesn't belong to any known validator account.", - validator - ); - if !args.tx.force { - safe_exit(1) - } - } - - // Check the source's current unbond amount - let bond_source = source.clone().unwrap_or_else(|| validator.clone()); - let tokens = rpc::query_withdrawable_tokens( - &client, - &bond_source, - &validator, - Some(epoch), - ) - .await; - if tokens == 0.into() { - eprintln!( - "There are no unbonded bonds ready to withdraw in the current \ - epoch {}.", - epoch - ); - rpc::query_and_print_unbonds(&client, &bond_source, &validator).await; - if !args.tx.force { - safe_exit(1) - } - } else { - println!("Found {tokens} tokens that can be withdrawn."); - println!("Submitting transaction to withdraw them..."); - } - - let data = pos::Withdraw { validator, source }; - let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); - - let tx_code_hash = - query_wasm_code_hash(TX_WITHDRAW_WASM, args.tx.ledger_address.clone()) - .await - .unwrap(); - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - let default_signer = args.source.unwrap_or(args.validator); - process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(default_signer), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; +pub async fn submit_withdraw( + client: &C, + mut ctx: Context, + mut args: args::Withdraw, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_withdraw::(client, &mut ctx.wallet, args).await } -pub async fn submit_validator_commission_change( - ctx: Context, - args: args::TxCommissionRateChange, -) { - let epoch = rpc::query_and_print_epoch(args::Query { - ledger_address: args.tx.ledger_address.clone(), - }) - .await; - - let tx_code_hash = query_wasm_code_hash( - TX_CHANGE_COMMISSION_WASM, - args.tx.ledger_address.clone(), +pub async fn submit_validator_commission_change< + C: namada::ledger::queries::Client + Sync, +>( + client: &C, + mut ctx: Context, + mut args: args::TxCommissionRateChange, +) -> Result<(), tx::Error> { + args.tx.chain_id = args + .tx + .chain_id + .or_else(|| Some(ctx.config.ledger.chain_id.clone())); + tx::submit_validator_commission_change::( + client, + &mut ctx.wallet, + args, ) .await - .unwrap(); - let client = HttpClient::new(args.tx.ledger_address.clone()).unwrap(); - - // TODO: put following two let statements in its own function - let params_key = namada::ledger::pos::params_key(); - let params = query_storage_value::(&client, ¶ms_key) - .await - .expect("Parameter should be defined."); - - let validator = ctx.get(&args.validator); - if rpc::is_validator(&client, &validator).await { - if args.rate < Decimal::ZERO || args.rate > Decimal::ONE { - eprintln!("Invalid new commission rate, received {}", args.rate); - if !args.tx.force { - safe_exit(1) - } - } - - let pipeline_epoch_minus_one = epoch + params.pipeline_len - 1; - - match rpc::query_commission_rate( - &client, - &validator, - Some(pipeline_epoch_minus_one), - ) - .await - { - Some(CommissionPair { - commission_rate, - max_commission_change_per_epoch, - }) => { - if (args.rate - commission_rate).abs() - > max_commission_change_per_epoch - { - eprintln!( - "New rate is too large of a change with respect to \ - the predecessor epoch in which the rate will take \ - effect." - ); - if !args.tx.force { - safe_exit(1) - } - } - } - None => { - eprintln!("Error retrieving from storage"); - if !args.tx.force { - safe_exit(1) - } - } - } - } else { - eprintln!("The given address {validator} is not a validator."); - if !args.tx.force { - safe_exit(1) - } - } - - let data = pos::CommissionChange { - validator: ctx.get(&args.validator), - new_rate: args.rate, - }; - let data = data.try_to_vec().expect("Encoding tx data shouldn't fail"); - - let tx = Tx::new( - tx_code_hash.to_vec(), - Some(data), - ctx.config.ledger.chain_id.clone(), - args.tx.expiration, - ); - let default_signer = args.validator; - process_tx( - ctx, - &args.tx, - tx, - TxSigningKey::WalletAddress(default_signer), - #[cfg(not(feature = "mainnet"))] - false, - ) - .await; -} - -/// Capture the result of running a transaction -enum ProcessTxResponse { - /// Result of submitting a transaction to the blockchain - Applied(TxResponse), - /// Result of submitting a transaction to the mempool - Broadcast(Response), - /// Result of dry running transaction - DryRun, -} - -impl ProcessTxResponse { - /// Get the the accounts that were reported to be initialized - fn initialized_accounts(&self) -> Vec
{ - match self { - Self::Applied(result) => result.initialized_accounts.clone(), - _ => vec![], - } - } } /// Submit transaction and wait for result. Returns a list of addresses /// initialized in the transaction if any. In dry run, this is always empty. -async fn process_tx( - ctx: Context, +async fn process_tx( + client: &C, + mut ctx: Context, args: &args::Tx, tx: Tx, default_signer: TxSigningKey, #[cfg(not(feature = "mainnet"))] requires_pow: bool, -) -> (Context, ProcessTxResponse) { - let (ctx, to_broadcast) = sign_tx( - ctx, +) -> Result<(Context, Vec
), tx::Error> { + let args = args::Tx { + chain_id: args.clone().chain_id.or_else(|| Some(tx.chain_id.clone())), + ..args.clone() + }; + let res: Vec
= tx::process_tx::( + client, + &mut ctx.wallet, + &args, tx, - args, default_signer, #[cfg(not(feature = "mainnet"))] requires_pow, ) - .await; - // NOTE: use this to print the request JSON body: - - // let request = - // tendermint_rpc::endpoint::broadcast::tx_commit::Request::new( - // tx_bytes.clone().into(), - // ); - // use tendermint_rpc::Request; - // let request_body = request.into_json(); - // println!("HTTP request body: {}", request_body); - - if args.dry_run { - if let TxBroadcastData::DryRun(tx) = to_broadcast { - rpc::dry_run_tx(&args.ledger_address, tx.to_bytes()).await; - (ctx, ProcessTxResponse::DryRun) - } else { - panic!( - "Expected a dry-run transaction, received a wrapper \ - transaction instead" - ); - } - } else { - // Either broadcast or submit transaction and collect result into - // sum type - if args.broadcast_only { - match broadcast_tx(args.ledger_address.clone(), &to_broadcast).await - { - Ok(resp) => (ctx, ProcessTxResponse::Broadcast(resp)), - Err(err) => { - eprintln!( - "Encountered error while broadcasting transaction: {}", - err - ); - safe_exit(1) - } - } - } else { - match submit_tx(args.ledger_address.clone(), to_broadcast).await { - Ok(result) => (ctx, ProcessTxResponse::Applied(result)), - Err(err) => { - eprintln!( - "Encountered error while broadcasting transaction: {}", - err - ); - safe_exit(1) - } - } - } - } + .await?; + Ok((ctx, res)) } /// Save accounts initialized from a tx into the wallet, if any. -async fn save_initialized_accounts( - mut ctx: Context, +pub async fn save_initialized_accounts( + wallet: &mut Wallet, args: &args::Tx, initialized_accounts: Vec
, ) { - let len = initialized_accounts.len(); - if len != 0 { - // Store newly initialized account addresses in the wallet - println!( - "The transaction initialized {} new account{}", - len, - if len == 1 { "" } else { "s" } - ); - // Store newly initialized account addresses in the wallet - let wallet = &mut ctx.wallet; - for (ix, address) in initialized_accounts.iter().enumerate() { - let encoded = address.encode(); - let alias: Cow = match &args.initialized_account_alias { - Some(initialized_account_alias) => { - if len == 1 { - // If there's only one account, use the - // alias as is - initialized_account_alias.into() - } else { - // If there're multiple accounts, use - // the alias as prefix, followed by - // index number - format!("{}{}", initialized_account_alias, ix).into() - } - } - None => { - print!("Choose an alias for {}: ", encoded); - io::stdout().flush().await.unwrap(); - let mut alias = String::new(); - io::stdin().read_line(&mut alias).await.unwrap(); - alias.trim().to_owned().into() - } - }; - let alias = alias.into_owned(); - let added = wallet.add_address(alias.clone(), address.clone()); - match added { - Some(new_alias) if new_alias != encoded => { - println!( - "Added alias {} for address {}.", - new_alias, encoded - ); - } - _ => println!("No alias added for address {}.", encoded), - }; - } - if !args.dry_run { - wallet.save().unwrap_or_else(|err| eprintln!("{}", err)); - } else { - println!("Transaction dry run. No addresses have been saved.") - } - } + tx::save_initialized_accounts::(wallet, args, initialized_accounts).await } /// Broadcast a transaction to be included in the blockchain and checks that /// the tx has been successfully included into the mempool of a validator /// /// In the case of errors in any of those stages, an error message is returned -pub async fn broadcast_tx( - address: TendermintAddress, +pub async fn broadcast_tx( + rpc_cli: &C, to_broadcast: &TxBroadcastData, -) -> Result { - let (tx, wrapper_tx_hash, decrypted_tx_hash) = match to_broadcast { - TxBroadcastData::Wrapper { - tx, - wrapper_hash, - decrypted_hash, - } => (tx, wrapper_hash, decrypted_hash), - _ => panic!("Cannot broadcast a dry-run transaction"), - }; - - tracing::debug!( - tendermint_rpc_address = ?address, - transaction = ?to_broadcast, - "Broadcasting transaction", - ); - let rpc_cli = HttpClient::new(address)?; - - // TODO: configure an explicit timeout value? we need to hack away at - // `tendermint-rs` for this, which is currently using a hard-coded 30s - // timeout. - let response = rpc_cli.broadcast_tx_sync(tx.to_bytes().into()).await?; - - if response.code == 0.into() { - println!("Transaction added to mempool: {:?}", response); - // Print the transaction identifiers to enable the extraction of - // acceptance/application results later - { - println!("Wrapper transaction hash: {:?}", wrapper_tx_hash); - println!("Inner transaction hash: {:?}", decrypted_tx_hash); - } - Ok(response) - } else { - Err(RpcError::server(serde_json::to_string(&response).unwrap())) - } +) -> Result { + tx::broadcast_tx(rpc_cli, to_broadcast).await } /// Broadcast a transaction to be included in the blockchain. @@ -3035,72 +1038,9 @@ pub async fn broadcast_tx( /// 3. The decrypted payload of the tx has been included on the blockchain. /// /// In the case of errors in any of those stages, an error message is returned -pub async fn submit_tx( - address: TendermintAddress, +pub async fn submit_tx( + client: &C, to_broadcast: TxBroadcastData, -) -> Result { - let (_, wrapper_hash, decrypted_hash) = match &to_broadcast { - TxBroadcastData::Wrapper { - tx, - wrapper_hash, - decrypted_hash, - } => (tx, wrapper_hash, decrypted_hash), - _ => panic!("Cannot broadcast a dry-run transaction"), - }; - - // Broadcast the supplied transaction - broadcast_tx(address.clone(), &to_broadcast).await?; - - let max_wait_time = Duration::from_secs( - env::var(ENV_VAR_NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS) - .ok() - .and_then(|val| val.parse().ok()) - .unwrap_or(DEFAULT_NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS), - ); - let deadline = Instant::now() + max_wait_time; - - tracing::debug!( - tendermint_rpc_address = ?address, - transaction = ?to_broadcast, - ?deadline, - "Awaiting transaction approval", - ); - - let parsed = { - let wrapper_query = rpc::TxEventQuery::Accepted(wrapper_hash.as_str()); - let event = - rpc::query_tx_status(wrapper_query, address.clone(), deadline) - .await; - let parsed = TxResponse::from_event(event); - - println!( - "Transaction accepted with result: {}", - serde_json::to_string_pretty(&parsed).unwrap() - ); - // The transaction is now on chain. We wait for it to be decrypted - // and applied - if parsed.code == 0.to_string() { - // We also listen to the event emitted when the encrypted - // payload makes its way onto the blockchain - let decrypted_query = - rpc::TxEventQuery::Applied(decrypted_hash.as_str()); - let event = - rpc::query_tx_status(decrypted_query, address, deadline).await; - let parsed = TxResponse::from_event(event); - println!( - "Transaction applied with result: {}", - serde_json::to_string_pretty(&parsed).unwrap() - ); - Ok(parsed) - } else { - Ok(parsed) - } - }; - - tracing::debug!( - transaction = ?to_broadcast, - "Transaction approved", - ); - - parsed +) -> Result { + tx::submit_tx(client, to_broadcast).await } diff --git a/apps/src/lib/client/utils.rs b/apps/src/lib/client/utils.rs index a73df375b1..e48188ef65 100644 --- a/apps/src/lib/client/utils.rs +++ b/apps/src/lib/client/utils.rs @@ -10,6 +10,7 @@ use borsh::BorshSerialize; use flate2::read::GzDecoder; use flate2::write::GzEncoder; use flate2::Compression; +use namada::ledger::wallet::Wallet; use namada::types::address; use namada::types::chain::ChainId; use namada::types::key::*; @@ -30,7 +31,7 @@ use crate::config::{self, Config, TendermintMode}; use crate::facade::tendermint::node::Id as TendermintNodeId; use crate::facade::tendermint_config::net::Address as TendermintAddress; use crate::node::ledger::tendermint_node; -use crate::wallet::{pre_genesis, Wallet}; +use crate::wallet::{pre_genesis, read_and_confirm_pwd, CliWalletUtils}; use crate::wasm_loader; pub const NET_ACCOUNTS_DIR: &str = "setup"; @@ -107,13 +108,12 @@ pub async fn join_network( validator_alias_and_dir.map(|(validator_alias, pre_genesis_dir)| { ( validator_alias, - pre_genesis::ValidatorWallet::load(&pre_genesis_dir) - .unwrap_or_else(|err| { - eprintln!( - "Error loading validator pre-genesis wallet {err}", - ); - cli::safe_exit(1) - }), + pre_genesis::load(&pre_genesis_dir).unwrap_or_else(|err| { + eprintln!( + "Error loading validator pre-genesis wallet {err}", + ); + cli::safe_exit(1) + }), ) }); @@ -275,7 +275,7 @@ pub async fn join_network( } let mut wallet = - Wallet::load_or_new_from_genesis(&chain_dir, genesis_config); + crate::wallet::load_or_new_from_genesis(&chain_dir, genesis_config); let address = wallet .find_address(&validator_alias) @@ -313,7 +313,7 @@ pub async fn join_network( pre_genesis_wallet, ); - wallet.save().unwrap(); + crate::wallet::save(&wallet).unwrap(); // Update the config from the default non-validator settings to // validator settings @@ -492,7 +492,7 @@ pub fn init_network( // Generate the consensus, account and reward keys, unless they're // pre-defined. - let mut wallet = Wallet::load_or_new(&chain_dir); + let mut wallet = crate::wallet::load_or_new(&chain_dir); let consensus_pk = try_parse_public_key( format!("validator {name} consensus key"), @@ -501,11 +501,9 @@ pub fn init_network( .unwrap_or_else(|| { let alias = format!("{}-consensus-key", name); println!("Generating validator {} consensus key...", name); - let (_alias, keypair) = wallet.gen_key( - SchemeType::Ed25519, - Some(alias), - unsafe_dont_encrypt, - ); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); + let (_alias, keypair) = + wallet.gen_key(SchemeType::Ed25519, Some(alias), password); // Write consensus key for Tendermint tendermint_node::write_validator_key(&tm_home_dir, &keypair); @@ -520,11 +518,9 @@ pub fn init_network( .unwrap_or_else(|| { let alias = format!("{}-account-key", name); println!("Generating validator {} account key...", name); - let (_alias, keypair) = wallet.gen_key( - SchemeType::Ed25519, - Some(alias), - unsafe_dont_encrypt, - ); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); + let (_alias, keypair) = + wallet.gen_key(SchemeType::Ed25519, Some(alias), password); keypair.ref_to() }); @@ -535,11 +531,9 @@ pub fn init_network( .unwrap_or_else(|| { let alias = format!("{}-protocol-key", name); println!("Generating validator {} protocol signing key...", name); - let (_alias, keypair) = wallet.gen_key( - SchemeType::Ed25519, - Some(alias), - unsafe_dont_encrypt, - ); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); + let (_alias, keypair) = + wallet.gen_key(SchemeType::Ed25519, Some(alias), password); keypair.ref_to() }); @@ -559,12 +553,12 @@ pub fn init_network( name ); - let validator_keys = wallet - .gen_validator_keys( - Some(protocol_pk.clone()), - SchemeType::Ed25519, - ) - .expect("Generating new validator keys should not fail"); + let validator_keys = crate::wallet::gen_validator_keys( + &mut wallet, + Some(protocol_pk.clone()), + SchemeType::Ed25519, + ) + .expect("Generating new validator keys should not fail"); let pk = validator_keys.dkg_keypair.as_ref().unwrap().public(); wallet.add_validator_data(address.clone(), validator_keys); pk @@ -584,12 +578,12 @@ pub fn init_network( // Write keypairs to wallet wallet.add_address(name.clone(), address); - wallet.save().unwrap(); + crate::wallet::save(&wallet).unwrap(); }); // Create a wallet for all accounts other than validators let mut wallet = - Wallet::load_or_new(&accounts_dir.join(NET_OTHER_ACCOUNTS_DIR)); + crate::wallet::load_or_new(&accounts_dir.join(NET_OTHER_ACCOUNTS_DIR)); if let Some(established) = &mut config.established { established.iter_mut().for_each(|(name, config)| { init_established_account( @@ -619,10 +613,11 @@ pub fn init_network( "Generating implicit account {} key and address ...", name ); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); let (_alias, keypair) = wallet.gen_key( SchemeType::Ed25519, Some(name.clone()), - unsafe_dont_encrypt, + password, ); let public_key = genesis_config::HexString(keypair.ref_to().to_string()); @@ -655,8 +650,8 @@ pub fn init_network( genesis_config::write_genesis_config(&config_clean, &genesis_path); // Add genesis addresses and save the wallet with other account keys - wallet.add_genesis_addresses(config_clean.clone()); - wallet.save().unwrap(); + crate::wallet::add_genesis_addresses(&mut wallet, config_clean.clone()); + crate::wallet::save(&wallet).unwrap(); // Write the global config setting the default chain ID let global_config = GlobalConfig::new(chain_id.clone()); @@ -705,9 +700,9 @@ pub fn init_network( ); global_config.write(validator_dir).unwrap(); // Add genesis addresses to the validator's wallet - let mut wallet = Wallet::load_or_new(&validator_chain_dir); - wallet.add_genesis_addresses(config_clean.clone()); - wallet.save().unwrap(); + let mut wallet = crate::wallet::load_or_new(&validator_chain_dir); + crate::wallet::add_genesis_addresses(&mut wallet, config_clean.clone()); + crate::wallet::save(&wallet).unwrap(); }); // Generate the validators' ledger config @@ -858,7 +853,7 @@ pub fn init_network( fn init_established_account( name: impl AsRef, - wallet: &mut Wallet, + wallet: &mut Wallet, config: &mut genesis_config::EstablishedAccountConfig, unsafe_dont_encrypt: bool, ) { @@ -869,10 +864,11 @@ fn init_established_account( } if config.public_key.is_none() { println!("Generating established account {} key...", name.as_ref()); + let password = read_and_confirm_pwd(unsafe_dont_encrypt); let (_alias, keypair) = wallet.gen_key( SchemeType::Ed25519, Some(format!("{}-key", name.as_ref())), - unsafe_dont_encrypt, + password, ); let public_key = genesis_config::HexString(keypair.ref_to().to_string()); @@ -924,7 +920,7 @@ pub fn init_genesis_validator( let pre_genesis_dir = validator_pre_genesis_dir(&global_args.base_dir, &alias); println!("Generating validator keys..."); - let pre_genesis = pre_genesis::ValidatorWallet::gen_and_store( + let pre_genesis = pre_genesis::gen_and_store( key_scheme, unsafe_dont_encrypt, &pre_genesis_dir, diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index 8c617e396b..3f69be490e 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -57,6 +57,7 @@ use num_traits::{FromPrimitive, ToPrimitive}; use thiserror::Error; use tokio::sync::mpsc::UnboundedSender; +use crate::config; use crate::config::{genesis, TendermintMode}; #[cfg(feature = "abcipp")] use crate::facade::tendermint_proto::abci::response_verify_vote_extension::VerifyStatus; @@ -71,7 +72,6 @@ use crate::node::ledger::shims::abcipp_shim_types::shim::response::TxResult; use crate::node::ledger::{storage, tendermint_node}; #[allow(unused_imports)] use crate::wallet::ValidatorData; -use crate::{config, wallet}; fn key_to_tendermint( pk: &common::PublicKey, @@ -331,7 +331,7 @@ where "{}", wallet_path.as_path().to_str().unwrap() ); - let wallet = wallet::Wallet::load_or_new_from_genesis( + let mut wallet = crate::wallet::load_or_new_from_genesis( wallet_path, genesis::genesis_config::open_genesis_config( genesis_path, @@ -341,7 +341,7 @@ where wallet .take_validator_data() .map(|data| ShellMode::Validator { - data, + data: data.clone(), broadcast_sender, }) .expect( @@ -351,11 +351,13 @@ where } #[cfg(feature = "dev")] { - let validator_keys = wallet::defaults::validator_keys(); + let validator_keys = + crate::wallet::defaults::validator_keys(); ShellMode::Validator { - data: wallet::ValidatorData { - address: wallet::defaults::validator_address(), - keys: wallet::ValidatorKeys { + data: crate::wallet::ValidatorData { + address: crate::wallet::defaults::validator_address( + ), + keys: crate::wallet::ValidatorKeys { protocol_keypair: validator_keys.0, dkg_keypair: Some(validator_keys.1), }, @@ -837,7 +839,7 @@ where let genesis_path = &self .base_dir .join(format!("{}.toml", self.chain_id.as_str())); - let mut wallet = wallet::Wallet::load_or_new_from_genesis( + let mut wallet = crate::wallet::load_or_new_from_genesis( wallet_path, genesis::genesis_config::open_genesis_config(genesis_path).unwrap(), ); @@ -854,7 +856,7 @@ where it's established account", ); let pk = sk.ref_to(); - wallet.find_key_by_pk(&pk).expect( + wallet.find_key_by_pk(&pk, None).expect( "A validator's established keypair should be stored in its \ wallet", ) diff --git a/apps/src/lib/node/ledger/shims/abcipp_shim.rs b/apps/src/lib/node/ledger/shims/abcipp_shim.rs index dff8ab7136..05ffbf8de0 100644 --- a/apps/src/lib/node/ledger/shims/abcipp_shim.rs +++ b/apps/src/lib/node/ledger/shims/abcipp_shim.rs @@ -5,6 +5,7 @@ use std::pin::Pin; use std::task::{Context, Poll}; use futures::future::FutureExt; +use namada::proto::Tx; use namada::types::address::Address; #[cfg(not(feature = "abcipp"))] use namada::types::hash::Hash; @@ -25,7 +26,11 @@ use super::abcipp_shim_types::shim::{Error, Request, Response}; use crate::config; use crate::config::{Action, ActionAtHeight}; #[cfg(not(feature = "abcipp"))] -use crate::facade::tendermint_proto::abci::RequestBeginBlock; +use crate::facade::tendermint_proto::abci::{ + RequestBeginBlock, ResponseDeliverTx, +}; +#[cfg(not(feature = "abcipp"))] +use crate::facade::tower_abci::response::DeliverTx; use crate::facade::tower_abci::{BoxError, Request as Req, Response as Resp}; /// The shim wraps the shell, which implements ABCI++. @@ -146,8 +151,14 @@ impl AbcippShim { } #[cfg(not(feature = "abcipp"))] Req::DeliverTx(tx) => { + let mut deliver: DeliverTx = Default::default(); + // Attach events to this transaction if possible + if let Ok(tx) = Tx::try_from(&tx.tx[..]) { + let resp: ResponseDeliverTx = tx.into(); + deliver.events = resp.events; + } self.delivered_txs.push(tx.tx); - Ok(Resp::DeliverTx(Default::default())) + Ok(Resp::DeliverTx(deliver)) } #[cfg(not(feature = "abcipp"))] Req::EndBlock(_) => { diff --git a/apps/src/lib/wallet/alias.rs b/apps/src/lib/wallet/alias.rs index 6998bf1894..e69de29bb2 100644 --- a/apps/src/lib/wallet/alias.rs +++ b/apps/src/lib/wallet/alias.rs @@ -1,103 +0,0 @@ -//! Wallet address and key aliases. - -use std::convert::Infallible; -use std::fmt::Display; -use std::hash::Hash; -use std::str::FromStr; - -use serde::{Deserialize, Serialize}; - -/// Aliases created from raw strings are kept in-memory as given, but their -/// `Serialize` and `Display` instance converts them to lowercase. Their -/// `PartialEq` instance is case-insensitive. -#[derive(Clone, Debug, Deserialize, PartialOrd, Ord, Eq)] -#[serde(transparent)] -pub struct Alias(String); - -impl Alias { - /// Normalize an alias to lower-case - pub fn normalize(&self) -> String { - self.0.to_lowercase() - } - - /// Returns the length of the underlying `String`. - pub fn len(&self) -> usize { - self.0.len() - } - - /// Is the underlying `String` empty? - pub fn is_empty(&self) -> bool { - self.0.is_empty() - } -} - -impl Serialize for Alias { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.normalize().serialize(serializer) - } -} - -impl PartialEq for Alias { - fn eq(&self, other: &Self) -> bool { - self.normalize() == other.normalize() - } -} - -impl Hash for Alias { - fn hash(&self, state: &mut H) { - self.normalize().hash(state); - } -} - -impl From for Alias -where - T: AsRef, -{ - fn from(raw: T) -> Self { - Self(raw.as_ref().to_owned()) - } -} - -impl From for String { - fn from(alias: Alias) -> Self { - alias.normalize() - } -} - -impl<'a> From<&'a Alias> for String { - fn from(alias: &'a Alias) -> Self { - alias.normalize() - } -} - -impl Display for Alias { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.normalize().fmt(f) - } -} - -impl FromStr for Alias { - type Err = Infallible; - - fn from_str(s: &str) -> Result { - Ok(Self(s.into())) - } -} - -/// Default alias of a validator's account key -pub fn validator_key(validator_alias: &Alias) -> Alias { - format!("{validator_alias}-validator-key").into() -} - -/// Default alias of a validator's consensus key -pub fn validator_consensus_key(validator_alias: &Alias) -> Alias { - format!("{validator_alias}-consensus-key").into() -} - -/// Default alias of a validator's Tendermint node key -pub fn validator_tendermint_node_key(validator_alias: &Alias) -> Alias { - format!("{validator_alias}-tendermint-node-key").into() -} diff --git a/apps/src/lib/wallet/defaults.rs b/apps/src/lib/wallet/defaults.rs index 5c9f4588b5..95d1fe035b 100644 --- a/apps/src/lib/wallet/defaults.rs +++ b/apps/src/lib/wallet/defaults.rs @@ -6,12 +6,12 @@ pub use dev::{ christel_address, christel_keypair, daewon_address, daewon_keypair, keys, validator_address, validator_keypair, validator_keys, }; +use namada::ledger::wallet::alias::Alias; use namada::ledger::{eth_bridge, governance, pos}; use namada::types::address::Address; use namada::types::key::*; use crate::config::genesis::genesis_config::GenesisConfig; -use crate::wallet::alias::Alias; /// The default addresses with their aliases. pub fn addresses_from_genesis(genesis: GenesisConfig) -> Vec<(Alias, Address)> { @@ -73,6 +73,7 @@ mod dev { use std::collections::HashMap; use borsh::BorshDeserialize; + use namada::ledger::wallet::alias::Alias; use namada::ledger::{governance, pos}; use namada::types::address::{ apfel, btc, dot, eth, kartoffel, nam, schnitzel, Address, @@ -80,8 +81,6 @@ mod dev { use namada::types::key::dkg_session_keys::DkgKeypair; use namada::types::key::*; - use crate::wallet::alias::Alias; - /// Generate a new protocol signing keypair and DKG session keypair pub fn validator_keys() -> (common::SecretKey, DkgKeypair) { let bytes: [u8; 33] = [ diff --git a/apps/src/lib/wallet/keys.rs b/apps/src/lib/wallet/keys.rs index 7627bd9b16..8b13789179 100644 --- a/apps/src/lib/wallet/keys.rs +++ b/apps/src/lib/wallet/keys.rs @@ -1,243 +1 @@ -//! Cryptographic keys for digital signatures support for the wallet. -use std::fmt::Display; -use std::marker::PhantomData; -use std::str::FromStr; - -use borsh::{BorshDeserialize, BorshSerialize}; -use data_encoding::HEXLOWER; -use orion::{aead, kdf}; -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -use super::read_password; - -const ENCRYPTED_KEY_PREFIX: &str = "encrypted:"; -const UNENCRYPTED_KEY_PREFIX: &str = "unencrypted:"; - -/// A keypair stored in a wallet -#[derive(Debug)] -pub enum StoredKeypair -where - ::Err: Display, -{ - /// An encrypted keypair - Encrypted(EncryptedKeypair), - /// An raw (unencrypted) keypair - Raw(T), -} - -impl Serialize - for StoredKeypair -where - ::Err: Display, -{ - fn serialize( - &self, - serializer: S, - ) -> std::result::Result - where - S: serde::Serializer, - { - // String encoded, because toml doesn't support enums - match self { - StoredKeypair::Encrypted(encrypted) => { - let keypair_string = - format!("{}{}", ENCRYPTED_KEY_PREFIX, encrypted); - serde::Serialize::serialize(&keypair_string, serializer) - } - StoredKeypair::Raw(raw) => { - let keypair_string = - format!("{}{}", UNENCRYPTED_KEY_PREFIX, raw); - serde::Serialize::serialize(&keypair_string, serializer) - } - } - } -} - -impl<'de, T: BorshSerialize + BorshDeserialize + Display + FromStr> - Deserialize<'de> for StoredKeypair -where - ::Err: Display, -{ - fn deserialize(deserializer: D) -> std::result::Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; - - let keypair_string: String = - serde::Deserialize::deserialize(deserializer) - .map_err(|err| { - DeserializeStoredKeypairError::InvalidStoredKeypairString( - err.to_string(), - ) - }) - .map_err(D::Error::custom)?; - if let Some(raw) = keypair_string.strip_prefix(UNENCRYPTED_KEY_PREFIX) { - FromStr::from_str(raw) - .map(|keypair| Self::Raw(keypair)) - .map_err(|err| { - DeserializeStoredKeypairError::InvalidStoredKeypairString( - err.to_string(), - ) - }) - .map_err(D::Error::custom) - } else if let Some(encrypted) = - keypair_string.strip_prefix(ENCRYPTED_KEY_PREFIX) - { - FromStr::from_str(encrypted) - .map(Self::Encrypted) - .map_err(|err| { - DeserializeStoredKeypairError::InvalidStoredKeypairString( - err.to_string(), - ) - }) - .map_err(D::Error::custom) - } else { - Err(DeserializeStoredKeypairError::MissingPrefix) - .map_err(D::Error::custom) - } - } -} - -#[allow(missing_docs)] -#[derive(Error, Debug)] -pub enum DeserializeStoredKeypairError { - #[error("The stored keypair is not valid: {0}")] - InvalidStoredKeypairString(String), - #[error("The stored keypair is missing a prefix")] - MissingPrefix, -} - -/// An encrypted keypair stored in a wallet -#[derive(Debug)] -pub struct EncryptedKeypair( - Vec, - PhantomData, -); - -impl Display for EncryptedKeypair { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", HEXLOWER.encode(self.0.as_ref())) - } -} - -impl FromStr for EncryptedKeypair { - type Err = data_encoding::DecodeError; - - fn from_str(s: &str) -> Result { - HEXLOWER.decode(s.as_ref()).map(|x| Self(x, PhantomData)) - } -} - -#[allow(missing_docs)] -#[derive(Debug, Error)] -pub enum DecryptionError { - #[error("Unexpected encryption salt")] - BadSalt, - #[error("Unable to decrypt the keypair. Is the password correct?")] - DecryptionError, - #[error("Unable to deserialize the keypair")] - DeserializingError, - #[error("Asked not to decrypt")] - NotDecrypting, -} - -impl - StoredKeypair -where - ::Err: Display, -{ - /// Construct a keypair for storage. If no password is provided, the keypair - /// will be stored raw without encryption. Returns the key for storing and a - /// reference-counting point to the raw key. - pub fn new(keypair: T, password: Option) -> (Self, T) { - match password { - Some(password) => ( - Self::Encrypted(EncryptedKeypair::new(&keypair, password)), - keypair, - ), - None => (Self::Raw(keypair.clone()), keypair), - } - } - - /// Get a raw keypair from a stored keypair. If the keypair is encrypted and - /// no password is provided in the argument, a password will be prompted - /// from stdin. - pub fn get( - &self, - decrypt: bool, - password: Option, - ) -> Result { - match self { - StoredKeypair::Encrypted(encrypted_keypair) => { - if decrypt { - let password = password.unwrap_or_else(|| { - read_password("Enter decryption password: ") - }); - let key = encrypted_keypair.decrypt(password)?; - Ok(key) - } else { - Err(DecryptionError::NotDecrypting) - } - } - StoredKeypair::Raw(keypair) => Ok(keypair.clone()), - } - } - - pub fn is_encrypted(&self) -> bool { - match self { - StoredKeypair::Encrypted(_) => true, - StoredKeypair::Raw(_) => false, - } - } -} - -impl EncryptedKeypair { - /// Encrypt a keypair and store it with its salt. - pub fn new(keypair: &T, password: String) -> Self { - let salt = encryption_salt(); - let encryption_key = encryption_key(&salt, password); - - let data = keypair - .try_to_vec() - .expect("Serializing keypair shouldn't fail"); - - let encrypted_keypair = aead::seal(&encryption_key, &data) - .expect("Encryption of data shouldn't fail"); - - let encrypted_data = [salt.as_ref(), &encrypted_keypair].concat(); - - Self(encrypted_data, PhantomData) - } - - /// Decrypt an encrypted keypair - pub fn decrypt(&self, password: String) -> Result { - let salt_len = encryption_salt().len(); - let (raw_salt, cipher) = self.0.split_at(salt_len); - - let salt = kdf::Salt::from_slice(raw_salt) - .map_err(|_| DecryptionError::BadSalt)?; - - let encryption_key = encryption_key(&salt, password); - - let decrypted_data = aead::open(&encryption_key, cipher) - .map_err(|_| DecryptionError::DecryptionError)?; - - T::try_from_slice(&decrypted_data) - .map_err(|_| DecryptionError::DeserializingError) - } -} - -/// Keypair encryption salt -fn encryption_salt() -> kdf::Salt { - kdf::Salt::default() -} - -/// Make encryption secret key from a password. -fn encryption_key(salt: &kdf::Salt, password: String) -> kdf::SecretKey { - kdf::Password::from_slice(password.as_bytes()) - .and_then(|password| kdf::derive_key(&password, salt, 3, 1 << 17, 32)) - .expect("Generation of encryption secret key shouldn't fail") -} diff --git a/apps/src/lib/wallet/mod.rs b/apps/src/lib/wallet/mod.rs index d823334a00..3c741e06c7 100644 --- a/apps/src/lib/wallet/mod.rs +++ b/apps/src/lib/wallet/mod.rs @@ -1,549 +1,213 @@ -mod alias; pub mod defaults; mod keys; pub mod pre_genesis; mod store; -use std::collections::{HashMap, HashSet}; -use std::fmt::Display; +use std::io::{self, Write}; use std::path::{Path, PathBuf}; -use std::str::FromStr; use std::{env, fs}; -use borsh::{BorshDeserialize, BorshSerialize}; -use masp_primitives::zip32::ExtendedFullViewingKey; -use namada::types::address::Address; -use namada::types::key::*; -use namada::types::masp::{ - ExtendedSpendingKey, ExtendedViewingKey, PaymentAddress, +pub use namada::ledger::wallet::alias::Alias; +use namada::ledger::wallet::{ + ConfirmationResponse, FindKeyError, Wallet, WalletUtils, +}; +pub use namada::ledger::wallet::{ + DecryptionError, StoredKeypair, ValidatorData, ValidatorKeys, }; +use namada::types::key::*; pub use store::wallet_file; -use thiserror::Error; -use self::alias::Alias; -pub use self::keys::{DecryptionError, StoredKeypair}; -use self::store::Store; -pub use self::store::{AddressVpType, ValidatorData, ValidatorKeys}; use crate::cli; use crate::config::genesis::genesis_config::GenesisConfig; #[derive(Debug)] -pub struct Wallet { - store_dir: PathBuf, - store: Store, - decrypted_key_cache: HashMap, - decrypted_spendkey_cache: HashMap, -} - -#[derive(Error, Debug)] -pub enum FindKeyError { - #[error("No matching key found")] - KeyNotFound, - #[error("{0}")] - KeyDecryptionError(keys::DecryptionError), -} - -impl Wallet { - /// Load a wallet from the store file. - pub fn load(store_dir: &Path) -> Option { - let store = Store::load(store_dir).unwrap_or_else(|err| { - eprintln!("Unable to load the wallet: {}", err); - cli::safe_exit(1) - }); - Some(Self { - store_dir: store_dir.to_path_buf(), - store, - decrypted_key_cache: HashMap::default(), - decrypted_spendkey_cache: HashMap::default(), - }) - } - - /// Load a wallet from the store file or create a new wallet without any - /// keys or addresses. - pub fn load_or_new(store_dir: &Path) -> Self { - let store = Store::load_or_new(store_dir).unwrap_or_else(|err| { - eprintln!("Unable to load the wallet: {}", err); - cli::safe_exit(1) - }); - Self { - store_dir: store_dir.to_path_buf(), - store, - decrypted_key_cache: HashMap::default(), - decrypted_spendkey_cache: HashMap::default(), - } - } - - /// Load a wallet from the store file or create a new one with the default - /// addresses loaded from the genesis file, if not found. - pub fn load_or_new_from_genesis( - store_dir: &Path, - genesis_cfg: GenesisConfig, - ) -> Self { - let store = Store::load_or_new_from_genesis(store_dir, genesis_cfg) - .unwrap_or_else(|err| { - eprintln!("Unable to load the wallet: {}", err); - cli::safe_exit(1) - }); - Self { - store_dir: store_dir.to_path_buf(), - store, - decrypted_key_cache: HashMap::default(), - decrypted_spendkey_cache: HashMap::default(), - } - } - - /// Add addresses from a genesis configuration. - pub fn add_genesis_addresses(&mut self, genesis: GenesisConfig) { - self.store.add_genesis_addresses(genesis) - } - - /// Save the wallet store to a file. - pub fn save(&self) -> std::io::Result<()> { - self.store.save(&self.store_dir) - } - - /// Prompt for pssword and confirm it if parameter is false - fn new_password_prompt(unsafe_dont_encrypt: bool) -> Option { - let password = if unsafe_dont_encrypt { - println!("Warning: The keypair will NOT be encrypted."); - None - } else { - Some(read_password("Enter your encryption password: ")) - }; - // Bis repetita for confirmation. - let pwd = if unsafe_dont_encrypt { - None - } else { - Some(read_password( - "To confirm, please enter the same encryption password once \ - more: ", - )) +pub struct CliWalletUtils; + +impl WalletUtils for CliWalletUtils { + type Storage = PathBuf; + + /// Read the password for encryption/decryption from the file/env/stdin. + /// Panics if all options are empty/invalid. + fn read_password(prompt_msg: &str) -> String { + let pwd = match env::var("NAMADA_WALLET_PASSWORD_FILE") { + Ok(path) => fs::read_to_string(path) + .expect("Something went wrong reading the file"), + Err(_) => match env::var("NAMADA_WALLET_PASSWORD") { + Ok(password) => password, + Err(_) => rpassword::read_password_from_tty(Some(prompt_msg)) + .unwrap_or_default(), + }, }; - if pwd != password { - eprintln!("Your two inputs do not match!"); + if pwd.is_empty() { + eprintln!("Password cannot be empty"); cli::safe_exit(1) } - password - } - - /// Generate a new keypair and derive an implicit address from its public - /// and insert them into the store with the provided alias, converted to - /// lower case. If none provided, the alias will be the public key hash (in - /// lowercase too). If the key is to be encrypted, will prompt for - /// password from stdin. Stores the key in decrypted key cache and - /// returns the alias of the key and a reference-counting pointer to the - /// key. - pub fn gen_key( - &mut self, - scheme: SchemeType, - alias: Option, - unsafe_dont_encrypt: bool, - ) -> (String, common::SecretKey) { - let password = read_and_confirm_pwd(unsafe_dont_encrypt); - let (alias, key) = self.store.gen_key(scheme, alias, password); - // Cache the newly added key - self.decrypted_key_cache.insert(alias.clone(), key.clone()); - (alias.into(), key) - } - - pub fn gen_spending_key( - &mut self, - alias: String, - unsafe_dont_encrypt: bool, - ) -> (String, ExtendedSpendingKey) { - let password = Self::new_password_prompt(unsafe_dont_encrypt); - let (alias, key) = self.store.gen_spending_key(alias, password); - // Cache the newly added key - self.decrypted_spendkey_cache.insert(alias.clone(), key); - (alias.into(), key) - } - - /// Generate keypair - /// for signing protocol txs and for the DKG (which will also be stored) - /// A protocol keypair may be optionally provided, indicating that - /// we should re-use a keypair already in the wallet - pub fn gen_validator_keys( - &mut self, - protocol_pk: Option, - scheme: SchemeType, - ) -> Result { - let protocol_keypair = protocol_pk.map(|pk| { - self.find_key_by_pkh(&PublicKeyHash::from(&pk)) - .ok() - .or_else(|| { - self.store - .validator_data - .take() - .map(|data| data.keys.protocol_keypair) - }) - .ok_or(FindKeyError::KeyNotFound) - }); - match protocol_keypair { - Some(Err(err)) => Err(err), - other => Ok(Store::gen_validator_keys( - other.map(|res| res.unwrap()), - scheme, - )), - } - } - - /// Add validator data to the store - pub fn add_validator_data( - &mut self, - address: Address, - keys: ValidatorKeys, - ) { - self.store.add_validator_data(address, keys); - } - - /// Returns the validator data, if it exists. - pub fn get_validator_data(&self) -> Option<&ValidatorData> { - self.store.get_validator_data() - } - - /// Returns the validator data, if it exists. - /// [`Wallet::save`] cannot be called after using this - /// method as it involves a partial move - pub fn take_validator_data(self) -> Option { - self.store.validator_data() - } - - /// Find the stored key by an alias, a public key hash or a public key. - /// If the key is encrypted, will prompt for password from stdin. - /// Any keys that are decrypted are stored in and read from a cache to avoid - /// prompting for password multiple times. - pub fn find_key( - &mut self, - alias_pkh_or_pk: impl AsRef, - ) -> Result { - // Try cache first - if let Some(cached_key) = self - .decrypted_key_cache - .get(&alias_pkh_or_pk.as_ref().into()) - { - return Ok(cached_key.clone()); - } - // If not cached, look-up in store - let stored_key = self - .store - .find_key(alias_pkh_or_pk.as_ref()) - .ok_or(FindKeyError::KeyNotFound)?; - Self::decrypt_stored_key( - &mut self.decrypted_key_cache, - stored_key, - alias_pkh_or_pk.into(), - ) - } - - pub fn find_spending_key( - &mut self, - alias: impl AsRef, - ) -> Result { - // Try cache first - if let Some(cached_key) = - self.decrypted_spendkey_cache.get(&alias.as_ref().into()) - { - return Ok(*cached_key); - } - // If not cached, look-up in store - let stored_spendkey = self - .store - .find_spending_key(alias.as_ref()) - .ok_or(FindKeyError::KeyNotFound)?; - Self::decrypt_stored_key( - &mut self.decrypted_spendkey_cache, - stored_spendkey, - alias.into(), - ) - } + pwd + } + + /// Read an alias from the file/env/stdin. + fn read_alias(prompt_msg: &str) -> String { + print!("Choose an alias for {}: ", prompt_msg); + io::stdout().flush().unwrap(); + let mut alias = String::new(); + io::stdin().read_line(&mut alias).unwrap(); + alias.trim().to_owned() + } + + // TODO: bring this back. removed in an evil merge change because e2e tests + // trigger it non-interactively; we will need to add a `--force` option to + // bypass it instead. + fn show_overwrite_confirmation( + _alias: &Alias, + _alias_for: &str, + ) -> ConfirmationResponse { + ConfirmationResponse::Replace + } + // The given alias has been selected but conflicts with another alias in + // the store. Offer the user to either replace existing mapping, alter the + // chosen alias to a name of their chosing, or cancel the aliasing. + // fn show_overwrite_confirmation( + // alias: &Alias, + // alias_for: &str, + // ) -> ConfirmationResponse { + // print!( + // "You're trying to create an alias \"{}\" that already exists for + // \ {} in your store.\nWould you like to replace it? \ + // s(k)ip/re(p)lace/re(s)elect: ", + // alias, alias_for + // ); + // io::stdout().flush().unwrap(); + // + // let mut buffer = String::new(); + // // Get the user to select between 3 choices + // match io::stdin().read_line(&mut buffer) { + // Ok(size) if size > 0 => { + // // Isolate the single character representing the choice + // let byte = buffer.chars().next().unwrap(); + // buffer.clear(); + // match byte { + // 'p' | 'P' => return ConfirmationResponse::Replace, + // 's' | 'S' => { + // // In the case of reselection, elicit new alias + // print!("Please enter a different alias: "); + // io::stdout().flush().unwrap(); + // if io::stdin().read_line(&mut buffer).is_ok() { + // return ConfirmationResponse::Reselect( + // buffer.trim().into(), + // ); + // } + // } + // 'k' | 'K' => return ConfirmationResponse::Skip, + // // Input is senseless fall through to repeat prompt + // _ => {} + // }; + // } + // _ => {} + // } + // // Input is senseless fall through to repeat prompt + // println!("Invalid option, try again."); + // Self::show_overwrite_confirmation(alias, alias_for) + // } +} - pub fn find_viewing_key( - &mut self, - alias: impl AsRef, - ) -> Result<&ExtendedViewingKey, FindKeyError> { - self.store - .find_viewing_key(alias.as_ref()) +/// Generate keypair +/// for signing protocol txs and for the DKG (which will also be stored) +/// A protocol keypair may be optionally provided, indicating that +/// we should re-use a keypair already in the wallet +pub fn gen_validator_keys( + wallet: &mut Wallet, + protocol_pk: Option, + scheme: SchemeType, +) -> Result { + let protocol_keypair = protocol_pk.map(|pk| { + wallet + .find_key_by_pkh(&PublicKeyHash::from(&pk), None) + .ok() + .or_else(|| { + wallet + .store_mut() + .validator_data() + .take() + .map(|data| data.keys.protocol_keypair.clone()) + }) .ok_or(FindKeyError::KeyNotFound) + }); + match protocol_keypair { + Some(Err(err)) => Err(err), + other => Ok(store::gen_validator_keys( + other.map(|res| res.unwrap()), + scheme, + )), } +} - pub fn find_payment_addr( - &self, - alias: impl AsRef, - ) -> Option<&PaymentAddress> { - self.store.find_payment_addr(alias.as_ref()) - } - - /// Find the stored key by a public key. - /// If the key is encrypted, will prompt for password from stdin. - /// Any keys that are decrypted are stored in and read from a cache to avoid - /// prompting for password multiple times. - pub fn find_key_by_pk( - &mut self, - pk: &common::PublicKey, - ) -> Result { - // Try to look-up alias for the given pk. Otherwise, use the PKH string. - let pkh: PublicKeyHash = pk.into(); - let alias = self - .store - .find_alias_by_pkh(&pkh) - .unwrap_or_else(|| pkh.to_string().into()); - // Try read cache - if let Some(cached_key) = self.decrypted_key_cache.get(&alias) { - return Ok(cached_key.clone()); - } - // Look-up from store - let stored_key = self - .store - .find_key_by_pk(pk) - .ok_or(FindKeyError::KeyNotFound)?; - Self::decrypt_stored_key( - &mut self.decrypted_key_cache, - stored_key, - alias, - ) - } - - /// Find the stored key by a public key hash. - /// If the key is encrypted, will prompt for password from stdin. - /// Any keys that are decrypted are stored in and read from a cache to avoid - /// prompting for password multiple times. - pub fn find_key_by_pkh( - &mut self, - pkh: &PublicKeyHash, - ) -> Result { - // Try to look-up alias for the given pk. Otherwise, use the PKH string. - let alias = self - .store - .find_alias_by_pkh(pkh) - .unwrap_or_else(|| pkh.to_string().into()); - // Try read cache - if let Some(cached_key) = self.decrypted_key_cache.get(&alias) { - return Ok(cached_key.clone()); - } - // Look-up from store - let stored_key = self - .store - .find_key_by_pkh(pkh) - .ok_or(FindKeyError::KeyNotFound)?; - Self::decrypt_stored_key( - &mut self.decrypted_key_cache, - stored_key, - alias, - ) - } - - /// Decrypt stored key, if it's not stored un-encrypted. - /// If a given storage key needs to be decrypted, prompt for password from - /// stdin and if successfully decrypted, store it in a cache. - fn decrypt_stored_key< - T: FromStr + Display + BorshSerialize + BorshDeserialize + Clone, - >( - decrypted_key_cache: &mut HashMap, - stored_key: &StoredKeypair, - alias: Alias, - ) -> Result - where - ::Err: Display, - { - match stored_key { - StoredKeypair::Encrypted(encrypted) => { - let password = read_password("Enter decryption password: "); - let key = encrypted - .decrypt(password) - .map_err(FindKeyError::KeyDecryptionError)?; - decrypted_key_cache.insert(alias.clone(), key); - decrypted_key_cache - .get(&alias) - .cloned() - .ok_or(FindKeyError::KeyNotFound) - } - StoredKeypair::Raw(raw) => Ok(raw.clone()), - } - } - - /// Get all known keys by their alias, paired with PKH, if known. - pub fn get_keys( - &self, - ) -> HashMap< - String, - (&StoredKeypair, Option<&PublicKeyHash>), - > { - self.store - .get_keys() - .into_iter() - .map(|(alias, value)| (alias.into(), value)) - .collect() - } - - /// Find the stored address by an alias. - pub fn find_address(&self, alias: impl AsRef) -> Option<&Address> { - self.store.find_address(alias) - } - - /// Find an alias by the address if it's in the wallet. - pub fn find_alias(&self, address: &Address) -> Option<&Alias> { - self.store.find_alias(address) - } - - /// Get all known addresses by their alias, paired with PKH, if known. - pub fn get_addresses(&self) -> HashMap { - self.store - .get_addresses() - .iter() - .map(|(alias, value)| (alias.into(), value.clone())) - .collect() - } - - /// Get all known payment addresses by their alias - pub fn get_payment_addrs(&self) -> HashMap { - self.store - .get_payment_addrs() - .iter() - .map(|(alias, value)| (alias.into(), *value)) - .collect() - } - - /// Get all known viewing keys by their alias - pub fn get_viewing_keys(&self) -> HashMap { - self.store - .get_viewing_keys() - .iter() - .map(|(alias, value)| (alias.into(), *value)) - .collect() - } - - /// Get all known viewing keys by their alias - pub fn get_spending_keys( - &self, - ) -> HashMap> { - self.store - .get_spending_keys() - .iter() - .map(|(alias, value)| (alias.into(), value)) - .collect() - } - - /// Add a new address with the given alias. If the alias is already used, - /// will ask whether the existing alias should be replaced, a different - /// alias is desired, or the alias creation should be cancelled. Return - /// the chosen alias if the address has been added, otherwise return - /// nothing. - pub fn add_address( - &mut self, - alias: impl AsRef, - address: Address, - ) -> Option { - self.store - .insert_address(alias.into(), address) - .map(Into::into) - } - - /// Insert a new key with the given alias. If the alias is already used, - /// will prompt for overwrite confirmation. - pub fn insert_keypair( - &mut self, - alias: String, - keypair: StoredKeypair, - pkh: PublicKeyHash, - ) -> Option { - self.store - .insert_keypair(alias.into(), keypair, pkh) - .map(Into::into) - } - - pub fn insert_viewing_key( - &mut self, - alias: String, - view_key: ExtendedViewingKey, - ) -> Option { - self.store - .insert_viewing_key(alias.into(), view_key) - .map(Into::into) - } - - pub fn insert_spending_key( - &mut self, - alias: String, - spend_key: StoredKeypair, - viewkey: ExtendedViewingKey, - ) -> Option { - self.store - .insert_spending_key(alias.into(), spend_key, viewkey) - .map(Into::into) - } - - pub fn encrypt_insert_spending_key( - &mut self, - alias: String, - spend_key: ExtendedSpendingKey, - unsafe_dont_encrypt: bool, - ) -> Option { - let password = Self::new_password_prompt(unsafe_dont_encrypt); - self.store - .insert_spending_key( - alias.into(), - StoredKeypair::new(spend_key, password).0, - ExtendedFullViewingKey::from(&spend_key.into()).into(), - ) - .map(Into::into) +/// Add addresses from a genesis configuration. +pub fn add_genesis_addresses( + wallet: &mut Wallet, + genesis: GenesisConfig, +) { + for (alias, addr) in defaults::addresses_from_genesis(genesis) { + wallet.add_address(alias.normalize(), addr); } +} - pub fn insert_payment_addr( - &mut self, - alias: String, - payment_addr: PaymentAddress, - ) -> Option { - self.store - .insert_payment_addr(alias.into(), payment_addr) - .map(Into::into) - } +/// Save the wallet store to a file. +pub fn save(wallet: &Wallet) -> std::io::Result<()> { + self::store::save(wallet.store(), wallet.store_dir()) +} - /// Extend this wallet from pre-genesis validator wallet. - pub fn extend_from_pre_genesis_validator( - &mut self, - validator_address: Address, - validator_alias: Alias, - other: pre_genesis::ValidatorWallet, - ) { - self.store.extend_from_pre_genesis_validator( - validator_address, - validator_alias, - other, - ) - } +/// Load a wallet from the store file. +pub fn load(store_dir: &Path) -> Option> { + let store = self::store::load(store_dir).unwrap_or_else(|err| { + eprintln!("Unable to load the wallet: {}", err); + cli::safe_exit(1) + }); + Some(Wallet::::new( + store_dir.to_path_buf(), + store, + )) +} - /// Gets all addresses given a vp_type - pub fn get_addresses_with_vp_type( - &self, - vp_type: AddressVpType, - ) -> HashSet
{ - self.store.get_addresses_with_vp_type(vp_type) - } +/// Load a wallet from the store file or create a new wallet without any +/// keys or addresses. +pub fn load_or_new(store_dir: &Path) -> Wallet { + let store = self::store::load_or_new(store_dir).unwrap_or_else(|err| { + eprintln!("Unable to load the wallet: {}", err); + cli::safe_exit(1) + }); + Wallet::::new(store_dir.to_path_buf(), store) +} - /// Add a vp_type to a given address - pub fn add_vp_type_to_address( - &mut self, - vp_type: AddressVpType, - address: Address, - ) { - // defaults to an empty set - self.store.add_vp_type_to_address(vp_type, address) - } +/// Load a wallet from the store file or create a new one with the default +/// addresses loaded from the genesis file, if not found. +pub fn load_or_new_from_genesis( + store_dir: &Path, + genesis_cfg: GenesisConfig, +) -> Wallet { + let store = self::store::load_or_new_from_genesis(store_dir, genesis_cfg) + .unwrap_or_else(|err| { + eprintln!("Unable to load the wallet: {}", err); + cli::safe_exit(1) + }); + Wallet::::new(store_dir.to_path_buf(), store) } -/// Read the password for encryption from the file/env/stdin with confirmation. +/// Read the password for encryption from the file/env/stdin with +/// confirmation. pub fn read_and_confirm_pwd(unsafe_dont_encrypt: bool) -> Option { let password = if unsafe_dont_encrypt { println!("Warning: The keypair will NOT be encrypted."); None } else { - Some(read_password("Enter your encryption password: ")) + Some(CliWalletUtils::read_password( + "Enter your encryption password: ", + )) }; // Bis repetita for confirmation. let to_confirm = if unsafe_dont_encrypt { None } else { - Some(read_password( + Some(CliWalletUtils::read_password( "To confirm, please enter the same encryption password once more: ", )) }; @@ -553,22 +217,3 @@ pub fn read_and_confirm_pwd(unsafe_dont_encrypt: bool) -> Option { } password } - -/// Read the password for encryption/decryption from the file/env/stdin. Panics -/// if all options are empty/invalid. -pub fn read_password(prompt_msg: &str) -> String { - let pwd = match env::var("NAMADA_WALLET_PASSWORD_FILE") { - Ok(path) => fs::read_to_string(path) - .expect("Something went wrong reading the file"), - Err(_) => match env::var("NAMADA_WALLET_PASSWORD") { - Ok(password) => password, - Err(_) => rpassword::read_password_from_tty(Some(prompt_msg)) - .unwrap_or_default(), - }, - }; - if pwd.is_empty() { - eprintln!("Password cannot be empty"); - cli::safe_exit(1) - } - pwd -} diff --git a/apps/src/lib/wallet/pre_genesis.rs b/apps/src/lib/wallet/pre_genesis.rs index d3c5fa14c5..12209d5674 100644 --- a/apps/src/lib/wallet/pre_genesis.rs +++ b/apps/src/lib/wallet/pre_genesis.rs @@ -3,188 +3,125 @@ use std::path::{Path, PathBuf}; use ark_serialize::{Read, Write}; use file_lock::{FileLock, FileOptions}; -use namada::types::key::{common, SchemeType}; -use serde::{Deserialize, Serialize}; -use thiserror::Error; +use namada::ledger::wallet::pre_genesis::{ + ReadError, ValidatorStore, ValidatorWallet, +}; +use namada::ledger::wallet::{gen_key_to_store, WalletUtils}; +use namada::types::key::SchemeType; -use crate::wallet; -use crate::wallet::{store, StoredKeypair}; +use crate::wallet::store::gen_validator_keys; +use crate::wallet::{read_and_confirm_pwd, CliWalletUtils}; /// Validator pre-genesis wallet file name const VALIDATOR_FILE_NAME: &str = "wallet.toml"; -#[derive(Error, Debug)] -pub enum ReadError { - #[error("Failed decoding the wallet store: {0}")] - Decode(toml::de::Error), - #[error("Failed to read the wallet store from {0}: {1}")] - ReadWallet(String, String), - #[error("Failed to write the wallet store: {0}")] - StoreNewWallet(String), - #[error("Failed to decode a key: {0}")] - Decryption(wallet::keys::DecryptionError), -} - /// Get the path to the validator pre-genesis wallet store. pub fn validator_file_name(store_dir: impl AsRef) -> PathBuf { store_dir.as_ref().join(VALIDATOR_FILE_NAME) } -/// Validator pre-genesis wallet includes all the required keys for genesis -/// setup and a cache of decrypted keys. -pub struct ValidatorWallet { - /// The wallet store that can be written/read to/from TOML - pub store: ValidatorStore, - /// Cryptographic keypair for validator account key - pub account_key: common::SecretKey, - /// Cryptographic keypair for consensus key - pub consensus_key: common::SecretKey, - /// Cryptographic keypair for Tendermint node key - pub tendermint_node_key: common::SecretKey, -} - -/// Validator pre-genesis wallet store includes all the required keys for -/// genesis setup. -#[derive(Serialize, Deserialize, Debug)] -pub struct ValidatorStore { - /// Cryptographic keypair for validator account key - pub account_key: wallet::StoredKeypair, - /// Cryptographic keypair for consensus key - pub consensus_key: wallet::StoredKeypair, - /// Cryptographic keypair for Tendermint node key - pub tendermint_node_key: wallet::StoredKeypair, - /// Special validator keys - pub validator_keys: wallet::ValidatorKeys, +/// Generate a new [`ValidatorWallet`] with required pre-genesis keys and +/// store it as TOML at the given path. +pub fn gen_and_store( + scheme: SchemeType, + unsafe_dont_encrypt: bool, + store_dir: &Path, +) -> std::io::Result { + let password = read_and_confirm_pwd(unsafe_dont_encrypt); + let validator = gen(scheme, password); + let data = validator.store.encode(); + let wallet_path = validator_file_name(store_dir); + // Make sure the dir exists + let wallet_dir = wallet_path.parent().unwrap(); + fs::create_dir_all(wallet_dir)?; + // Write the file + let options = FileOptions::new().create(true).write(true).truncate(true); + let mut filelock = + FileLock::lock(wallet_path.to_str().unwrap(), true, options)?; + filelock.file.write_all(&data)?; + Ok(validator) } -impl ValidatorWallet { - /// Generate a new [`ValidatorWallet`] with required pre-genesis keys and - /// store it as TOML at the given path. - pub fn gen_and_store( - scheme: SchemeType, - unsafe_dont_encrypt: bool, - store_dir: &Path, - ) -> std::io::Result { - let validator = Self::gen(scheme, unsafe_dont_encrypt); - let data = validator.store.encode(); - let wallet_path = validator_file_name(store_dir); - // Make sure the dir exists - let wallet_dir = wallet_path.parent().unwrap(); - fs::create_dir_all(wallet_dir)?; - // Write the file - let options = - FileOptions::new().create(true).write(true).truncate(true); - let mut filelock = - FileLock::lock(wallet_path.to_str().unwrap(), true, options)?; - filelock.file.write_all(&data)?; - Ok(validator) - } - - /// Try to load and decrypt keys, if encrypted, in a [`ValidatorWallet`] - /// from a TOML file. - pub fn load(store_dir: &Path) -> Result { - let wallet_file = validator_file_name(store_dir); - match FileLock::lock( - wallet_file.to_str().unwrap(), - true, - FileOptions::new().read(true).write(false), - ) { - Ok(mut filelock) => { - let mut store = Vec::::new(); - filelock.file.read_to_end(&mut store).map_err(|err| { - ReadError::ReadWallet( - store_dir.to_str().unwrap().into(), - err.to_string(), - ) - })?; - let store = - ValidatorStore::decode(store).map_err(ReadError::Decode)?; - - let password = if store.account_key.is_encrypted() - || store.consensus_key.is_encrypted() - || store.account_key.is_encrypted() - { - Some(wallet::read_password("Enter decryption password: ")) - } else { - None - }; - - let account_key = - store.account_key.get(true, password.clone())?; - let consensus_key = - store.consensus_key.get(true, password.clone())?; - let tendermint_node_key = - store.tendermint_node_key.get(true, password)?; - - Ok(Self { - store, - account_key, - consensus_key, - tendermint_node_key, - }) - } - Err(err) => Err(ReadError::ReadWallet( - wallet_file.to_string_lossy().into_owned(), - err.to_string(), - )), +/// Try to load and decrypt keys, if encrypted, in a [`ValidatorWallet`] +/// from a TOML file. +pub fn load(store_dir: &Path) -> Result { + let wallet_file = validator_file_name(store_dir); + match FileLock::lock( + wallet_file.to_str().unwrap(), + true, + FileOptions::new().read(true).write(false), + ) { + Ok(mut filelock) => { + let mut store = Vec::::new(); + filelock.file.read_to_end(&mut store).map_err(|err| { + ReadError::ReadWallet( + store_dir.to_str().unwrap().into(), + err.to_string(), + ) + })?; + let store = + ValidatorStore::decode(store).map_err(ReadError::Decode)?; + + let password = if store.account_key.is_encrypted() + || store.consensus_key.is_encrypted() + || store.account_key.is_encrypted() + { + Some(CliWalletUtils::read_password( + "Enter decryption password: ", + )) + } else { + None + }; + + let account_key = store + .account_key + .get::(true, password.clone())?; + let consensus_key = store + .consensus_key + .get::(true, password.clone())?; + let tendermint_node_key = store + .tendermint_node_key + .get::(true, password)?; + + Ok(ValidatorWallet { + store, + account_key, + consensus_key, + tendermint_node_key, + }) } + Err(err) => Err(ReadError::ReadWallet( + wallet_file.to_string_lossy().into_owned(), + err.to_string(), + )), } - - /// Generate a new [`ValidatorWallet`] with required pre-genesis keys. Will - /// prompt for password when `!unsafe_dont_encrypt`. - fn gen(scheme: SchemeType, unsafe_dont_encrypt: bool) -> Self { - let password = wallet::read_and_confirm_pwd(unsafe_dont_encrypt); - let (account_key, account_sk) = gen_key_to_store(scheme, &password); - let (consensus_key, consensus_sk) = gen_key_to_store( - // Note that TM only allows ed25519 for consensus key - SchemeType::Ed25519, - &password, - ); - let (tendermint_node_key, tendermint_node_sk) = gen_key_to_store( - // Note that TM only allows ed25519 for node IDs - SchemeType::Ed25519, - &password, - ); - let validator_keys = store::Store::gen_validator_keys(None, scheme); - let store = ValidatorStore { - account_key, - consensus_key, - tendermint_node_key, - validator_keys, - }; - Self { - store, - account_key: account_sk, - consensus_key: consensus_sk, - tendermint_node_key: tendermint_node_sk, - } - } -} - -impl ValidatorStore { - /// Decode from TOML string bytes - pub fn decode(data: Vec) -> Result { - toml::from_slice(&data) - } - - /// Encode in TOML string bytes - pub fn encode(&self) -> Vec { - toml::to_vec(self).expect( - "Serializing of validator pre-genesis wallet shouldn't fail", - ) - } -} - -fn gen_key_to_store( - scheme: SchemeType, - password: &Option, -) -> (StoredKeypair, common::SecretKey) { - let sk = store::gen_sk(scheme); - StoredKeypair::new(sk, password.clone()) } -impl From for ReadError { - fn from(err: wallet::keys::DecryptionError) -> Self { - ReadError::Decryption(err) +/// Generate a new [`ValidatorWallet`] with required pre-genesis keys. Will +/// prompt for password when `!unsafe_dont_encrypt`. +fn gen(scheme: SchemeType, password: Option) -> ValidatorWallet { + let (account_key, account_sk) = gen_key_to_store(scheme, &password); + let (consensus_key, consensus_sk) = gen_key_to_store( + // Note that TM only allows ed25519 for consensus key + SchemeType::Ed25519, + &password, + ); + let (tendermint_node_key, tendermint_node_sk) = gen_key_to_store( + // Note that TM only allows ed25519 for node IDs + SchemeType::Ed25519, + &password, + ); + let validator_keys = gen_validator_keys(None, scheme); + let store = ValidatorStore { + account_key, + consensus_key, + tendermint_node_key, + validator_keys, + }; + ValidatorWallet { + store, + account_key: account_sk, + consensus_key: consensus_sk, + tendermint_node_key: tendermint_node_sk, } } diff --git a/apps/src/lib/wallet/store.rs b/apps/src/lib/wallet/store.rs index 465a2b8a7f..a6e50e423b 100644 --- a/apps/src/lib/wallet/store.rs +++ b/apps/src/lib/wallet/store.rs @@ -1,84 +1,26 @@ -use std::collections::{HashMap, HashSet}; -use std::fmt::Display; use std::fs; use std::io::prelude::*; -use std::io::{self, Write}; +use std::io::Write; use std::path::{Path, PathBuf}; +#[cfg(not(feature = "dev"))] use std::str::FromStr; use ark_std::rand::prelude::*; use ark_std::rand::SeedableRng; -use bimap::BiHashMap; use file_lock::{FileLock, FileOptions}; -use masp_primitives::zip32::ExtendedFullViewingKey; -use namada::types::address::{Address, ImplicitAddress}; -use namada::types::key::dkg_session_keys::DkgKeypair; +#[cfg(not(feature = "dev"))] +use namada::ledger::wallet::store::AddressVpType; +#[cfg(feature = "dev")] +use namada::ledger::wallet::StoredKeypair; +use namada::ledger::wallet::{gen_sk, Store, ValidatorKeys}; +#[cfg(not(feature = "dev"))] +use namada::types::address::Address; use namada::types::key::*; -use namada::types::masp::{ - ExtendedSpendingKey, ExtendedViewingKey, PaymentAddress, -}; use namada::types::transaction::EllipticCurve; -use serde::{Deserialize, Serialize}; use thiserror::Error; -use super::alias::{self, Alias}; -use super::keys::StoredKeypair; -use super::pre_genesis; -use crate::cli; use crate::config::genesis::genesis_config::GenesisConfig; - -/// Special keys for a validator -#[derive(Serialize, Deserialize, Debug)] -pub struct ValidatorKeys { - /// Special keypair for signing protocol txs - pub protocol_keypair: common::SecretKey, - /// Special session keypair needed by validators for participating - /// in the DKG protocol - pub dkg_keypair: Option, -} - -impl ValidatorKeys { - /// Get the protocol keypair - pub fn get_protocol_keypair(&self) -> &common::SecretKey { - &self.protocol_keypair - } -} - -/// Special data associated with a validator -#[derive(Serialize, Deserialize, Debug)] -pub struct ValidatorData { - /// The address associated to a validator - pub address: Address, - /// special keys for a validator - pub keys: ValidatorKeys, -} - -#[derive(Serialize, Deserialize, Debug, Default)] -pub struct Store { - /// Known viewing keys - view_keys: HashMap, - /// Known spending keys - spend_keys: HashMap>, - /// Known payment addresses - payment_addrs: HashMap, - /// Cryptographic keypairs - keys: HashMap>, - /// Namada address book - addresses: BiHashMap, - /// Known mappings of public key hashes to their aliases in the `keys` - /// field. Used for look-up by a public key. - pkhs: HashMap, - /// Special keys if the wallet belongs to a validator - pub(crate) validator_data: Option, - /// Namada address vp type - address_vp_types: HashMap>, -} - -/// Grouping of addresses by validity predicate. -#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash, Debug)] -pub enum AddressVpType { - Token, -} +use crate::wallet::CliWalletUtils; #[derive(Error, Debug)] pub enum LoadStoreError { @@ -90,692 +32,6 @@ pub enum LoadStoreError { StoreNewWallet(String), } -impl Store { - #[cfg(not(feature = "dev"))] - fn new(genesis: GenesisConfig) -> Self { - let mut store = Self::default(); - store.add_genesis_addresses(genesis); - store - } - - #[cfg(feature = "dev")] - fn new() -> Self { - let mut store = Self::default(); - // Pre-load the default keys without encryption - let no_password = None; - for (alias, keypair) in super::defaults::keys() { - let pkh: PublicKeyHash = (&keypair.ref_to()).into(); - store.keys.insert( - alias.clone(), - StoredKeypair::new(keypair, no_password.clone()).0, - ); - store.pkhs.insert(pkh, alias); - } - store - .addresses - .extend(super::defaults::addresses().into_iter()); - store - } - - /// Add addresses from a genesis configuration. - pub fn add_genesis_addresses(&mut self, genesis: GenesisConfig) { - for (alias, token) in &genesis.token { - if let Some(address) = token.address.as_ref() { - match Address::from_str(address) { - Ok(address) => self - .add_vp_type_to_address(AddressVpType::Token, address), - Err(_) => { - tracing::error!( - "Weird address for token {alias}: {address}" - ) - } - } - } - } - self.addresses.extend( - super::defaults::addresses_from_genesis(genesis).into_iter(), - ); - } - - /// Save the wallet store to a file. - pub fn save(&self, store_dir: &Path) -> std::io::Result<()> { - let data = self.encode(); - let wallet_path = wallet_file(store_dir); - // Make sure the dir exists - let wallet_dir = wallet_path.parent().unwrap(); - fs::create_dir_all(wallet_dir)?; - // Write the file - let options = - FileOptions::new().create(true).write(true).truncate(true); - let mut filelock = - FileLock::lock(wallet_path.to_str().unwrap(), true, options)?; - filelock.file.write_all(&data) - } - - /// Load the store file or create a new one without any keys or addresses. - pub fn load_or_new(store_dir: &Path) -> Result { - Self::load(store_dir).or_else(|_| { - let store = Self::default(); - store.save(store_dir).map_err(|err| { - LoadStoreError::StoreNewWallet(err.to_string()) - })?; - Ok(store) - }) - } - - /// Load the store file or create a new one with the default addresses from - /// the genesis file, if not found. - pub fn load_or_new_from_genesis( - store_dir: &Path, - genesis_cfg: GenesisConfig, - ) -> Result { - Self::load(store_dir).or_else(|_| { - #[cfg(not(feature = "dev"))] - let store = Self::new(genesis_cfg); - #[cfg(feature = "dev")] - let store = { - // The function is unused in dev - let _ = genesis_cfg; - Self::new() - }; - store.save(store_dir).map_err(|err| { - LoadStoreError::StoreNewWallet(err.to_string()) - })?; - Ok(store) - }) - } - - /// Attempt to load the store file. - pub fn load(store_dir: &Path) -> Result { - let wallet_file = wallet_file(store_dir); - match FileLock::lock( - wallet_file.to_str().unwrap(), - true, - FileOptions::new().read(true).write(false), - ) { - Ok(mut filelock) => { - let mut store = Vec::::new(); - filelock.file.read_to_end(&mut store).map_err(|err| { - LoadStoreError::ReadWallet( - store_dir.to_str().unwrap().into(), - err.to_string(), - ) - })?; - Store::decode(store).map_err(LoadStoreError::Decode) - } - Err(err) => Err(LoadStoreError::ReadWallet( - wallet_file.to_string_lossy().into_owned(), - err.to_string(), - )), - } - } - - /// Find the stored key by an alias, a public key hash or a public key. - pub fn find_key( - &self, - alias_pkh_or_pk: impl AsRef, - ) -> Option<&StoredKeypair> { - let alias_pkh_or_pk = alias_pkh_or_pk.as_ref(); - // Try to find by alias - self.keys - .get(&alias_pkh_or_pk.into()) - // Try to find by PKH - .or_else(|| { - let pkh = PublicKeyHash::from_str(alias_pkh_or_pk).ok()?; - self.find_key_by_pkh(&pkh) - }) - // Try to find by PK - .or_else(|| { - let pk = common::PublicKey::from_str(alias_pkh_or_pk).ok()?; - self.find_key_by_pk(&pk) - }) - } - - pub fn find_spending_key( - &self, - alias: impl AsRef, - ) -> Option<&StoredKeypair> { - self.spend_keys.get(&alias.into()) - } - - pub fn find_viewing_key( - &self, - alias: impl AsRef, - ) -> Option<&ExtendedViewingKey> { - self.view_keys.get(&alias.into()) - } - - pub fn find_payment_addr( - &self, - alias: impl AsRef, - ) -> Option<&PaymentAddress> { - self.payment_addrs.get(&alias.into()) - } - - /// Find the stored key by a public key. - pub fn find_key_by_pk( - &self, - pk: &common::PublicKey, - ) -> Option<&StoredKeypair> { - let pkh = PublicKeyHash::from(pk); - self.find_key_by_pkh(&pkh) - } - - /// Find the stored key by a public key hash. - pub fn find_key_by_pkh( - &self, - pkh: &PublicKeyHash, - ) -> Option<&StoredKeypair> { - let alias = self.pkhs.get(pkh)?; - self.keys.get(alias) - } - - /// Find the stored alias for a public key hash. - pub fn find_alias_by_pkh(&self, pkh: &PublicKeyHash) -> Option { - self.pkhs.get(pkh).cloned() - } - - /// Find the stored address by an alias. - pub fn find_address(&self, alias: impl AsRef) -> Option<&Address> { - self.addresses.get_by_left(&alias.into()) - } - - /// Find an alias by the address if it's in the wallet. - pub fn find_alias(&self, address: &Address) -> Option<&Alias> { - self.addresses.get_by_right(address) - } - - /// Get all known keys by their alias, paired with PKH, if known. - pub fn get_keys( - &self, - ) -> HashMap< - Alias, - (&StoredKeypair, Option<&PublicKeyHash>), - > { - let mut keys: HashMap< - Alias, - (&StoredKeypair, Option<&PublicKeyHash>), - > = self - .pkhs - .iter() - .filter_map(|(pkh, alias)| { - let key = &self.keys.get(alias)?; - Some((alias.clone(), (*key, Some(pkh)))) - }) - .collect(); - self.keys.iter().for_each(|(alias, key)| { - if !keys.contains_key(alias) { - keys.insert(alias.clone(), (key, None)); - } - }); - keys - } - - /// Get all known addresses by their alias, paired with PKH, if known. - pub fn get_addresses(&self) -> &BiHashMap { - &self.addresses - } - - /// Get all known payment addresses by their alias. - pub fn get_payment_addrs(&self) -> &HashMap { - &self.payment_addrs - } - - /// Get all known viewing keys by their alias. - pub fn get_viewing_keys(&self) -> &HashMap { - &self.view_keys - } - - /// Get all known spending keys by their alias. - pub fn get_spending_keys( - &self, - ) -> &HashMap> { - &self.spend_keys - } - - fn generate_spending_key() -> ExtendedSpendingKey { - use rand::rngs::OsRng; - let mut spend_key = [0; 32]; - OsRng.fill_bytes(&mut spend_key); - masp_primitives::zip32::ExtendedSpendingKey::master(spend_key.as_ref()) - .into() - } - - /// Generate a new keypair and insert it into the store with the provided - /// alias. If none provided, the alias will be the public key hash. - /// If no password is provided, the keypair will be stored raw without - /// encryption. Returns the alias of the key and a reference-counting - /// pointer to the key. - pub fn gen_key( - &mut self, - scheme: SchemeType, - alias: Option, - password: Option, - ) -> (Alias, common::SecretKey) { - let sk = gen_sk(scheme); - let pkh: PublicKeyHash = PublicKeyHash::from(&sk.ref_to()); - let (keypair_to_store, raw_keypair) = StoredKeypair::new(sk, password); - let address = Address::Implicit(ImplicitAddress(pkh.clone())); - let alias: Alias = alias.unwrap_or_else(|| pkh.clone().into()).into(); - if self - .insert_keypair(alias.clone(), keypair_to_store, pkh) - .is_none() - { - eprintln!("Action cancelled, no changes persisted."); - cli::safe_exit(1); - } - if self.insert_address(alias.clone(), address).is_none() { - eprintln!("Action cancelled, no changes persisted."); - cli::safe_exit(1); - } - (alias, raw_keypair) - } - - /// Generate a spending key similarly to how it's done for keypairs - pub fn gen_spending_key( - &mut self, - alias: String, - password: Option, - ) -> (Alias, ExtendedSpendingKey) { - let spendkey = Self::generate_spending_key(); - let viewkey = ExtendedFullViewingKey::from(&spendkey.into()).into(); - let (spendkey_to_store, _raw_spendkey) = - StoredKeypair::new(spendkey, password); - let alias = Alias::from(alias); - if self - .insert_spending_key(alias.clone(), spendkey_to_store, viewkey) - .is_none() - { - eprintln!("Action cancelled, no changes persisted."); - cli::safe_exit(1); - } - (alias, spendkey) - } - - /// Generate keypair for signing protocol txs and for the DKG - /// A protocol keypair may be optionally provided - /// - /// Note that this removes the validator data. - pub fn gen_validator_keys( - protocol_keypair: Option, - scheme: SchemeType, - ) -> ValidatorKeys { - let protocol_keypair = - protocol_keypair.unwrap_or_else(|| gen_sk(scheme)); - let dkg_keypair = ferveo_common::Keypair::::new( - &mut StdRng::from_entropy(), - ); - ValidatorKeys { - protocol_keypair, - dkg_keypair: Some(dkg_keypair.into()), - } - } - - /// Add validator data to the store - pub fn add_validator_data( - &mut self, - address: Address, - keys: ValidatorKeys, - ) { - self.validator_data = Some(ValidatorData { address, keys }); - } - - /// Returns the validator data, if it exists - pub fn get_validator_data(&self) -> Option<&ValidatorData> { - self.validator_data.as_ref() - } - - /// Returns the validator data, if it exists - pub fn validator_data(self) -> Option { - self.validator_data - } - - /// Insert a new key with the given alias. If the alias is already used, - /// will prompt for overwrite/reselection confirmation. If declined, then - /// keypair is not inserted and nothing is returned, otherwise selected - /// alias is returned. - pub(super) fn insert_keypair( - &mut self, - alias: Alias, - keypair: StoredKeypair, - pkh: PublicKeyHash, - ) -> Option { - if alias.is_empty() { - println!( - "Empty alias given, defaulting to {}.", - Into::::into(pkh.to_string()) - ); - } - // Addresses and keypairs can share aliases, so first remove any - // addresses sharing the same namesake before checking if alias has been - // used. - let counterpart_address = self.addresses.remove_by_left(&alias); - if self.contains_alias(&alias) { - match show_overwrite_confirmation(&alias, "a key") { - ConfirmationResponse::Replace => {} - ConfirmationResponse::Reselect(new_alias) => { - // Restore the removed address in case the recursive prompt - // terminates with a cancellation - counterpart_address - .map(|x| self.addresses.insert(alias.clone(), x.1)); - return self.insert_keypair(new_alias, keypair, pkh); - } - ConfirmationResponse::Skip => { - // Restore the removed address since this insertion action - // has now been cancelled - counterpart_address - .map(|x| self.addresses.insert(alias.clone(), x.1)); - return None; - } - } - } - self.remove_alias(&alias); - self.keys.insert(alias.clone(), keypair); - self.pkhs.insert(pkh, alias.clone()); - // Since it is intended for the inserted keypair to share its namesake - // with the pre-existing address - counterpart_address.map(|x| self.addresses.insert(alias.clone(), x.1)); - Some(alias) - } - - /// Insert spending keys similarly to how it's done for keypairs - pub fn insert_spending_key( - &mut self, - alias: Alias, - spendkey: StoredKeypair, - viewkey: ExtendedViewingKey, - ) -> Option { - if alias.is_empty() { - eprintln!("Empty alias given."); - return None; - } - if self.contains_alias(&alias) { - match show_overwrite_confirmation(&alias, "a spending key") { - ConfirmationResponse::Replace => {} - ConfirmationResponse::Reselect(new_alias) => { - return self - .insert_spending_key(new_alias, spendkey, viewkey); - } - ConfirmationResponse::Skip => return None, - } - } - self.remove_alias(&alias); - self.spend_keys.insert(alias.clone(), spendkey); - // Simultaneously add the derived viewing key to ease balance viewing - self.view_keys.insert(alias.clone(), viewkey); - Some(alias) - } - - /// Insert viewing keys similarly to how it's done for keypairs - pub fn insert_viewing_key( - &mut self, - alias: Alias, - viewkey: ExtendedViewingKey, - ) -> Option { - if alias.is_empty() { - eprintln!("Empty alias given."); - return None; - } - if self.contains_alias(&alias) { - match show_overwrite_confirmation(&alias, "a viewing key") { - ConfirmationResponse::Replace => {} - ConfirmationResponse::Reselect(new_alias) => { - return self.insert_viewing_key(new_alias, viewkey); - } - ConfirmationResponse::Skip => return None, - } - } - self.remove_alias(&alias); - self.view_keys.insert(alias.clone(), viewkey); - Some(alias) - } - - /// Check if any map of the wallet contains the given alias - fn contains_alias(&self, alias: &Alias) -> bool { - self.payment_addrs.contains_key(alias) - || self.view_keys.contains_key(alias) - || self.spend_keys.contains_key(alias) - || self.keys.contains_key(alias) - || self.addresses.contains_left(alias) - } - - /// Completely remove the given alias from all maps in the wallet - fn remove_alias(&mut self, alias: &Alias) { - self.payment_addrs.remove(alias); - self.view_keys.remove(alias); - self.spend_keys.remove(alias); - self.keys.remove(alias); - self.addresses.remove_by_left(alias); - self.pkhs.retain(|_key, val| val != alias); - } - - /// Insert payment addresses similarly to how it's done for keypairs - pub fn insert_payment_addr( - &mut self, - alias: Alias, - payment_addr: PaymentAddress, - ) -> Option { - if alias.is_empty() { - eprintln!("Empty alias given."); - return None; - } - if self.contains_alias(&alias) { - match show_overwrite_confirmation(&alias, "a payment address") { - ConfirmationResponse::Replace => {} - ConfirmationResponse::Reselect(new_alias) => { - return self.insert_payment_addr(new_alias, payment_addr); - } - ConfirmationResponse::Skip => return None, - } - } - self.remove_alias(&alias); - self.payment_addrs.insert(alias.clone(), payment_addr); - Some(alias) - } - - /// Helper function to restore keypair given alias-keypair mapping and the - /// pkhs-alias mapping. - fn restore_keypair( - &mut self, - alias: Alias, - key: Option>, - pkh: Option, - ) { - key.map(|x| self.keys.insert(alias.clone(), x)); - pkh.map(|x| self.pkhs.insert(x, alias.clone())); - } - - /// Insert a new address with the given alias. If the alias is already used, - /// will prompt for overwrite/reselection confirmation, which when declined, - /// the address won't be added. Return the selected alias if the address has - /// been added. - pub fn insert_address( - &mut self, - alias: Alias, - address: Address, - ) -> Option { - if alias.is_empty() { - println!("Empty alias given, defaulting to {}.", address.encode()); - } - // Addresses and keypairs can share aliases, so first remove any keys - // sharing the same namesake before checking if alias has been used. - let counterpart_key = self.keys.remove(&alias); - let mut counterpart_pkh = None; - self.pkhs.retain(|k, v| { - if v == &alias { - counterpart_pkh = Some(k.clone()); - false - } else { - true - } - }); - if self.addresses.contains_left(&alias) { - match show_overwrite_confirmation(&alias, "an address") { - ConfirmationResponse::Replace => {} - ConfirmationResponse::Reselect(new_alias) => { - // Restore the removed keypair in case the recursive prompt - // terminates with a cancellation - self.restore_keypair( - alias, - counterpart_key, - counterpart_pkh, - ); - return self.insert_address(new_alias, address); - } - ConfirmationResponse::Skip => { - // Restore the removed keypair since this insertion action - // has now been cancelled - self.restore_keypair( - alias, - counterpart_key, - counterpart_pkh, - ); - return None; - } - } - } - self.remove_alias(&alias); - self.addresses.insert(alias.clone(), address); - // Since it is intended for the inserted address to share its namesake - // with the pre-existing keypair - self.restore_keypair(alias.clone(), counterpart_key, counterpart_pkh); - Some(alias) - } - - /// Extend this store from pre-genesis validator wallet. - pub fn extend_from_pre_genesis_validator( - &mut self, - validator_address: Address, - validator_alias: Alias, - other: pre_genesis::ValidatorWallet, - ) { - let account_key_alias = alias::validator_key(&validator_alias); - let consensus_key_alias = - alias::validator_consensus_key(&validator_alias); - let tendermint_node_key_alias = - alias::validator_tendermint_node_key(&validator_alias); - - let keys = [ - (account_key_alias.clone(), other.store.account_key), - (consensus_key_alias.clone(), other.store.consensus_key), - ( - tendermint_node_key_alias.clone(), - other.store.tendermint_node_key, - ), - ]; - self.keys.extend(keys.into_iter()); - - let account_pk = other.account_key.ref_to(); - let consensus_pk = other.consensus_key.ref_to(); - let tendermint_node_pk = other.tendermint_node_key.ref_to(); - let addresses = [ - (account_key_alias.clone(), (&account_pk).into()), - (consensus_key_alias.clone(), (&consensus_pk).into()), - ( - tendermint_node_key_alias.clone(), - (&tendermint_node_pk).into(), - ), - ]; - self.addresses.extend(addresses.into_iter()); - - let pkhs = [ - ((&account_pk).into(), account_key_alias), - ((&consensus_pk).into(), consensus_key_alias), - ((&tendermint_node_pk).into(), tendermint_node_key_alias), - ]; - self.pkhs.extend(pkhs.into_iter()); - - self.validator_data = Some(ValidatorData { - address: validator_address, - keys: other.store.validator_keys, - }); - } - - pub fn get_addresses_with_vp_type( - &self, - vp_type: AddressVpType, - ) -> HashSet
{ - // defaults to an empty set - self.address_vp_types - .get(&vp_type) - .cloned() - .unwrap_or_default() - } - - pub fn add_vp_type_to_address( - &mut self, - vp_type: AddressVpType, - address: Address, - ) { - // defaults to an empty set - self.address_vp_types - .entry(vp_type) - .or_default() - .insert(address); - } - - fn decode(data: Vec) -> Result { - toml::from_slice(&data) - } - - fn encode(&self) -> Vec { - toml::to_vec(self).expect("Serializing of store shouldn't fail") - } -} - -enum ConfirmationResponse { - Replace, - Reselect(Alias), - Skip, -} - -/// The given alias has been selected but conflicts with another alias in -/// the store. Offer the user to either replace existing mapping, alter the -/// chosen alias to a name of their chosing, or cancel the aliasing. - -fn show_overwrite_confirmation( - alias: &Alias, - alias_for: &str, -) -> ConfirmationResponse { - print!( - "You're trying to create an alias \"{}\" that already exists for {} \ - in your store.\nWould you like to replace it? \ - s(k)ip/re(p)lace/re(s)elect: ", - alias, alias_for - ); - io::stdout().flush().unwrap(); - - let mut buffer = String::new(); - // Get the user to select between 3 choices - match io::stdin().read_line(&mut buffer) { - Ok(size) if size > 0 => { - // Isolate the single character representing the choice - let byte = buffer.chars().next().unwrap(); - buffer.clear(); - match byte { - 'p' | 'P' => return ConfirmationResponse::Replace, - 's' | 'S' => { - // In the case of reselection, elicit new alias - print!("Please enter a different alias: "); - io::stdout().flush().unwrap(); - if io::stdin().read_line(&mut buffer).is_ok() { - return ConfirmationResponse::Reselect( - buffer.trim().into(), - ); - } - } - 'k' | 'K' => return ConfirmationResponse::Skip, - // Input is senseless fall through to repeat prompt - _ => {} - }; - } - _ => {} - } - // Input is senseless fall through to repeat prompt - println!("Invalid option, try again."); - show_overwrite_confirmation(alias, alias_for) -} - /// Wallet file name const FILE_NAME: &str = "wallet.toml"; @@ -784,72 +40,154 @@ pub fn wallet_file(store_dir: impl AsRef) -> PathBuf { store_dir.as_ref().join(FILE_NAME) } -impl Display for AddressVpType { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - AddressVpType::Token => write!(f, "token"), +/// Save the wallet store to a file. +pub fn save(store: &Store, store_dir: &Path) -> std::io::Result<()> { + let data = store.encode(); + let wallet_path = wallet_file(store_dir); + // Make sure the dir exists + let wallet_dir = wallet_path.parent().unwrap(); + fs::create_dir_all(wallet_dir)?; + // Write the file + let options = FileOptions::new().create(true).write(true).truncate(true); + let mut filelock = + FileLock::lock(wallet_path.to_str().unwrap(), true, options)?; + filelock.file.write_all(&data) +} + +/// Load the store file or create a new one without any keys or addresses. +pub fn load_or_new(store_dir: &Path) -> Result { + load(store_dir).or_else(|_| { + let store = Store::default(); + save(&store, store_dir) + .map_err(|err| LoadStoreError::StoreNewWallet(err.to_string()))?; + Ok(store) + }) +} + +/// Load the store file or create a new one with the default addresses from +/// the genesis file, if not found. +pub fn load_or_new_from_genesis( + store_dir: &Path, + genesis_cfg: GenesisConfig, +) -> Result { + load(store_dir).or_else(|_| { + #[cfg(not(feature = "dev"))] + let store = new(genesis_cfg); + #[cfg(feature = "dev")] + let store = { + // The function is unused in dev + let _ = genesis_cfg; + new() + }; + save(&store, store_dir) + .map_err(|err| LoadStoreError::StoreNewWallet(err.to_string()))?; + Ok(store) + }) +} + +/// Attempt to load the store file. +pub fn load(store_dir: &Path) -> Result { + let wallet_file = wallet_file(store_dir); + match FileLock::lock( + wallet_file.to_str().unwrap(), + true, + FileOptions::new().read(true).write(false), + ) { + Ok(mut filelock) => { + let mut store = Vec::::new(); + filelock.file.read_to_end(&mut store).map_err(|err| { + LoadStoreError::ReadWallet( + store_dir.to_str().unwrap().parse().unwrap(), + err.to_string(), + ) + })?; + Store::decode(store).map_err(LoadStoreError::Decode) } + Err(err) => Err(LoadStoreError::ReadWallet( + wallet_file.to_string_lossy().into_owned(), + err.to_string(), + )), } } -impl FromStr for AddressVpType { - type Err = &'static str; - - fn from_str(s: &str) -> Result { - match s { - "token" => Ok(Self::Token), - _ => Err("unexpected address VP type"), +/// Add addresses from a genesis configuration. +#[cfg(not(feature = "dev"))] +pub fn add_genesis_addresses(store: &mut Store, genesis: GenesisConfig) { + for (alias, addr) in + super::defaults::addresses_from_genesis(genesis.clone()) + { + store.insert_address::(alias, addr); + } + for (alias, token) in &genesis.token { + if let Some(address) = token.address.as_ref() { + match Address::from_str(address) { + Ok(address) => { + store.add_vp_type_to_address(AddressVpType::Token, address) + } + Err(_) => { + tracing::error!( + "Weird address for token {alias}: {address}" + ) + } + } } } } -impl Serialize for AddressVpType { - fn serialize(&self, serializer: S) -> Result - where - S: serde::Serializer, - { - self.to_string().serialize(serializer) - } +#[cfg(not(feature = "dev"))] +fn new(genesis: GenesisConfig) -> Store { + let mut store = Store::default(); + add_genesis_addresses(&mut store, genesis); + store } -impl<'de> Deserialize<'de> for AddressVpType { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - use serde::de::Error; - - let raw: String = Deserialize::deserialize(deserializer)?; - Self::from_str(&raw).map_err(D::Error::custom) +#[cfg(feature = "dev")] +fn new() -> Store { + let mut store = Store::default(); + // Pre-load the default keys without encryption + let no_password = None; + for (alias, keypair) in super::defaults::keys() { + let pkh: PublicKeyHash = (&keypair.ref_to()).into(); + store.insert_keypair::( + alias, + StoredKeypair::new(keypair, no_password.clone()).0, + pkh, + ); + } + for (alias, addr) in super::defaults::addresses() { + store.insert_address::(alias, addr); } + store } -/// Generate a new secret key. -pub fn gen_sk(scheme: SchemeType) -> common::SecretKey { - use rand::rngs::OsRng; - let mut csprng = OsRng {}; - match scheme { - SchemeType::Ed25519 => ed25519::SigScheme::generate(&mut csprng) - .try_to_sk() - .unwrap(), - SchemeType::Secp256k1 => secp256k1::SigScheme::generate(&mut csprng) - .try_to_sk() - .unwrap(), - SchemeType::Common => common::SigScheme::generate(&mut csprng) - .try_to_sk() - .unwrap(), +/// Generate keypair for signing protocol txs and for the DKG +/// A protocol keypair may be optionally provided +/// +/// Note that this removes the validator data. +pub fn gen_validator_keys( + protocol_keypair: Option, + scheme: SchemeType, +) -> ValidatorKeys { + let protocol_keypair = protocol_keypair.unwrap_or_else(|| gen_sk(scheme)); + let dkg_keypair = ferveo_common::Keypair::::new( + &mut StdRng::from_entropy(), + ); + ValidatorKeys { + protocol_keypair, + dkg_keypair: Some(dkg_keypair.into()), } } #[cfg(all(test, feature = "dev"))] mod test_wallet { + use namada::types::address::Address; + use super::*; #[test] fn test_toml_roundtrip_ed25519() { - let mut store = Store::new(); - let validator_keys = - Store::gen_validator_keys(None, SchemeType::Ed25519); + let mut store = new(); + let validator_keys = gen_validator_keys(None, SchemeType::Ed25519); store.add_validator_data( Address::decode("atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5").unwrap(), validator_keys @@ -860,9 +198,8 @@ mod test_wallet { #[test] fn test_toml_roundtrip_secp256k1() { - let mut store = Store::new(); - let validator_keys = - Store::gen_validator_keys(None, SchemeType::Secp256k1); + let mut store = new(); + let validator_keys = gen_validator_keys(None, SchemeType::Secp256k1); store.add_validator_data( Address::decode("atest1v4ehgw36x3prswzxggunzv6pxqmnvdj9xvcyzvpsggeyvs3cg9qnywf589qnwvfsg5erg3fkl09rg5").unwrap(), validator_keys diff --git a/core/Cargo.toml b/core/Cargo.toml index 743be487d4..d6435500a7 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -88,15 +88,15 @@ prost-types = "0.11.6" rand = {version = "0.8", optional = true} rand_core = {version = "0.6", optional = true} rayon = {version = "=1.5.3", optional = true} -rust_decimal = { version = "1.26.1", features = ["borsh"] } -rust_decimal_macros = "1.26.1" +rust_decimal = { version = "=1.26.1", features = ["borsh"] } +rust_decimal_macros = "=1.26.1" serde = {version = "1.0.125", features = ["derive"]} serde_json = "1.0.62" sha2 = "0.9.3" tendermint = {version = "0.23.6", optional = true} tendermint-proto = {version = "0.23.6", optional = true} -tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} -tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} +tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} +tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} thiserror = "1.0.38" tracing = "0.1.30" zeroize = {version = "1.5.5", features = ["zeroize_derive"]} diff --git a/core/src/ledger/storage/wl_storage.rs b/core/src/ledger/storage/wl_storage.rs index 99df4534e4..82bb799f39 100644 --- a/core/src/ledger/storage/wl_storage.rs +++ b/core/src/ledger/storage/wl_storage.rs @@ -361,14 +361,14 @@ where // try to read from the write log first let (log_val, _gas) = self.write_log().read(key); match log_val { - Some(&write_log::StorageModification::Write { ref value }) => { + Some(write_log::StorageModification::Write { ref value }) => { Ok(Some(value.clone())) } - Some(&write_log::StorageModification::Delete) => Ok(None), - Some(&write_log::StorageModification::InitAccount { + Some(write_log::StorageModification::Delete) => Ok(None), + Some(write_log::StorageModification::InitAccount { ref vp_code_hash, }) => Ok(Some(vp_code_hash.to_vec())), - Some(&write_log::StorageModification::Temp { ref value }) => { + Some(write_log::StorageModification::Temp { ref value }) => { Ok(Some(value.clone())) } None => { diff --git a/documentation/docs/src/testnets/running-a-full-node.md b/documentation/docs/src/testnets/running-a-full-node.md index 94422c3c7c..b185c3d47d 100644 --- a/documentation/docs/src/testnets/running-a-full-node.md +++ b/documentation/docs/src/testnets/running-a-full-node.md @@ -11,11 +11,11 @@ ``` Optional: If you want more logs, you can instead run ```bash -NAMADA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run +NAMADA_LOG=debug ANOMA_TM_STDOUT=true namada node ledger run ``` And if you want to save your logs to a file, you can instead run: ```bash TIMESTAMP=$(date +%s) -NAMADA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run &> logs-${TIMESTAMP}.txt +ANOMA_LOG=debug NAMADA_TM_STDOUT=true namada node ledger run &> logs-${TIMESTAMP}.txt tail -f -n 20 logs-${TIMESTAMP}.txt ## (in another shell) ``` \ No newline at end of file diff --git a/proof_of_stake/Cargo.toml b/proof_of_stake/Cargo.toml index bda4631867..d989125183 100644 --- a/proof_of_stake/Cargo.toml +++ b/proof_of_stake/Cargo.toml @@ -24,8 +24,8 @@ hex = "0.4.3" once_cell = "1.8.0" # A fork with state machine testing proptest = {git = "https://github.com/heliaxdev/proptest", rev = "8f1b4abe7ebd35c0781bf9a00a4ee59833ffa2a1", optional = true} -rust_decimal = { version = "1.26.1", features = ["borsh"] } -rust_decimal_macros = "1.26.1" +rust_decimal = { version = "=1.26.1", features = ["borsh"] } +rust_decimal_macros = "=1.26.1" thiserror = "1.0.38" tracing = "0.1.30" data-encoding = "2.3.2" diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 8d7c312ecf..541cce2dd7 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -9,7 +9,7 @@ version = "0.15.3" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] -default = ["abciplus"] +default = ["abciplus", "namada-sdk"] mainnet = [ "namada_core/mainnet", ] @@ -70,6 +70,11 @@ ibc-mocks-abcipp = [ "namada_core/ibc-mocks-abcipp", ] +masp-tx-gen = [ + "rand", + "rand_core", +] + # for integration tests and test utilies testing = [ "namada_core/testing", @@ -79,7 +84,15 @@ testing = [ "tempfile", ] +namada-sdk = [ + "tendermint-rpc", + "masp-tx-gen", + "ferveo-tpke", + "masp_primitives/transparent-inputs", +] + [dependencies] +async-std = "1.11.0" namada_core = {path = "../core", default-features = false, features = ["secp256k1-sign-verify"]} namada_proof_of_stake = {path = "../proof_of_stake", default-features = false} async-trait = {version = "0.1.51", optional = true} @@ -105,17 +118,18 @@ proptest = {git = "https://github.com/heliaxdev/proptest", rev = "8f1b4abe7ebd35 prost = "0.11.6" pwasm-utils = {git = "https://github.com/heliaxdev/wasm-utils", tag = "v0.20.0", features = ["sign_ext"], optional = true} rayon = {version = "=1.5.3", optional = true} -rust_decimal = "1.26.1" -rust_decimal_macros = "1.26.1" +rust_decimal = "=1.26.1" +rust_decimal_macros = "=1.26.1" +serde = {version = "1.0.125", features = ["derive"]} serde_json = "1.0.62" sha2 = "0.9.3" # We switch off "blake2b" because it cannot be compiled to wasm tempfile = {version = "3.2.0", optional = true} -tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} -tendermint-rpc-abcipp = {package = "tendermint-rpc", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", features = ["http-client"], optional = true} -tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "a3a0ad5f07d380976bbd5321239aec9cc3a8f916", optional = true} +tendermint-abcipp = {package = "tendermint", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} +tendermint-rpc-abcipp = {package = "tendermint-rpc", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", features = ["http-client"], optional = true} +tendermint-proto-abcipp = {package = "tendermint-proto", git = "https://github.com/heliaxdev/tendermint-rs", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35", optional = true} tendermint = {version = "0.23.6", optional = true} -tendermint-rpc = {version = "0.23.6", features = ["http-client"], optional = true} +tendermint-rpc = {version = "0.23.6", default-features = false, features = ["trait-client"], optional = true} tendermint-proto = {version = "0.23.6", optional = true} thiserror = "1.0.38" tracing = "0.1.30" @@ -129,7 +143,13 @@ wasmparser = "0.83.0" #libmasp = { git = "https://github.com/anoma/masp", branch = "murisi/masp-incentive" } masp_primitives = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c" } masp_proofs = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c" } +rand = {version = "0.8", default-features = false, optional = true} +rand_core = {version = "0.6", default-features = false, optional = true} zeroize = "1.5.5" +toml = "0.5.8" +bimap = {version = "0.6.2", features = ["serde"]} +orion = "0.16.0" +tokio = {version = "1.8.2", default-features = false} [dev-dependencies] assert_matches = "1.5.0" diff --git a/shared/src/ledger/args.rs b/shared/src/ledger/args.rs new file mode 100644 index 0000000000..813ee4da92 --- /dev/null +++ b/shared/src/ledger/args.rs @@ -0,0 +1,511 @@ +//! Structures encapsulating SDK arguments +use namada_core::types::chain::ChainId; +use namada_core::types::time::DateTimeUtc; +use rust_decimal::Decimal; + +use crate::ibc::core::ics24_host::identifier::{ChannelId, PortId}; +use crate::types::address::Address; +use crate::types::key::{common, SchemeType}; +use crate::types::masp::MaspValue; +use crate::types::storage::Epoch; +use crate::types::transaction::GasLimit; +use crate::types::{storage, token}; + +/// Abstraction of types being used in Namada +pub trait NamadaTypes: Clone + std::fmt::Debug { + /// Represents an address on the ledger + type Address: Clone + std::fmt::Debug; + /// Represents the address of a native token + type NativeAddress: Clone + std::fmt::Debug; + /// Represents a key pair + type Keypair: Clone + std::fmt::Debug; + /// Represents the address of a Tendermint endpoint + type TendermintAddress: Clone + std::fmt::Debug; + /// Represents a viewing key + type ViewingKey: Clone + std::fmt::Debug; + /// Represents the owner of a balance + type BalanceOwner: Clone + std::fmt::Debug; + /// Represents a public key + type PublicKey: Clone + std::fmt::Debug; + /// Represents the source of a Transfer + type TransferSource: Clone + std::fmt::Debug; + /// Represents the target of a Transfer + type TransferTarget: Clone + std::fmt::Debug; + /// Represents some data that is used in a transaction + type Data: Clone + std::fmt::Debug; +} + +/// The concrete types being used in Namada SDK +#[derive(Clone, Debug)] +pub struct SdkTypes; + +impl NamadaTypes for SdkTypes { + type Address = Address; + type BalanceOwner = namada_core::types::masp::BalanceOwner; + type Data = Vec; + type Keypair = namada_core::types::key::common::SecretKey; + type NativeAddress = Address; + type PublicKey = namada_core::types::key::common::PublicKey; + type TendermintAddress = (); + type TransferSource = namada_core::types::masp::TransferSource; + type TransferTarget = namada_core::types::masp::TransferTarget; + type ViewingKey = namada_core::types::masp::ExtendedViewingKey; +} + +/// Common query arguments +#[derive(Clone, Debug)] +pub struct Query { + /// The address of the ledger node as host:port + pub ledger_address: C::TendermintAddress, +} + +/// Transaction associated results arguments +#[derive(Clone, Debug)] +pub struct QueryResult { + /// Common query args + pub query: Query, + /// Hash of transaction to lookup + pub tx_hash: String, +} + +/// Custom transaction arguments +#[derive(Clone, Debug)] +pub struct TxCustom { + /// Common tx arguments + pub tx: Tx, + /// Path to the tx WASM code file + pub code_path: C::Data, + /// Path to the data file + pub data_path: Option, +} + +/// Transfer transaction arguments +#[derive(Clone, Debug)] +pub struct TxTransfer { + /// Common tx arguments + pub tx: Tx, + /// Transfer source address + pub source: C::TransferSource, + /// Transfer target address + pub target: C::TransferTarget, + /// Transferred token address + pub token: C::Address, + /// Transferred token address + pub sub_prefix: Option, + /// Transferred token amount + pub amount: token::Amount, + /// Native token address + pub native_token: C::NativeAddress, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, +} + +/// IBC transfer transaction arguments +#[derive(Clone, Debug)] +pub struct TxIbcTransfer { + /// Common tx arguments + pub tx: Tx, + /// Transfer source address + pub source: C::Address, + /// Transfer target address + pub receiver: String, + /// Transferred token address + pub token: C::Address, + /// Transferred token address + pub sub_prefix: Option, + /// Transferred token amount + pub amount: token::Amount, + /// Port ID + pub port_id: PortId, + /// Channel ID + pub channel_id: ChannelId, + /// Timeout height of the destination chain + pub timeout_height: Option, + /// Timeout timestamp offset + pub timeout_sec_offset: Option, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, +} + +/// Transaction to initialize a new account +#[derive(Clone, Debug)] +pub struct TxInitAccount { + /// Common tx arguments + pub tx: Tx, + /// Address of the source account + pub source: C::Address, + /// Wasm VP for the new account + pub vp_code: C::Data, + /// Path to the VP WASM code file for the new account + pub vp_code_path: C::Data, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, + /// Public key for the new account + pub public_key: C::PublicKey, +} + +/// Transaction to initialize a new account +#[derive(Clone, Debug)] +pub struct TxInitValidator { + /// Common tx arguments + pub tx: Tx, + /// Source + pub source: C::Address, + /// Signature scheme + pub scheme: SchemeType, + /// Account key + pub account_key: Option, + /// Consensus key + pub consensus_key: Option, + /// Protocol key + pub protocol_key: Option, + /// Commission rate + pub commission_rate: Decimal, + /// Maximum commission rate change + pub max_commission_rate_change: Decimal, + /// Path to the VP WASM code file + pub validator_vp_code_path: C::Data, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, + /// Don't encrypt the keypair + pub unsafe_dont_encrypt: bool, +} + +/// Transaction to update a VP arguments +#[derive(Clone, Debug)] +pub struct TxUpdateVp { + /// Common tx arguments + pub tx: Tx, + /// Path to the VP WASM code file + pub vp_code_path: C::Data, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, + /// Address of the account whose VP is to be updated + pub addr: C::Address, +} + +/// Bond arguments +#[derive(Clone, Debug)] +pub struct Bond { + /// Common tx arguments + pub tx: Tx, + /// Validator address + pub validator: C::Address, + /// Amount of tokens to stake in a bond + pub amount: token::Amount, + /// Source address for delegations. For self-bonds, the validator is + /// also the source. + pub source: Option, + /// Native token address + pub native_token: C::NativeAddress, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, +} + +/// Unbond arguments +#[derive(Clone, Debug)] +pub struct Unbond { + /// Common tx arguments + pub tx: Tx, + /// Validator address + pub validator: C::Address, + /// Amount of tokens to unbond from a bond + pub amount: token::Amount, + /// Source address for unbonding from delegations. For unbonding from + /// self-bonds, the validator is also the source + pub source: Option, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, +} + +/// Reveal public key +#[derive(Clone, Debug)] +pub struct RevealPk { + /// Common tx arguments + pub tx: Tx, + /// A public key to be revealed on-chain + pub public_key: C::PublicKey, +} + +/// Query proposal +#[derive(Clone, Debug)] +pub struct QueryProposal { + /// Common query args + pub query: Query, + /// Proposal id + pub proposal_id: Option, +} + +/// Query protocol parameters +#[derive(Clone, Debug)] +pub struct QueryProtocolParameters { + /// Common query args + pub query: Query, +} + +/// Withdraw arguments +#[derive(Clone, Debug)] +pub struct Withdraw { + /// Common tx arguments + pub tx: Tx, + /// Validator address + pub validator: C::Address, + /// Source address for withdrawing from delegations. For withdrawing + /// from self-bonds, the validator is also the source + pub source: Option, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, +} + +/// Query asset conversions +#[derive(Clone, Debug)] +pub struct QueryConversions { + /// Common query args + pub query: Query, + /// Address of a token + pub token: Option, + /// Epoch of the asset + pub epoch: Option, +} + +/// Query token balance(s) +#[derive(Clone, Debug)] +pub struct QueryBalance { + /// Common query args + pub query: Query, + /// Address of an owner + pub owner: Option, + /// Address of a token + pub token: Option, + /// Whether not to convert balances + pub no_conversions: bool, + /// Sub prefix of an account + pub sub_prefix: Option, +} + +/// Query historical transfer(s) +#[derive(Clone, Debug)] +pub struct QueryTransfers { + /// Common query args + pub query: Query, + /// Address of an owner + pub owner: Option, + /// Address of a token + pub token: Option, +} + +/// Query PoS bond(s) +#[derive(Clone, Debug)] +pub struct QueryBonds { + /// Common query args + pub query: Query, + /// Address of an owner + pub owner: Option, + /// Address of a validator + pub validator: Option, +} + +/// Query PoS bonded stake +#[derive(Clone, Debug)] +pub struct QueryBondedStake { + /// Common query args + pub query: Query, + /// Address of a validator + pub validator: Option, + /// Epoch in which to find bonded stake + pub epoch: Option, +} + +#[derive(Clone, Debug)] +/// Commission rate change args +pub struct TxCommissionRateChange { + /// Common tx arguments + pub tx: Tx, + /// Validator address (should be self) + pub validator: C::Address, + /// Value to which the tx changes the commission rate + pub rate: Decimal, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, +} + +/// Query PoS commission rate +#[derive(Clone, Debug)] +pub struct QueryCommissionRate { + /// Common query args + pub query: Query, + /// Address of a validator + pub validator: C::Address, + /// Epoch in which to find commission rate + pub epoch: Option, +} + +/// Query PoS slashes +#[derive(Clone, Debug)] +pub struct QuerySlashes { + /// Common query args + pub query: Query, + /// Address of a validator + pub validator: Option, +} + +/// Query PoS delegations +#[derive(Clone, Debug)] +pub struct QueryDelegations { + /// Common query args + pub query: Query, + /// Address of an owner + pub owner: C::Address, +} + +/// Query the raw bytes of given storage key +#[derive(Clone, Debug)] +pub struct QueryRawBytes { + /// The storage key to query + pub storage_key: storage::Key, + /// Common query args + pub query: Query, +} + +/// Common transaction arguments +#[derive(Clone, Debug)] +pub struct Tx { + /// Simulate applying the transaction + pub dry_run: bool, + /// Dump the transaction bytes + pub dump_tx: bool, + /// Submit the transaction even if it doesn't pass client checks + pub force: bool, + /// Do not wait for the transaction to be added to the blockchain + pub broadcast_only: bool, + /// The address of the ledger node as host:port + pub ledger_address: C::TendermintAddress, + /// If any new account is initialized by the tx, use the given alias to + /// save it in the wallet. + pub initialized_account_alias: Option, + /// The amount being payed to include the transaction + pub fee_amount: token::Amount, + /// The token in which the fee is being paid + pub fee_token: C::Address, + /// The max amount of gas used to process tx + pub gas_limit: GasLimit, + /// The optional expiration of the transaction + pub expiration: Option, + /// The chain id for which the transaction is intended + pub chain_id: Option, + /// Sign the tx with the key for the given alias from your wallet + pub signing_key: Option, + /// Sign the tx with the keypair of the public key of the given address + pub signer: Option, + /// Path to the TX WASM code file + pub tx_code_path: C::Data, + /// Password to decrypt key + pub password: Option, +} + +/// MASP add key or address arguments +#[derive(Clone, Debug)] +pub struct MaspAddrKeyAdd { + /// Key alias + pub alias: String, + /// Any MASP value + pub value: MaspValue, + /// Don't encrypt the keypair + pub unsafe_dont_encrypt: bool, +} + +/// MASP generate spending key arguments +#[derive(Clone, Debug)] +pub struct MaspSpendKeyGen { + /// Key alias + pub alias: String, + /// Don't encrypt the keypair + pub unsafe_dont_encrypt: bool, +} + +/// MASP generate payment address arguments +#[derive(Clone, Debug)] +pub struct MaspPayAddrGen { + /// Key alias + pub alias: String, + /// Viewing key + pub viewing_key: C::ViewingKey, + /// Pin + pub pin: bool, +} + +/// Wallet generate key and implicit address arguments +#[derive(Clone, Debug)] +pub struct KeyAndAddressGen { + /// Scheme type + pub scheme: SchemeType, + /// Key alias + pub alias: Option, + /// Don't encrypt the keypair + pub unsafe_dont_encrypt: bool, +} + +/// Wallet key lookup arguments +#[derive(Clone, Debug)] +pub struct KeyFind { + /// Public key to lookup keypair with + pub public_key: Option, + /// Key alias to lookup keypair with + pub alias: Option, + /// Public key hash to lookup keypair with + pub value: Option, + /// Show secret keys to user + pub unsafe_show_secret: bool, +} + +/// Wallet find shielded address or key arguments +#[derive(Clone, Debug)] +pub struct AddrKeyFind { + /// Address/key alias + pub alias: String, + /// Show secret keys to user + pub unsafe_show_secret: bool, +} + +/// Wallet list shielded keys arguments +#[derive(Clone, Debug)] +pub struct MaspKeysList { + /// Don't decrypt spending keys + pub decrypt: bool, + /// Show secret keys to user + pub unsafe_show_secret: bool, +} + +/// Wallet list keys arguments +#[derive(Clone, Debug)] +pub struct KeyList { + /// Don't decrypt keypairs + pub decrypt: bool, + /// Show secret keys to user + pub unsafe_show_secret: bool, +} + +/// Wallet key export arguments +#[derive(Clone, Debug)] +pub struct KeyExport { + /// Key alias + pub alias: String, +} + +/// Wallet address lookup arguments +#[derive(Clone, Debug)] +pub struct AddressOrAliasFind { + /// Alias to find + pub alias: Option, + /// Address to find + pub address: Option
, +} + +/// Wallet address add arguments +#[derive(Clone, Debug)] +pub struct AddressAdd { + /// Address alias + pub alias: String, + /// Address to add + pub address: Address, +} diff --git a/shared/src/ledger/masp.rs b/shared/src/ledger/masp.rs index 10c63db4cb..2c43028333 100644 --- a/shared/src/ledger/masp.rs +++ b/shared/src/ledger/masp.rs @@ -1,22 +1,71 @@ //! MASP verification wrappers. +use std::collections::hash_map::Entry; +use std::collections::{BTreeMap, HashMap, HashSet}; use std::env; +use std::fmt::Debug; use std::fs::File; +#[cfg(feature = "masp-tx-gen")] use std::ops::Deref; use std::path::PathBuf; +use async_trait::async_trait; use bellman::groth16::{prepare_verifying_key, PreparedVerifyingKey}; use bls12_381::Bls12; +// use async_std::io::prelude::WriteExt; +// use async_std::io::{self}; +use borsh::{BorshDeserialize, BorshSerialize}; +use itertools::Either; use masp_primitives::asset_type::AssetType; use masp_primitives::consensus::BranchId::Sapling; +use masp_primitives::consensus::{BranchId, TestNetwork}; +use masp_primitives::convert::AllowedConversion; +use masp_primitives::ff::PrimeField; +use masp_primitives::group::cofactor::CofactorGroup; +use masp_primitives::keys::FullViewingKey; +#[cfg(feature = "masp-tx-gen")] +use masp_primitives::legacy::TransparentAddress; +use masp_primitives::merkle_tree::{ + CommitmentTree, IncrementalWitness, MerklePath, +}; +use masp_primitives::note_encryption::*; +use masp_primitives::primitives::{Diversifier, Note, ViewingKey}; use masp_primitives::redjubjub::PublicKey; +use masp_primitives::sapling::Node; +#[cfg(feature = "masp-tx-gen")] +use masp_primitives::transaction::builder::{self, secp256k1, *}; use masp_primitives::transaction::components::{ - ConvertDescription, OutputDescription, SpendDescription, + Amount, ConvertDescription, OutputDescription, SpendDescription, }; +#[cfg(feature = "masp-tx-gen")] +use masp_primitives::transaction::components::{OutPoint, TxOut}; use masp_primitives::transaction::{ signature_hash_data, Transaction, SIGHASH_ALL, }; +use masp_primitives::zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}; +use masp_proofs::prover::LocalTxProver; use masp_proofs::sapling::SaplingVerificationContext; +use namada_core::types::transaction::AffineCurve; +#[cfg(feature = "masp-tx-gen")] +use rand_core::{CryptoRng, OsRng, RngCore}; +#[cfg(feature = "masp-tx-gen")] +use sha2::Digest; + +use crate::ledger::queries::Client; +use crate::ledger::{args, rpc}; +use crate::proto::{SignedTxData, Tx}; +use crate::tendermint_rpc::query::Query; +use crate::tendermint_rpc::Order; +use crate::types::address::{masp, Address}; +use crate::types::masp::{BalanceOwner, ExtendedViewingKey, PaymentAddress}; +use crate::types::storage::{BlockHeight, Epoch, Key, KeySeg, TxIndex}; +use crate::types::token; +use crate::types::token::{ + Transfer, HEAD_TX_KEY, PIN_KEY_PREFIX, TX_KEY_PREFIX, +}; +use crate::types::transaction::{ + process_tx, DecryptedTx, EllipticCurve, PairingEngine, TxType, WrapperTx, +}; /// Env var to point to a dir with MASP parameters. When not specified, /// the default OS specific path is used. @@ -200,3 +249,1218 @@ pub fn get_params_dir() -> PathBuf { masp_proofs::default_params_folder().unwrap() } } + +/// Abstracts platform specific details away from the logic of shielded pool +/// operations. +#[async_trait] +pub trait ShieldedUtils: + Sized + BorshDeserialize + BorshSerialize + Default + Clone +{ + /// The type of the Tendermint client to make queries with + type C: crate::ledger::queries::Client + std::marker::Sync; + + /// Get a MASP transaction prover + fn local_tx_prover(&self) -> LocalTxProver; + + /// Load up the currently saved ShieldedContext + fn load(self) -> std::io::Result>; + + /// Sace the given ShieldedContext for future loads + fn save(&self, ctx: &ShieldedContext) -> std::io::Result<()>; +} + +/// Make a ViewingKey that can view notes encrypted by given ExtendedSpendingKey +pub fn to_viewing_key(esk: &ExtendedSpendingKey) -> FullViewingKey { + ExtendedFullViewingKey::from(esk).fvk +} + +/// Generate a valid diversifier, i.e. one that has a diversified base. Return +/// also this diversified base. +#[cfg(feature = "masp-tx-gen")] +pub fn find_valid_diversifier( + rng: &mut R, +) -> (Diversifier, masp_primitives::jubjub::SubgroupPoint) { + let mut diversifier; + let g_d; + // Keep generating random diversifiers until one has a diversified base + loop { + let mut d = [0; 11]; + rng.fill_bytes(&mut d); + diversifier = Diversifier(d); + if let Some(val) = diversifier.g_d() { + g_d = val; + break; + } + } + (diversifier, g_d) +} + +/// Determine if using the current note would actually bring us closer to our +/// target +pub fn is_amount_required(src: Amount, dest: Amount, delta: Amount) -> bool { + if delta > Amount::zero() { + let gap = dest - src; + for (asset_type, value) in gap.components() { + if *value > 0 && delta[asset_type] > 0 { + return true; + } + } + } + false +} + +/// An extension of Option's cloned method for pair types +fn cloned_pair((a, b): (&T, &U)) -> (T, U) { + (a.clone(), b.clone()) +} + +/// Errors that can occur when trying to retrieve pinned transaction +#[derive(PartialEq, Eq)] +pub enum PinnedBalanceError { + /// No transaction has yet been pinned to the given payment address + NoTransactionPinned, + /// The supplied viewing key does not recognize payments to given address + InvalidViewingKey, +} + +/// Represents the amount used of different conversions +pub type Conversions = + HashMap, i64)>; + +/// Represents the changes that were made to a list of transparent accounts +pub type TransferDelta = HashMap>; + +/// Represents the changes that were made to a list of shielded accounts +pub type TransactionDelta = HashMap; + +/// Represents the current state of the shielded pool from the perspective of +/// the chosen viewing keys. +#[derive(BorshSerialize, BorshDeserialize, Debug)] +pub struct ShieldedContext { + /// Location where this shielded context is saved + #[borsh_skip] + pub utils: U, + /// The last transaction index to be processed in this context + pub last_txidx: u64, + /// The commitment tree produced by scanning all transactions up to tx_pos + pub tree: CommitmentTree, + /// Maps viewing keys to applicable note positions + pub pos_map: HashMap>, + /// Maps a nullifier to the note position to which it applies + pub nf_map: HashMap<[u8; 32], usize>, + /// Maps note positions to their corresponding notes + pub note_map: HashMap, + /// Maps note positions to their corresponding memos + pub memo_map: HashMap, + /// Maps note positions to the diversifier of their payment address + pub div_map: HashMap, + /// Maps note positions to their witness (used to make merkle paths) + pub witness_map: HashMap>, + /// Tracks what each transaction does to various account balances + pub delta_map: BTreeMap< + (BlockHeight, TxIndex), + (Epoch, TransferDelta, TransactionDelta), + >, + /// The set of note positions that have been spent + pub spents: HashSet, + /// Maps asset types to their decodings + pub asset_types: HashMap, + /// Maps note positions to their corresponding viewing keys + pub vk_map: HashMap, +} + +/// Default implementation to ease construction of TxContexts. Derive cannot be +/// used here due to CommitmentTree not implementing Default. +impl Default for ShieldedContext { + fn default() -> ShieldedContext { + ShieldedContext:: { + utils: U::default(), + last_txidx: u64::default(), + tree: CommitmentTree::empty(), + pos_map: HashMap::default(), + nf_map: HashMap::default(), + note_map: HashMap::default(), + memo_map: HashMap::default(), + div_map: HashMap::default(), + witness_map: HashMap::default(), + spents: HashSet::default(), + delta_map: BTreeMap::default(), + asset_types: HashMap::default(), + vk_map: HashMap::default(), + } + } +} + +impl ShieldedContext { + /// Try to load the last saved shielded context from the given context + /// directory. If this fails, then leave the current context unchanged. + pub fn load(&mut self) -> std::io::Result<()> { + let new_ctx = self.utils.clone().load()?; + *self = new_ctx; + Ok(()) + } + + /// Save this shielded context into its associated context directory + pub fn save(&self) -> std::io::Result<()> { + self.utils.save(self) + } + + /// Merge data from the given shielded context into the current shielded + /// context. It must be the case that the two shielded contexts share the + /// same last transaction ID and share identical commitment trees. + pub fn merge(&mut self, new_ctx: ShieldedContext) { + debug_assert_eq!(self.last_txidx, new_ctx.last_txidx); + // Merge by simply extending maps. Identical keys should contain + // identical values, so overwriting should not be problematic. + self.pos_map.extend(new_ctx.pos_map); + self.nf_map.extend(new_ctx.nf_map); + self.note_map.extend(new_ctx.note_map); + self.memo_map.extend(new_ctx.memo_map); + self.div_map.extend(new_ctx.div_map); + self.witness_map.extend(new_ctx.witness_map); + self.spents.extend(new_ctx.spents); + self.asset_types.extend(new_ctx.asset_types); + self.vk_map.extend(new_ctx.vk_map); + // The deltas are the exception because different keys can reveal + // different parts of the same transaction. Hence each delta needs to be + // merged separately. + for ((height, idx), (ep, ntfer_delta, ntx_delta)) in new_ctx.delta_map { + let (_ep, tfer_delta, tx_delta) = self + .delta_map + .entry((height, idx)) + .or_insert((ep, TransferDelta::new(), TransactionDelta::new())); + tfer_delta.extend(ntfer_delta); + tx_delta.extend(ntx_delta); + } + } + + /// Fetch the current state of the multi-asset shielded pool into a + /// ShieldedContext + pub async fn fetch( + &mut self, + client: &U::C, + sks: &[ExtendedSpendingKey], + fvks: &[ViewingKey], + ) { + // First determine which of the keys requested to be fetched are new. + // Necessary because old transactions will need to be scanned for new + // keys. + let mut unknown_keys = Vec::new(); + for esk in sks { + let vk = to_viewing_key(esk).vk; + if !self.pos_map.contains_key(&vk) { + unknown_keys.push(vk); + } + } + for vk in fvks { + if !self.pos_map.contains_key(vk) { + unknown_keys.push(*vk); + } + } + + // If unknown keys are being used, we need to scan older transactions + // for any unspent notes + let (txs, mut tx_iter); + if !unknown_keys.is_empty() { + // Load all transactions accepted until this point + txs = Self::fetch_shielded_transfers(client, 0).await; + tx_iter = txs.iter(); + // Do this by constructing a shielding context only for unknown keys + let mut tx_ctx = Self { + utils: self.utils.clone(), + ..Default::default() + }; + for vk in unknown_keys { + tx_ctx.pos_map.entry(vk).or_insert_with(HashSet::new); + } + // Update this unknown shielded context until it is level with self + while tx_ctx.last_txidx != self.last_txidx { + if let Some(((height, idx), (epoch, tx))) = tx_iter.next() { + tx_ctx.scan_tx(*height, *idx, *epoch, tx); + } else { + break; + } + } + // Merge the context data originating from the unknown keys into the + // current context + self.merge(tx_ctx); + } else { + // Load only transactions accepted from last_txid until this point + txs = Self::fetch_shielded_transfers(client, self.last_txidx).await; + tx_iter = txs.iter(); + } + // Now that we possess the unspent notes corresponding to both old and + // new keys up until tx_pos, proceed to scan the new transactions. + for ((height, idx), (epoch, tx)) in &mut tx_iter { + self.scan_tx(*height, *idx, *epoch, tx); + } + } + + /// Obtain a chronologically-ordered list of all accepted shielded + /// transactions from the ledger. The ledger conceptually stores + /// transactions as a vector. More concretely, the HEAD_TX_KEY location + /// stores the index of the last accepted transaction and each transaction + /// is stored at a key derived from its index. + pub async fn fetch_shielded_transfers( + client: &U::C, + last_txidx: u64, + ) -> BTreeMap<(BlockHeight, TxIndex), (Epoch, Transfer)> { + // The address of the MASP account + let masp_addr = masp(); + // Construct the key where last transaction pointer is stored + let head_tx_key = Key::from(masp_addr.to_db_key()) + .push(&HEAD_TX_KEY.to_owned()) + .expect("Cannot obtain a storage key"); + // Query for the index of the last accepted transaction + let head_txidx = + rpc::query_storage_value::(client, &head_tx_key) + .await + .unwrap_or(0); + let mut shielded_txs = BTreeMap::new(); + // Fetch all the transactions we do not have yet + for i in last_txidx..head_txidx { + // Construct the key for where the current transaction is stored + let current_tx_key = Key::from(masp_addr.to_db_key()) + .push(&(TX_KEY_PREFIX.to_owned() + &i.to_string())) + .expect("Cannot obtain a storage key"); + // Obtain the current transaction + let (tx_epoch, tx_height, tx_index, current_tx) = + rpc::query_storage_value::< + U::C, + (Epoch, BlockHeight, TxIndex, Transfer), + >(client, ¤t_tx_key) + .await + .unwrap(); + // Collect the current transaction + shielded_txs.insert((tx_height, tx_index), (tx_epoch, current_tx)); + } + shielded_txs + } + + /// Applies the given transaction to the supplied context. More precisely, + /// the shielded transaction's outputs are added to the commitment tree. + /// Newly discovered notes are associated to the supplied viewing keys. Note + /// nullifiers are mapped to their originating notes. Note positions are + /// associated to notes, memos, and diversifiers. And the set of notes that + /// we have spent are updated. The witness map is maintained to make it + /// easier to construct note merkle paths in other code. See + /// https://zips.z.cash/protocol/protocol.pdf#scan + pub fn scan_tx( + &mut self, + height: BlockHeight, + index: TxIndex, + epoch: Epoch, + tx: &Transfer, + ) { + // Ignore purely transparent transactions + let shielded = if let Some(shielded) = &tx.shielded { + shielded + } else { + return; + }; + // For tracking the account changes caused by this Transaction + let mut transaction_delta = TransactionDelta::new(); + // Listen for notes sent to our viewing keys + for so in &shielded.shielded_outputs { + // Create merkle tree leaf node from note commitment + let node = Node::new(so.cmu.to_repr()); + // Update each merkle tree in the witness map with the latest + // addition + for (_, witness) in self.witness_map.iter_mut() { + witness.append(node).expect("note commitment tree is full"); + } + let note_pos = self.tree.size(); + self.tree + .append(node) + .expect("note commitment tree is full"); + // Finally, make it easier to construct merkle paths to this new + // note + let witness = IncrementalWitness::::from_tree(&self.tree); + self.witness_map.insert(note_pos, witness); + // Let's try to see if any of our viewing keys can decrypt latest + // note + for (vk, notes) in self.pos_map.iter_mut() { + let decres = try_sapling_note_decryption::( + 0, + &vk.ivk().0, + &so.ephemeral_key.into_subgroup().unwrap(), + &so.cmu, + &so.enc_ciphertext, + ); + // So this current viewing key does decrypt this current note... + if let Some((note, pa, memo)) = decres { + // Add this note to list of notes decrypted by this viewing + // key + notes.insert(note_pos); + // Compute the nullifier now to quickly recognize when spent + let nf = note.nf(vk, note_pos.try_into().unwrap()); + self.note_map.insert(note_pos, note); + self.memo_map.insert(note_pos, memo); + // The payment address' diversifier is required to spend + // note + self.div_map.insert(note_pos, *pa.diversifier()); + self.nf_map.insert(nf.0, note_pos); + // Note the account changes + let balance = transaction_delta + .entry(*vk) + .or_insert_with(Amount::zero); + *balance += + Amount::from_nonnegative(note.asset_type, note.value) + .expect( + "found note with invalid value or asset type", + ); + self.vk_map.insert(note_pos, *vk); + break; + } + } + } + // Cancel out those of our notes that have been spent + for ss in &shielded.shielded_spends { + // If the shielded spend's nullifier is in our map, then target note + // is rendered unusable + if let Some(note_pos) = self.nf_map.get(&ss.nullifier) { + self.spents.insert(*note_pos); + // Note the account changes + let balance = transaction_delta + .entry(self.vk_map[note_pos]) + .or_insert_with(Amount::zero); + let note = self.note_map[note_pos]; + *balance -= + Amount::from_nonnegative(note.asset_type, note.value) + .expect("found note with invalid value or asset type"); + } + } + // Record the changes to the transparent accounts + let transparent_delta = + Amount::from_nonnegative(tx.token.clone(), u64::from(tx.amount)) + .expect("invalid value for amount"); + let mut transfer_delta = TransferDelta::new(); + transfer_delta + .insert(tx.source.clone(), Amount::zero() - &transparent_delta); + transfer_delta.insert(tx.target.clone(), transparent_delta); + self.delta_map.insert( + (height, index), + (epoch, transfer_delta, transaction_delta), + ); + self.last_txidx += 1; + } + + /// Summarize the effects on shielded and transparent accounts of each + /// Transfer in this context + pub fn get_tx_deltas( + &self, + ) -> &BTreeMap< + (BlockHeight, TxIndex), + (Epoch, TransferDelta, TransactionDelta), + > { + &self.delta_map + } + + /// Compute the total unspent notes associated with the viewing key in the + /// context. If the key is not in the context, then we do not know the + /// balance and hence we return None. + pub fn compute_shielded_balance(&self, vk: &ViewingKey) -> Option { + // Cannot query the balance of a key that's not in the map + if !self.pos_map.contains_key(vk) { + return None; + } + let mut val_acc = Amount::zero(); + // Retrieve the notes that can be spent by this key + if let Some(avail_notes) = self.pos_map.get(vk) { + for note_idx in avail_notes { + // Spent notes cannot contribute a new transaction's pool + if self.spents.contains(note_idx) { + continue; + } + // Get note associated with this ID + let note = self.note_map.get(note_idx).unwrap(); + // Finally add value to multi-asset accumulator + val_acc += + Amount::from_nonnegative(note.asset_type, note.value) + .expect("found note with invalid value or asset type"); + } + } + Some(val_acc) + } + + /// Query the ledger for the decoding of the given asset type and cache it + /// if it is found. + pub async fn decode_asset_type( + &mut self, + client: &U::C, + asset_type: AssetType, + ) -> Option<(Address, Epoch)> { + // Try to find the decoding in the cache + if let decoded @ Some(_) = self.asset_types.get(&asset_type) { + return decoded.cloned(); + } + // Query for the ID of the last accepted transaction + let (addr, ep, _conv, _path): (Address, _, Amount, MerklePath) = + rpc::query_conversion(client, asset_type).await?; + self.asset_types.insert(asset_type, (addr.clone(), ep)); + Some((addr, ep)) + } + + /// Query the ledger for the conversion that is allowed for the given asset + /// type and cache it. + async fn query_allowed_conversion<'a>( + &'a mut self, + client: &U::C, + asset_type: AssetType, + conversions: &'a mut Conversions, + ) -> Option<&'a mut (AllowedConversion, MerklePath, i64)> { + match conversions.entry(asset_type) { + Entry::Occupied(conv_entry) => Some(conv_entry.into_mut()), + Entry::Vacant(conv_entry) => { + // Query for the ID of the last accepted transaction + let (addr, ep, conv, path): (Address, _, _, _) = + rpc::query_conversion(client, asset_type).await?; + self.asset_types.insert(asset_type, (addr, ep)); + // If the conversion is 0, then we just have a pure decoding + if conv == Amount::zero() { + None + } else { + Some(conv_entry.insert((Amount::into(conv), path, 0))) + } + } + } + } + + /// Compute the total unspent notes associated with the viewing key in the + /// context and express that value in terms of the currently timestamped + /// asset types. If the key is not in the context, then we do not know the + /// balance and hence we return None. + pub async fn compute_exchanged_balance( + &mut self, + client: &U::C, + vk: &ViewingKey, + target_epoch: Epoch, + ) -> Option { + // First get the unexchanged balance + if let Some(balance) = self.compute_shielded_balance(vk) { + // And then exchange balance into current asset types + Some( + self.compute_exchanged_amount( + client, + balance, + target_epoch, + HashMap::new(), + ) + .await + .0, + ) + } else { + None + } + } + + /// Try to convert as much of the given asset type-value pair using the + /// given allowed conversion. usage is incremented by the amount of the + /// conversion used, the conversions are applied to the given input, and + /// the trace amount that could not be converted is moved from input to + /// output. + fn apply_conversion( + conv: AllowedConversion, + asset_type: AssetType, + value: i64, + usage: &mut i64, + input: &mut Amount, + output: &mut Amount, + ) { + // If conversion if possible, accumulate the exchanged amount + let conv: Amount = conv.into(); + // The amount required of current asset to qualify for conversion + let threshold = -conv[&asset_type]; + if threshold == 0 { + eprintln!( + "Asset threshold of selected conversion for asset type {} is \ + 0, this is a bug, please report it.", + asset_type + ); + } + // We should use an amount of the AllowedConversion that almost + // cancels the original amount + let required = value / threshold; + // Forget about the trace amount left over because we cannot + // realize its value + let trace = Amount::from_pair(asset_type, value % threshold).unwrap(); + // Record how much more of the given conversion has been used + *usage += required; + // Apply the conversions to input and move the trace amount to output + *input += conv * required - &trace; + *output += trace; + } + + /// Convert the given amount into the latest asset types whilst making a + /// note of the conversions that were used. Note that this function does + /// not assume that allowed conversions from the ledger are expressed in + /// terms of the latest asset types. + pub async fn compute_exchanged_amount( + &mut self, + client: &U::C, + mut input: Amount, + target_epoch: Epoch, + mut conversions: Conversions, + ) -> (Amount, Conversions) { + // Where we will store our exchanged value + let mut output = Amount::zero(); + // Repeatedly exchange assets until it is no longer possible + while let Some((asset_type, value)) = + input.components().next().map(cloned_pair) + { + let target_asset_type = self + .decode_asset_type(client, asset_type) + .await + .map(|(addr, _epoch)| make_asset_type(target_epoch, &addr)) + .unwrap_or(asset_type); + let at_target_asset_type = asset_type == target_asset_type; + if let (Some((conv, _wit, usage)), false) = ( + self.query_allowed_conversion( + client, + asset_type, + &mut conversions, + ) + .await, + at_target_asset_type, + ) { + println!( + "converting current asset type to latest asset type..." + ); + // Not at the target asset type, not at the latest asset type. + // Apply conversion to get from current asset type to the latest + // asset type. + Self::apply_conversion( + conv.clone(), + asset_type, + value, + usage, + &mut input, + &mut output, + ); + } else if let (Some((conv, _wit, usage)), false) = ( + self.query_allowed_conversion( + client, + target_asset_type, + &mut conversions, + ) + .await, + at_target_asset_type, + ) { + println!( + "converting latest asset type to target asset type..." + ); + // Not at the target asset type, yes at the latest asset type. + // Apply inverse conversion to get from latest asset type to + // the target asset type. + Self::apply_conversion( + conv.clone(), + asset_type, + value, + usage, + &mut input, + &mut output, + ); + } else { + // At the target asset type. Then move component over to output. + let comp = input.project(asset_type); + output += ∁ + // Strike from input to avoid repeating computation + input -= comp; + } + } + (output, conversions) + } + + /// Collect enough unspent notes in this context to exceed the given amount + /// of the specified asset type. Return the total value accumulated plus + /// notes and the corresponding diversifiers/merkle paths that were used to + /// achieve the total value. + pub async fn collect_unspent_notes( + &mut self, + client: &U::C, + vk: &ViewingKey, + target: Amount, + target_epoch: Epoch, + ) -> ( + Amount, + Vec<(Diversifier, Note, MerklePath)>, + Conversions, + ) { + // Establish connection with which to do exchange rate queries + let mut conversions = HashMap::new(); + let mut val_acc = Amount::zero(); + let mut notes = Vec::new(); + // Retrieve the notes that can be spent by this key + if let Some(avail_notes) = self.pos_map.get(vk).cloned() { + for note_idx in &avail_notes { + // No more transaction inputs are required once we have met + // the target amount + if val_acc >= target { + break; + } + // Spent notes cannot contribute a new transaction's pool + if self.spents.contains(note_idx) { + continue; + } + // Get note, merkle path, diversifier associated with this ID + let note = *self.note_map.get(note_idx).unwrap(); + + // The amount contributed by this note before conversion + let pre_contr = Amount::from_pair(note.asset_type, note.value) + .expect("received note has invalid value or asset type"); + let (contr, proposed_convs) = self + .compute_exchanged_amount( + client, + pre_contr, + target_epoch, + conversions.clone(), + ) + .await; + + // Use this note only if it brings us closer to our target + if is_amount_required( + val_acc.clone(), + target.clone(), + contr.clone(), + ) { + // Be sure to record the conversions used in computing + // accumulated value + val_acc += contr; + // Commit the conversions that were used to exchange + conversions = proposed_convs; + let merkle_path = + self.witness_map.get(note_idx).unwrap().path().unwrap(); + let diversifier = self.div_map.get(note_idx).unwrap(); + // Commit this note to our transaction + notes.push((*diversifier, note, merkle_path)); + } + } + } + (val_acc, notes, conversions) + } + + /// Compute the combined value of the output notes of the transaction pinned + /// at the given payment address. This computation uses the supplied viewing + /// keys to try to decrypt the output notes. If no transaction is pinned at + /// the given payment address fails with + /// `PinnedBalanceError::NoTransactionPinned`. + pub async fn compute_pinned_balance( + client: &U::C, + owner: PaymentAddress, + viewing_key: &ViewingKey, + ) -> Result<(Amount, Epoch), PinnedBalanceError> { + // Check that the supplied viewing key corresponds to given payment + // address + let counter_owner = viewing_key.to_payment_address( + *masp_primitives::primitives::PaymentAddress::diversifier( + &owner.into(), + ), + ); + match counter_owner { + Some(counter_owner) if counter_owner == owner.into() => {} + _ => return Err(PinnedBalanceError::InvalidViewingKey), + } + // The address of the MASP account + let masp_addr = masp(); + // Construct the key for where the transaction ID would be stored + let pin_key = Key::from(masp_addr.to_db_key()) + .push(&(PIN_KEY_PREFIX.to_owned() + &owner.hash())) + .expect("Cannot obtain a storage key"); + // Obtain the transaction pointer at the key + let txidx = rpc::query_storage_value::(client, &pin_key) + .await + .ok_or(PinnedBalanceError::NoTransactionPinned)?; + // Construct the key for where the pinned transaction is stored + let tx_key = Key::from(masp_addr.to_db_key()) + .push(&(TX_KEY_PREFIX.to_owned() + &txidx.to_string())) + .expect("Cannot obtain a storage key"); + // Obtain the pointed to transaction + let (tx_epoch, _tx_height, _tx_index, tx) = rpc::query_storage_value::< + U::C, + (Epoch, BlockHeight, TxIndex, Transfer), + >(client, &tx_key) + .await + .expect("Ill-formed epoch, transaction pair"); + // Accumulate the combined output note value into this Amount + let mut val_acc = Amount::zero(); + let tx = tx + .shielded + .expect("Pinned Transfers should have shielded part"); + for so in &tx.shielded_outputs { + // Let's try to see if our viewing key can decrypt current note + let decres = try_sapling_note_decryption::( + 0, + &viewing_key.ivk().0, + &so.ephemeral_key.into_subgroup().unwrap(), + &so.cmu, + &so.enc_ciphertext, + ); + match decres { + // So the given viewing key does decrypt this current note... + Some((note, pa, _memo)) if pa == owner.into() => { + val_acc += + Amount::from_nonnegative(note.asset_type, note.value) + .expect( + "found note with invalid value or asset type", + ); + break; + } + _ => {} + } + } + Ok((val_acc, tx_epoch)) + } + + /// Compute the combined value of the output notes of the pinned transaction + /// at the given payment address if there's any. The asset types may be from + /// the epoch of the transaction or even before, so exchange all these + /// amounts to the epoch of the transaction in order to get the value that + /// would have been displayed in the epoch of the transaction. + pub async fn compute_exchanged_pinned_balance( + &mut self, + client: &U::C, + owner: PaymentAddress, + viewing_key: &ViewingKey, + ) -> Result<(Amount, Epoch), PinnedBalanceError> { + // Obtain the balance that will be exchanged + let (amt, ep) = + Self::compute_pinned_balance(client, owner, viewing_key).await?; + // Finally, exchange the balance to the transaction's epoch + Ok(( + self.compute_exchanged_amount(client, amt, ep, HashMap::new()) + .await + .0, + ep, + )) + } + + /// Convert an amount whose units are AssetTypes to one whose units are + /// Addresses that they decode to. All asset types not corresponding to + /// the given epoch are ignored. + pub async fn decode_amount( + &mut self, + client: &U::C, + amt: Amount, + target_epoch: Epoch, + ) -> Amount
{ + let mut res = Amount::zero(); + for (asset_type, val) in amt.components() { + // Decode the asset type + let decoded = self.decode_asset_type(client, *asset_type).await; + // Only assets with the target timestamp count + match decoded { + Some((addr, epoch)) if epoch == target_epoch => { + res += &Amount::from_pair(addr, *val).unwrap() + } + _ => {} + } + } + res + } + + /// Convert an amount whose units are AssetTypes to one whose units are + /// Addresses that they decode to. + pub async fn decode_all_amounts( + &mut self, + client: &U::C, + amt: Amount, + ) -> Amount<(Address, Epoch)> { + let mut res = Amount::zero(); + for (asset_type, val) in amt.components() { + // Decode the asset type + let decoded = self.decode_asset_type(client, *asset_type).await; + // Only assets with the target timestamp count + if let Some((addr, epoch)) = decoded { + res += &Amount::from_pair((addr, epoch), *val).unwrap() + } + } + res + } + + /// Make shielded components to embed within a Transfer object. If no + /// shielded payment address nor spending key is specified, then no + /// shielded components are produced. Otherwise a transaction containing + /// nullifiers and/or note commitments are produced. Dummy transparent + /// UTXOs are sometimes used to make transactions balanced, but it is + /// understood that transparent account changes are effected only by the + /// amounts and signatures specified by the containing Transfer object. + #[cfg(feature = "masp-tx-gen")] + pub async fn gen_shielded_transfer( + &mut self, + client: &U::C, + args: args::TxTransfer, + shielded_gas: bool, + ) -> Result, builder::Error> + { + // No shielded components are needed when neither source nor destination + // are shielded + let spending_key = args.source.spending_key(); + let payment_address = args.target.payment_address(); + if spending_key.is_none() && payment_address.is_none() { + return Ok(None); + } + // We want to fund our transaction solely from supplied spending key + let spending_key = spending_key.map(|x| x.into()); + let spending_keys: Vec<_> = spending_key.into_iter().collect(); + // Load the current shielded context given the spending key we possess + let _ = self.load(); + self.fetch(client, &spending_keys, &[]).await; + // Save the update state so that future fetches can be short-circuited + let _ = self.save(); + // Determine epoch in which to submit potential shielded transaction + let epoch = rpc::query_epoch(client).await; + // Context required for storing which notes are in the source's + // possesion + let consensus_branch_id = BranchId::Sapling; + let amt: u64 = args.amount.into(); + let memo: Option = None; + + // Now we build up the transaction within this object + let mut builder = Builder::::new(0u32); + // Convert transaction amount into MASP types + let (asset_type, amount) = + convert_amount(epoch, &args.token, args.amount); + + // Transactions with transparent input and shielded output + // may be affected if constructed close to epoch boundary + let mut epoch_sensitive: bool = false; + // If there are shielded inputs + if let Some(sk) = spending_key { + // Transaction fees need to match the amount in the wrapper Transfer + // when MASP source is used + let (_, fee) = + convert_amount(epoch, &args.tx.fee_token, args.tx.fee_amount); + builder.set_fee(fee.clone())?; + // If the gas is coming from the shielded pool, then our shielded + // inputs must also cover the gas fee + let required_amt = if shielded_gas { amount + fee } else { amount }; + // Locate unspent notes that can help us meet the transaction amount + let (_, unspent_notes, used_convs) = self + .collect_unspent_notes( + client, + &to_viewing_key(&sk).vk, + required_amt, + epoch, + ) + .await; + // Commit the notes found to our transaction + for (diversifier, note, merkle_path) in unspent_notes { + builder.add_sapling_spend( + sk, + diversifier, + note, + merkle_path, + )?; + } + // Commit the conversion notes used during summation + for (conv, wit, value) in used_convs.values() { + if *value > 0 { + builder.add_convert( + conv.clone(), + *value as u64, + wit.clone(), + )?; + } + } + } else { + // No transfer fees come from the shielded transaction for non-MASP + // sources + builder.set_fee(Amount::zero())?; + // We add a dummy UTXO to our transaction, but only the source of + // the parent Transfer object is used to validate fund + // availability + let secp_sk = secp256k1::SecretKey::from_slice(&[0xcd; 32]) + .expect("secret key"); + let secp_ctx = + secp256k1::Secp256k1::::gen_new(); + let secp_pk = + secp256k1::PublicKey::from_secret_key(&secp_ctx, &secp_sk) + .serialize(); + let hash = ripemd160::Ripemd160::digest( + sha2::Sha256::digest(&secp_pk).as_slice(), + ); + let script = TransparentAddress::PublicKey(hash.into()).script(); + epoch_sensitive = true; + builder.add_transparent_input( + secp_sk, + OutPoint::new([0u8; 32], 0), + TxOut { + asset_type, + value: amt, + script_pubkey: script, + }, + )?; + } + // Now handle the outputs of this transaction + // If there is a shielded output + if let Some(pa) = payment_address { + let ovk_opt = spending_key.map(|x| x.expsk.ovk); + builder.add_sapling_output( + ovk_opt, + pa.into(), + asset_type, + amt, + memo.clone(), + )?; + } else { + epoch_sensitive = false; + // Embed the transparent target address into the shielded + // transaction so that it can be signed + let target_enc = args + .target + .address() + .expect("target address should be transparent") + .try_to_vec() + .expect("target address encoding"); + let hash = ripemd160::Ripemd160::digest( + sha2::Sha256::digest(target_enc.as_ref()).as_slice(), + ); + builder.add_transparent_output( + &TransparentAddress::PublicKey(hash.into()), + asset_type, + amt, + )?; + } + let prover = self.utils.local_tx_prover(); + // Build and return the constructed transaction + let mut tx = builder.build(consensus_branch_id, &prover); + + if epoch_sensitive { + let new_epoch = rpc::query_epoch(client).await; + + // If epoch has changed, recalculate shielded outputs to match new + // epoch + if new_epoch != epoch { + // Hack: build new shielded transfer with updated outputs + let mut replay_builder = + Builder::::new(0u32); + replay_builder.set_fee(Amount::zero())?; + let ovk_opt = spending_key.map(|x| x.expsk.ovk); + let (new_asset_type, _) = + convert_amount(new_epoch, &args.token, args.amount); + replay_builder.add_sapling_output( + ovk_opt, + payment_address.unwrap().into(), + new_asset_type, + amt, + memo, + )?; + + let secp_sk = secp256k1::SecretKey::from_slice(&[0xcd; 32]) + .expect("secret key"); + let secp_ctx = + secp256k1::Secp256k1::::gen_new(); + let secp_pk = + secp256k1::PublicKey::from_secret_key(&secp_ctx, &secp_sk) + .serialize(); + let hash = ripemd160::Ripemd160::digest( + sha2::Sha256::digest(&secp_pk).as_slice(), + ); + let script = + TransparentAddress::PublicKey(hash.into()).script(); + replay_builder.add_transparent_input( + secp_sk, + OutPoint::new([0u8; 32], 0), + TxOut { + asset_type: new_asset_type, + value: amt, + script_pubkey: script, + }, + )?; + + let (replay_tx, _) = + replay_builder.build(consensus_branch_id, &prover)?; + tx = tx.map(|(t, tm)| { + let mut temp = t.deref().clone(); + temp.shielded_outputs = replay_tx.shielded_outputs.clone(); + temp.value_balance = temp.value_balance.reject(asset_type) + - Amount::from_pair(new_asset_type, amt).unwrap(); + (temp.freeze().unwrap(), tm) + }); + } + } + + tx.map(Some) + } + + /// Obtain the known effects of all accepted shielded and transparent + /// transactions. If an owner is specified, then restrict the set to only + /// transactions crediting/debiting the given owner. If token is specified, + /// then restrict set to only transactions involving the given token. + pub async fn query_tx_deltas( + &mut self, + client: &U::C, + query_owner: &Either>, + query_token: &Option
, + viewing_keys: &HashMap, + ) -> BTreeMap< + (BlockHeight, TxIndex), + (Epoch, TransferDelta, TransactionDelta), + > { + const TXS_PER_PAGE: u8 = 100; + let _ = self.load(); + let vks = viewing_keys; + let fvks: Vec<_> = vks + .values() + .map(|fvk| ExtendedFullViewingKey::from(*fvk).fvk.vk) + .collect(); + self.fetch(client, &[], &fvks).await; + // Save the update state so that future fetches can be short-circuited + let _ = self.save(); + // Required for filtering out rejected transactions from Tendermint + // responses + let block_results = rpc::query_results(client).await; + let mut transfers = self.get_tx_deltas().clone(); + // Construct the set of addresses relevant to user's query + let relevant_addrs = match &query_owner { + Either::Left(BalanceOwner::Address(owner)) => vec![owner.clone()], + // MASP objects are dealt with outside of tx_search + Either::Left(BalanceOwner::FullViewingKey(_viewing_key)) => vec![], + Either::Left(BalanceOwner::PaymentAddress(_owner)) => vec![], + // Unspecified owner means all known addresses are considered + // relevant + Either::Right(addrs) => addrs.clone(), + }; + // Find all transactions to or from the relevant address set + for addr in relevant_addrs { + for prop in ["transfer.source", "transfer.target"] { + // Query transactions involving the current address + let mut tx_query = Query::eq(prop, addr.encode()); + // Elaborate the query if requested by the user + if let Some(token) = &query_token { + tx_query = + tx_query.and_eq("transfer.token", token.encode()); + } + for page in 1.. { + let txs = &client + .tx_search( + tx_query.clone(), + true, + page, + TXS_PER_PAGE, + Order::Ascending, + ) + .await + .expect("Unable to query for transactions") + .txs; + for response_tx in txs { + let height = BlockHeight(response_tx.height.value()); + let idx = TxIndex(response_tx.index); + // Only process yet unprocessed transactions which have + // been accepted by node VPs + let should_process = !transfers + .contains_key(&(height, idx)) + && block_results[u64::from(height) as usize] + .is_accepted(idx.0 as usize); + if !should_process { + continue; + } + let tx = Tx::try_from(response_tx.tx.as_ref()) + .expect("Ill-formed Tx"); + let mut wrapper = None; + let mut transfer = None; + extract_payload(tx, &mut wrapper, &mut transfer); + // Epoch data is not needed for transparent transactions + let epoch = + wrapper.map(|x| x.epoch).unwrap_or_default(); + if let Some(transfer) = transfer { + // Skip MASP addresses as they are already handled + // by ShieldedContext + if transfer.source == masp() + || transfer.target == masp() + { + continue; + } + // Describe how a Transfer simply subtracts from one + // account and adds the same to another + let mut delta = TransferDelta::default(); + let tfer_delta = Amount::from_nonnegative( + transfer.token.clone(), + u64::from(transfer.amount), + ) + .expect("invalid value for amount"); + delta.insert( + transfer.source, + Amount::zero() - &tfer_delta, + ); + delta.insert(transfer.target, tfer_delta); + // No shielded accounts are affected by this + // Transfer + transfers.insert( + (height, idx), + (epoch, delta, TransactionDelta::new()), + ); + } + } + // An incomplete page signifies no more transactions + if (txs.len() as u8) < TXS_PER_PAGE { + break; + } + } + } + } + transfers + } +} + +/// Extract the payload from the given Tx object +fn extract_payload( + tx: Tx, + wrapper: &mut Option, + transfer: &mut Option, +) { + match process_tx(tx) { + Ok(TxType::Wrapper(wrapper_tx)) => { + let privkey = ::G2Affine::prime_subgroup_generator(); + extract_payload( + Tx::from(match wrapper_tx.decrypt(privkey) { + Ok(tx) => DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: false, + }, + _ => DecryptedTx::Undecryptable(wrapper_tx.clone()), + }), + wrapper, + transfer, + ); + *wrapper = Some(wrapper_tx); + } + Ok(TxType::Decrypted(DecryptedTx::Decrypted { + tx, + #[cfg(not(feature = "mainnet"))] + has_valid_pow: _, + })) => { + let empty_vec = vec![]; + let tx_data = tx.data.as_ref().unwrap_or(&empty_vec); + let _ = SignedTxData::try_from_slice(tx_data).map(|signed| { + Transfer::try_from_slice(&signed.data.unwrap()[..]) + .map(|tfer| *transfer = Some(tfer)) + }); + } + _ => {} + } +} + +/// Make asset type corresponding to given address and epoch +fn make_asset_type(epoch: Epoch, token: &Address) -> AssetType { + // Typestamp the chosen token with the current epoch + let token_bytes = (token, epoch.0) + .try_to_vec() + .expect("token should serialize"); + // Generate the unique asset identifier from the unique token address + AssetType::new(token_bytes.as_ref()).expect("unable to create asset type") +} + +/// Convert Anoma amount and token type to MASP equivalents +fn convert_amount( + epoch: Epoch, + token: &Address, + val: token::Amount, +) -> (AssetType, Amount) { + let asset_type = make_asset_type(epoch, token); + // Combine the value and unit into one amount + let amount = Amount::from_nonnegative(asset_type, u64::from(val)) + .expect("invalid value for amount"); + (asset_type, amount) +} diff --git a/shared/src/ledger/mod.rs b/shared/src/ledger/mod.rs index 0986878b54..f933df26b3 100644 --- a/shared/src/ledger/mod.rs +++ b/shared/src/ledger/mod.rs @@ -1,5 +1,6 @@ //! The ledger modules +pub mod args; pub mod eth_bridge; pub mod events; pub mod ibc; @@ -10,8 +11,12 @@ pub mod pos; #[cfg(all(feature = "wasm-runtime", feature = "ferveo-tpke"))] pub mod protocol; pub mod queries; +pub mod rpc; +pub mod signing; pub mod storage; +pub mod tx; pub mod vp_host_fns; +pub mod wallet; pub use namada_core::ledger::{ gas, governance, parameters, replay_protection, storage_api, tx_env, vp_env, diff --git a/shared/src/ledger/native_vp/mod.rs b/shared/src/ledger/native_vp/mod.rs index bfd14e7c1b..f1fbf9944a 100644 --- a/shared/src/ledger/native_vp/mod.rs +++ b/shared/src/ledger/native_vp/mod.rs @@ -524,7 +524,7 @@ where #[cfg(not(feature = "wasm-runtime"))] { // This line is here to prevent unused var clippy warning - let _ = (vp_code, input_data); + let _ = (vp_code_hash, input_data); unimplemented!( "The \"wasm-runtime\" feature must be enabled to use the \ `eval` function." diff --git a/shared/src/ledger/queries/mod.rs b/shared/src/ledger/queries/mod.rs index 565100b81b..bec728188c 100644 --- a/shared/src/ledger/queries/mod.rs +++ b/shared/src/ledger/queries/mod.rs @@ -15,6 +15,7 @@ pub use vp::{Pos, Vp}; use super::storage::{DBIter, StorageHasher, DB}; use super::storage_api; +use crate::tendermint_rpc::error::Error as RpcError; use crate::types::storage::BlockHeight; #[macro_use] @@ -91,71 +92,11 @@ pub fn require_no_data(request: &RequestQuery) -> storage_api::Result<()> { Ok(()) } -#[cfg(any(feature = "tendermint-rpc", feature = "tendermint-rpc-abcipp",))] -/// Provides [`Client`] implementation for Tendermint RPC client -pub mod tm { - use thiserror::Error; - - use super::*; - use crate::types::storage::BlockHeight; - - #[allow(missing_docs)] - #[derive(Error, Debug)] - pub enum Error { - #[error("{0}")] - Tendermint(#[from] crate::tendermint_rpc::Error), - #[error("Decoding error: {0}")] - Decoding(#[from] std::io::Error), - #[error("Info log: {0}, error code: {1}")] - Query(String, u32), - #[error("Invalid block height: {0} (overflown i64)")] - InvalidHeight(BlockHeight), - } - - #[async_trait::async_trait(?Send)] - impl Client for crate::tendermint_rpc::HttpClient { - type Error = Error; - - async fn request( - &self, - path: String, - data: Option>, - height: Option, - prove: bool, - ) -> Result { - let data = data.unwrap_or_default(); - let height = height - .map(|height| { - crate::tendermint::block::Height::try_from(height.0) - .map_err(|_err| Error::InvalidHeight(height)) - }) - .transpose()?; - let response = crate::tendermint_rpc::Client::abci_query( - self, - // TODO open the private Path constructor in tendermint-rpc - Some(std::str::FromStr::from_str(&path).unwrap()), - data, - height, - prove, - ) - .await?; - use crate::tendermint::abci::Code; - match response.code { - Code::Ok => Ok(EncodedResponseQuery { - data: response.value, - info: response.info, - proof: response.proof, - }), - Code::Err(code) => Err(Error::Query(response.info, code)), - } - } - } -} - /// Queries testing helpers #[cfg(any(test, feature = "testing"))] mod testing { use tempfile::TempDir; + use tendermint_rpc::Response; use super::*; use crate::ledger::events::log::EventLog; @@ -245,5 +186,12 @@ mod testing { let response = self.rpc.handle(ctx, &request).unwrap(); Ok(response) } + + async fn perform(&self, _request: R) -> Result + where + R: tendermint_rpc::SimpleRequest, + { + Response::from_string("TODO") + } } } diff --git a/shared/src/ledger/queries/shell.rs b/shared/src/ledger/queries/shell.rs index 14bc0a8806..37e6fe38bb 100644 --- a/shared/src/ledger/queries/shell.rs +++ b/shared/src/ledger/queries/shell.rs @@ -4,7 +4,7 @@ use masp_primitives::merkle_tree::MerklePath; use masp_primitives::sapling::Node; use namada_core::types::address::Address; use namada_core::types::hash::Hash; -use namada_core::types::storage::BlockResults; +use namada_core::types::storage::{BlockResults, KeySeg}; use crate::ledger::events::log::dumb_queries; use crate::ledger::events::Event; @@ -117,12 +117,13 @@ where ctx.wl_storage.storage.block.height.0 as usize + 1 ]; iter.for_each(|(key, value, _gas)| { - let key = key - .parse::() - .expect("expected integer for block height"); + let key = u64::parse(key).expect("expected integer for block height"); let value = BlockResults::try_from_slice(&value) .expect("expected BlockResults bytes"); - results[key] = value; + let idx: usize = key + .try_into() + .expect("expected block height to fit into usize"); + results[idx] = value; }); Ok(results) } diff --git a/shared/src/ledger/queries/types.rs b/shared/src/ledger/queries/types.rs index fd65edcfd9..04e26d1ce3 100644 --- a/shared/src/ledger/queries/types.rs +++ b/shared/src/ledger/queries/types.rs @@ -1,15 +1,23 @@ use namada_core::ledger::storage::WlStorage; +use tendermint::block::Height; +use tendermint_rpc::endpoint::{ + abci_info, block, block_results, blockchain, commit, consensus_params, + consensus_state, health, net_info, status, +}; +use tendermint_rpc::query::Query; +use tendermint_rpc::Order; +use thiserror::Error; use crate::ledger::events::log::EventLog; use crate::ledger::storage::{DBIter, StorageHasher, DB}; use crate::ledger::storage_api; use crate::tendermint::merkle::proof::Proof; +use crate::tendermint_rpc::error::Error as RpcError; use crate::types::storage::BlockHeight; #[cfg(feature = "wasm-runtime")] use crate::vm::wasm::{TxCache, VpCache}; #[cfg(feature = "wasm-runtime")] use crate::vm::WasmCacheRoAccess; - /// A request context provides read-only access to storage and WASM compilation /// caches to request handlers. #[derive(Debug, Clone)] @@ -96,6 +104,250 @@ pub trait Client { height: Option, prove: bool, ) -> Result; + + /// `/abci_info`: get information about the ABCI application. + async fn abci_info(&self) -> Result { + Ok(self.perform(abci_info::Request).await?.response) + } + + /// `/broadcast_tx_sync`: broadcast a transaction, returning the response + /// from `CheckTx`. + async fn broadcast_tx_sync( + &self, + tx: tendermint::abci::Transaction, + ) -> Result + { + self.perform( + tendermint_rpc::endpoint::broadcast::tx_sync::Request::new(tx), + ) + .await + } + + /// `/block`: get the latest block. + async fn latest_block(&self) -> Result { + self.perform(block::Request::default()).await + } + + /// `/block`: get block at a given height. + async fn block(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(block::Request::new(height.into())).await + } + + /// `/block_search`: search for blocks by BeginBlock and EndBlock events. + async fn block_search( + &self, + query: Query, + page: u32, + per_page: u8, + order: Order, + ) -> Result + { + self.perform(tendermint_rpc::endpoint::block_search::Request::new( + query, page, per_page, order, + )) + .await + } + + /// `/block_results`: get ABCI results for a block at a particular height. + async fn block_results( + &self, + height: H, + ) -> Result + where + H: Into + Send, + { + self.perform(tendermint_rpc::endpoint::block_results::Request::new( + height.into(), + )) + .await + } + + /// `/tx_search`: search for transactions with their results. + async fn tx_search( + &self, + query: Query, + prove: bool, + page: u32, + per_page: u8, + order: Order, + ) -> Result { + self.perform(tendermint_rpc::endpoint::tx_search::Request::new( + query, prove, page, per_page, order, + )) + .await + } + + /// `/abci_query`: query the ABCI application + async fn abci_query( + &self, + path: Option, + data: V, + height: Option, + prove: bool, + ) -> Result + where + V: Into> + Send, + { + Ok(self + .perform(tendermint_rpc::endpoint::abci_query::Request::new( + path, data, height, prove, + )) + .await? + .response) + } + + /// `/block_results`: get ABCI results for the latest block. + async fn latest_block_results( + &self, + ) -> Result { + self.perform(block_results::Request::default()).await + } + + /// `/blockchain`: get block headers for `min` <= `height` <= `max`. + /// + /// Block headers are returned in descending order (highest first). + /// + /// Returns at most 20 items. + async fn blockchain( + &self, + min: H, + max: H, + ) -> Result + where + H: Into + Send, + { + // TODO(tarcieri): return errors for invalid params before making + // request? + self.perform(blockchain::Request::new(min.into(), max.into())) + .await + } + + /// `/commit`: get block commit at a given height. + async fn commit(&self, height: H) -> Result + where + H: Into + Send, + { + self.perform(commit::Request::new(height.into())).await + } + + /// `/consensus_params`: get current consensus parameters at the specified + /// height. + async fn consensus_params( + &self, + height: H, + ) -> Result + where + H: Into + Send, + { + self.perform(consensus_params::Request::new(Some(height.into()))) + .await + } + + /// `/consensus_state`: get current consensus state + async fn consensus_state( + &self, + ) -> Result { + self.perform(consensus_state::Request::new()).await + } + + /// `/consensus_params`: get the latest consensus parameters. + async fn latest_consensus_params( + &self, + ) -> Result { + self.perform(consensus_params::Request::new(None)).await + } + + /// `/commit`: get the latest block commit + async fn latest_commit(&self) -> Result { + self.perform(commit::Request::default()).await + } + + /// `/health`: get node health. + /// + /// Returns empty result (200 OK) on success, no response in case of an + /// error. + async fn health(&self) -> Result<(), Error> { + self.perform(health::Request).await?; + Ok(()) + } + + /// `/net_info`: obtain information about P2P and other network connections. + async fn net_info(&self) -> Result { + self.perform(net_info::Request).await + } + + /// `/status`: get Tendermint status including node info, pubkey, latest + /// block hash, app hash, block height and time. + async fn status(&self) -> Result { + self.perform(status::Request).await + } + + /// Perform a request against the RPC endpoint + async fn perform(&self, request: R) -> Result + where + R: tendermint_rpc::SimpleRequest; +} + +#[allow(missing_docs)] +#[derive(Error, Debug)] +pub enum Error { + #[error("{0}")] + Tendermint(#[from] tendermint_rpc::Error), + #[error("Decoding error: {0}")] + Decoding(#[from] std::io::Error), + #[error("Info log: {0}, error code: {1}")] + Query(String, u32), + #[error("Invalid block height: {0} (overflown i64)")] + InvalidHeight(BlockHeight), +} + +#[async_trait::async_trait(?Send)] +impl Client for C { + type Error = Error; + + async fn request( + &self, + path: String, + data: Option>, + height: Option, + prove: bool, + ) -> Result { + let data = data.unwrap_or_default(); + let height = height + .map(|height| { + tendermint::block::Height::try_from(height.0) + .map_err(|_err| Error::InvalidHeight(height)) + }) + .transpose()?; + let response = self + .abci_query( + // TODO open the private Path constructor in tendermint-rpc + Some(std::str::FromStr::from_str(&path).unwrap()), + data, + height, + prove, + ) + .await?; + use tendermint::abci::Code; + match response.code { + Code::Ok => Ok(EncodedResponseQuery { + data: response.value, + info: response.info, + proof: response.proof, + }), + Code::Err(code) => Err(Error::Query(response.info, code)), + } + } + + async fn perform(&self, request: R) -> Result + where + R: tendermint_rpc::SimpleRequest, + { + tendermint_rpc::Client::perform(self, request).await + } } /// Temporary domain-type for `tendermint_proto::abci::RequestQuery`, copied diff --git a/shared/src/ledger/rpc.rs b/shared/src/ledger/rpc.rs new file mode 100644 index 0000000000..ddae02dd74 --- /dev/null +++ b/shared/src/ledger/rpc.rs @@ -0,0 +1,888 @@ +//! SDK RPC queries +use std::collections::{HashMap, HashSet}; + +use borsh::BorshDeserialize; +use masp_primitives::asset_type::AssetType; +use masp_primitives::merkle_tree::MerklePath; +use masp_primitives::sapling::Node; +use namada_core::ledger::testnet_pow; +use namada_core::types::address::Address; +use namada_core::types::storage::Key; +use namada_core::types::token::Amount; +use namada_proof_of_stake::types::CommissionPair; +use serde::Serialize; +use tokio::time::Duration; + +use crate::ledger::events::Event; +use crate::ledger::governance::parameters::GovParams; +use crate::ledger::governance::storage as gov_storage; +use crate::ledger::native_vp::governance::utils::Votes; +use crate::ledger::queries::RPC; +use crate::proto::Tx; +use crate::tendermint::merkle::proof::Proof; +use crate::tendermint_rpc::error::Error as TError; +use crate::tendermint_rpc::query::Query; +use crate::tendermint_rpc::Order; +use crate::types::governance::{ProposalVote, VotePower}; +use crate::types::hash::Hash; +use crate::types::key::*; +use crate::types::storage::{BlockHeight, BlockResults, Epoch, PrefixValue}; +use crate::types::token::balance_key; +use crate::types::{storage, token}; + +/// Query the status of a given transaction. +/// +/// If a response is not delivered until `deadline`, we exit the cli with an +/// error. +pub async fn query_tx_status( + client: &C, + status: TxEventQuery<'_>, + deadline: Duration, +) -> Event { + const ONE_SECOND: Duration = Duration::from_secs(1); + // sleep for the duration of `backoff`, + // and update the underlying value + async fn sleep_update(query: TxEventQuery<'_>, backoff: &mut Duration) { + tracing::debug!( + ?query, + duration = ?backoff, + "Retrying tx status query after timeout", + ); + // simple linear backoff - if an event is not available, + // increase the backoff duration by one second + async_std::task::sleep(*backoff).await; + *backoff += ONE_SECOND; + } + + let mut backoff = ONE_SECOND; + loop { + tracing::debug!(query = ?status, "Querying tx status"); + let maybe_event = match query_tx_events(client, status).await { + Ok(response) => response, + Err(_err) => { + // tracing::debug!(%err, "ABCI query failed"); + sleep_update(status, &mut backoff).await; + continue; + } + }; + if let Some(e) = maybe_event { + break e; + } else if deadline < backoff { + panic!( + "Transaction status query deadline of {deadline:?} exceeded" + ); + } else { + sleep_update(status, &mut backoff).await; + } + } +} + +/// Query the epoch of the last committed block +pub async fn query_epoch( + client: &C, +) -> Epoch { + let epoch = unwrap_client_response::(RPC.shell().epoch(client).await); + println!("Last committed epoch: {}", epoch); + epoch +} + +/// Query the last committed block +pub async fn query_block( + client: &C, +) -> crate::tendermint_rpc::endpoint::block::Response { + let response = client.latest_block().await.unwrap(); + println!( + "Last committed block ID: {}, height: {}, time: {}", + response.block_id, + response.block.header.height, + response.block.header.time + ); + response +} + +/// A helper to unwrap client's response. Will shut down process on error. +fn unwrap_client_response( + response: Result, +) -> T { + response.unwrap_or_else(|_err| { + panic!("Error in the query"); + }) +} + +/// Query the results of the last committed block +pub async fn query_results( + client: &C, +) -> Vec { + unwrap_client_response::(RPC.shell().read_results(client).await) +} + +/// Query token amount of owner. +pub async fn get_token_balance( + client: &C, + token: &Address, + owner: &Address, +) -> Option { + let balance_key = balance_key(token, owner); + query_storage_value(client, &balance_key).await +} + +/// Get account's public key stored in its storage sub-space +pub async fn get_public_key( + client: &C, + address: &Address, +) -> Option { + let key = pk_key(address); + query_storage_value(client, &key).await +} + +/// Check if the given address is a known validator. +pub async fn is_validator( + client: &C, + address: &Address, +) -> bool { + unwrap_client_response::( + RPC.vp().pos().is_validator(client, address).await, + ) +} + +/// Check if a given address is a known delegator +pub async fn is_delegator( + client: &C, + address: &Address, +) -> bool { + unwrap_client_response::( + RPC.vp().pos().is_delegator(client, address, &None).await, + ) +} + +/// Check if a given address is a known delegator at the given epoch +pub async fn is_delegator_at( + client: &C, + address: &Address, + epoch: Epoch, +) -> bool { + unwrap_client_response::( + RPC.vp() + .pos() + .is_delegator(client, address, &Some(epoch)) + .await, + ) +} + +/// Check if the address exists on chain. Established address exists if it has a +/// stored validity predicate. Implicit and internal addresses always return +/// true. +pub async fn known_address( + client: &C, + address: &Address, +) -> bool { + match address { + Address::Established(_) => { + // Established account exists if it has a VP + let key = storage::Key::validity_predicate(address); + query_has_storage_key(client, &key).await + } + Address::Implicit(_) | Address::Internal(_) => true, + } +} + +#[cfg(not(feature = "mainnet"))] +/// Check if the given address is a testnet faucet account address. +pub async fn is_faucet_account( + client: &C, + address: &Address, +) -> bool { + unwrap_client_response::(RPC.vp().is_faucet(client, address).await) +} + +#[cfg(not(feature = "mainnet"))] +/// Get faucet account address, if any is setup for the network. +pub async fn get_faucet_address( + client: &C, +) -> Option
{ + unwrap_client_response::>( + RPC.vp().get_faucet_address(client).await, + ) +} + +#[cfg(not(feature = "mainnet"))] +/// Obtain a PoW challenge for a withdrawal from a testnet faucet account, if +/// any is setup for the network. +pub async fn get_testnet_pow_challenge< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + source: Address, +) -> testnet_pow::Challenge { + unwrap_client_response::( + RPC.vp().testnet_pow_challenge(client, source).await, + ) +} + +/// Query a conversion. +pub async fn query_conversion( + client: &C, + asset_type: AssetType, +) -> Option<( + Address, + Epoch, + masp_primitives::transaction::components::Amount, + MerklePath, +)> { + Some(unwrap_client_response::( + RPC.shell().read_conversion(client, &asset_type).await, + )) +} + +/// Query a wasm code hash +pub async fn query_wasm_code_hash( + client: &C, + code_path: impl AsRef, +) -> Option { + let hash_key = Key::wasm_hash(code_path.as_ref()); + match query_storage_value_bytes(client, &hash_key, None, false) + .await + .0 + { + Some(hash) => { + Some(Hash::try_from(&hash[..]).expect("Invalid code hash")) + } + None => { + eprintln!( + "The corresponding wasm code of the code path {} doesn't \ + exist on chain.", + code_path.as_ref(), + ); + None + } + } +} + +/// Query a storage value and decode it with [`BorshDeserialize`]. +pub async fn query_storage_value( + client: &C, + key: &storage::Key, +) -> Option +where + T: BorshDeserialize, + C: crate::ledger::queries::Client + Sync, +{ + // In case `T` is a unit (only thing that encodes to 0 bytes), we have to + // use `storage_has_key` instead of `storage_value`, because `storage_value` + // returns 0 bytes when the key is not found. + let maybe_unit = T::try_from_slice(&[]); + if let Ok(unit) = maybe_unit { + return if unwrap_client_response::( + RPC.shell().storage_has_key(client, key).await, + ) { + Some(unit) + } else { + None + }; + } + + let response = unwrap_client_response::( + RPC.shell() + .storage_value(client, None, None, false, key) + .await, + ); + if response.data.is_empty() { + return None; + } + T::try_from_slice(&response.data[..]) + .map(Some) + .unwrap_or_else(|err| { + panic!("Error decoding the value: {}", err); + }) +} + +/// Query a storage value and the proof without decoding. +pub async fn query_storage_value_bytes< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + key: &storage::Key, + height: Option, + prove: bool, +) -> (Option>, Option) { + let data = None; + let response = unwrap_client_response::( + RPC.shell() + .storage_value(client, data, height, prove, key) + .await, + ); + if response.data.is_empty() { + (None, response.proof) + } else { + (Some(response.data), response.proof) + } +} + +/// Query a range of storage values with a matching prefix and decode them with +/// [`BorshDeserialize`]. Returns an iterator of the storage keys paired with +/// their associated values. +pub async fn query_storage_prefix( + client: &C, + key: &storage::Key, +) -> Option> +where + T: BorshDeserialize, +{ + let values = unwrap_client_response::( + RPC.shell() + .storage_prefix(client, None, None, false, key) + .await, + ); + let decode = + |PrefixValue { key, value }: PrefixValue| match T::try_from_slice( + &value[..], + ) { + Err(err) => { + eprintln!( + "Skipping a value for key {}. Error in decoding: {}", + key, err + ); + None + } + Ok(value) => Some((key, value)), + }; + if values.data.is_empty() { + None + } else { + Some(values.data.into_iter().filter_map(decode)) + } +} + +/// Query to check if the given storage key exists. +pub async fn query_has_storage_key( + client: &C, + key: &storage::Key, +) -> bool { + unwrap_client_response::( + RPC.shell().storage_has_key(client, key).await, + ) +} + +/// Represents a query for an event pertaining to the specified transaction +#[derive(Debug, Copy, Clone)] +pub enum TxEventQuery<'a> { + /// Queries whether transaction with given hash was accepted + Accepted(&'a str), + /// Queries whether transaction with given hash was applied + Applied(&'a str), +} + +impl<'a> TxEventQuery<'a> { + /// The event type to which this event query pertains + pub fn event_type(self) -> &'static str { + match self { + TxEventQuery::Accepted(_) => "accepted", + TxEventQuery::Applied(_) => "applied", + } + } + + /// The transaction to which this event query pertains + pub fn tx_hash(self) -> &'a str { + match self { + TxEventQuery::Accepted(tx_hash) => tx_hash, + TxEventQuery::Applied(tx_hash) => tx_hash, + } + } +} + +/// Transaction event queries are semantically a subset of general queries +impl<'a> From> for Query { + fn from(tx_query: TxEventQuery<'a>) -> Self { + match tx_query { + TxEventQuery::Accepted(tx_hash) => { + Query::default().and_eq("accepted.hash", tx_hash) + } + TxEventQuery::Applied(tx_hash) => { + Query::default().and_eq("applied.hash", tx_hash) + } + } + } +} + +/// Call the corresponding `tx_event_query` RPC method, to fetch +/// the current status of a transation. +pub async fn query_tx_events( + client: &C, + tx_event_query: TxEventQuery<'_>, +) -> std::result::Result< + Option, + ::Error, +> { + let tx_hash: Hash = tx_event_query.tx_hash().try_into().unwrap(); + match tx_event_query { + TxEventQuery::Accepted(_) => { + RPC.shell().accepted(client, &tx_hash).await + } + /*.wrap_err_with(|| { + eyre!("Failed querying whether a transaction was accepted") + })*/, + TxEventQuery::Applied(_) => RPC.shell().applied(client, &tx_hash).await, /*.wrap_err_with(|| { + eyre!("Error querying whether a transaction was applied") + })*/ + } +} + +/// Dry run a transaction +pub async fn dry_run_tx( + client: &C, + tx_bytes: Vec, +) -> namada_core::types::transaction::TxResult { + let (data, height, prove) = (Some(tx_bytes), None, false); + let result = unwrap_client_response::( + RPC.shell().dry_run_tx(client, data, height, prove).await, + ) + .data; + println! {"Dry-run result: {}", result}; + result +} + +/// Data needed for broadcasting a tx and +/// monitoring its progress on chain +/// +/// Txs may be either a dry run or else +/// they should be encrypted and included +/// in a wrapper. +#[derive(Debug, Clone)] +pub enum TxBroadcastData { + /// Dry run broadcast data + DryRun(Tx), + /// Wrapper broadcast data + Wrapper { + /// Transaction to broadcast + tx: Tx, + /// Hash of the wrapper transaction + wrapper_hash: String, + /// Hash of decrypted transaction + decrypted_hash: String, + }, +} + +/// A parsed event from tendermint relating to a transaction +#[derive(Debug, Serialize)] +pub struct TxResponse { + /// Response information + pub info: String, + /// Response log + pub log: String, + /// Block height + pub height: String, + /// Transaction height + pub hash: String, + /// Response code + pub code: String, + /// Gas used + pub gas_used: String, + /// Initialized accounts + pub initialized_accounts: Vec
, +} + +impl TryFrom for TxResponse { + type Error = String; + + fn try_from(event: Event) -> Result { + fn missing_field_err(field: &str) -> String { + format!("Field \"{field}\" not present in event") + } + + let hash = event + .get("hash") + .ok_or_else(|| missing_field_err("hash"))? + .clone(); + let info = event + .get("info") + .ok_or_else(|| missing_field_err("info"))? + .clone(); + let log = event + .get("log") + .ok_or_else(|| missing_field_err("log"))? + .clone(); + let height = event + .get("height") + .ok_or_else(|| missing_field_err("height"))? + .clone(); + let code = event + .get("code") + .ok_or_else(|| missing_field_err("code"))? + .clone(); + let gas_used = event + .get("gas_used") + .ok_or_else(|| missing_field_err("gas_used"))? + .clone(); + let initialized_accounts = event + .get("initialized_accounts") + .map(String::as_str) + // TODO: fix finalize block, to return initialized accounts, + // even when we reject a tx? + .map_or(Ok(vec![]), |initialized_accounts| { + serde_json::from_str(initialized_accounts) + .map_err(|err| format!("JSON decode error: {err}")) + })?; + + Ok(TxResponse { + hash, + info, + log, + height, + code, + gas_used, + initialized_accounts, + }) + } +} + +impl TxResponse { + /// Convert an [`Event`] to a [`TxResponse`], or error out. + pub fn from_event(event: Event) -> Self { + event.try_into().unwrap_or_else(|err| { + panic!("Error fetching TxResponse: {err}"); + }) + } +} + +/// Lookup the full response accompanying the specified transaction event +// TODO: maybe remove this in favor of `query_tx_status` +pub async fn query_tx_response( + client: &C, + tx_query: TxEventQuery<'_>, +) -> Result { + // Find all blocks that apply a transaction with the specified hash + let blocks = &client + .block_search(tx_query.into(), 1, 255, Order::Ascending) + .await + .expect("Unable to query for transaction with given hash") + .blocks; + // Get the block results corresponding to a block to which + // the specified transaction belongs + let block = &blocks + .get(0) + .ok_or_else(|| { + TError::server( + "Unable to find a block applying the given transaction" + .to_string(), + ) + })? + .block; + let response_block_results = client + .block_results(block.header.height) + .await + .expect("Unable to retrieve block containing transaction"); + // Search for the event where the specified transaction is + // applied to the blockchain + let query_event_opt = + response_block_results.end_block_events.and_then(|events| { + events + .iter() + .find(|event| { + event.type_str == tx_query.event_type() + && event.attributes.iter().any(|tag| { + tag.key.as_ref() == "hash" + && tag.value.as_ref() == tx_query.tx_hash() + }) + }) + .cloned() + }); + let query_event = query_event_opt.ok_or_else(|| { + TError::server( + "Unable to find the event corresponding to the specified \ + transaction" + .to_string(), + ) + })?; + // Reformat the event attributes so as to ease value extraction + let event_map: std::collections::HashMap<&str, &str> = query_event + .attributes + .iter() + .map(|tag| (tag.key.as_ref(), tag.value.as_ref())) + .collect(); + // Summarize the transaction results that we were searching for + let result = TxResponse { + info: event_map["info"].to_string(), + log: event_map["log"].to_string(), + height: event_map["height"].to_string(), + hash: event_map["hash"].to_string(), + code: event_map["code"].to_string(), + gas_used: event_map["gas_used"].to_string(), + initialized_accounts: serde_json::from_str( + event_map["initialized_accounts"], + ) + .unwrap_or_default(), + }; + Ok(result) +} + +/// Get the votes for a given proposal id +pub async fn get_proposal_votes( + client: &C, + epoch: Epoch, + proposal_id: u64, +) -> Votes { + let validators = get_all_validators(client, epoch).await; + + let vote_prefix_key = + gov_storage::get_proposal_vote_prefix_key(proposal_id); + let vote_iter = + query_storage_prefix::(client, &vote_prefix_key).await; + + let mut yay_validators: HashMap = + HashMap::new(); + let mut delegators: HashMap< + Address, + HashMap, + > = HashMap::new(); + + if let Some(vote_iter) = vote_iter { + for (key, vote) in vote_iter { + let voter_address = gov_storage::get_voter_address(&key) + .expect("Vote key should contain the voting address.") + .clone(); + if vote.is_yay() && validators.contains(&voter_address) { + let amount: VotePower = + get_validator_stake(client, epoch, &voter_address) + .await + .into(); + yay_validators.insert(voter_address, (amount, vote)); + } else if !validators.contains(&voter_address) { + let validator_address = + gov_storage::get_vote_delegation_address(&key) + .expect( + "Vote key should contain the delegation address.", + ) + .clone(); + let delegator_token_amount = get_bond_amount_at( + client, + &voter_address, + &validator_address, + epoch, + ) + .await; + if let Some(amount) = delegator_token_amount { + let entry = delegators.entry(voter_address).or_default(); + entry.insert( + validator_address, + (VotePower::from(amount), vote), + ); + } + } + } + } + + Votes { + yay_validators, + delegators, + } +} + +/// Get all validators in the given epoch +pub async fn get_all_validators( + client: &C, + epoch: Epoch, +) -> HashSet
{ + unwrap_client_response::( + RPC.vp() + .pos() + .validator_addresses(client, &Some(epoch)) + .await, + ) +} + +/// Get the total staked tokens in the given epoch +pub async fn get_total_staked_tokens< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + epoch: Epoch, +) -> token::Amount { + unwrap_client_response::( + RPC.vp().pos().total_stake(client, &Some(epoch)).await, + ) +} + +/// Get the given validator's stake at the given epoch +pub async fn get_validator_stake( + client: &C, + epoch: Epoch, + validator: &Address, +) -> token::Amount { + unwrap_client_response::( + RPC.vp() + .pos() + .validator_stake(client, validator, &Some(epoch)) + .await, + ) + .unwrap_or_default() +} + +/// Get the delegator's delegation +pub async fn get_delegators_delegation< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + address: &Address, +) -> HashSet
{ + unwrap_client_response::( + RPC.vp().pos().delegation_validators(client, address).await, + ) +} + +/// Query and return validator's commission rate and max commission rate change +/// per epoch +pub async fn query_commission_rate( + client: &C, + validator: &Address, + epoch: Option, +) -> Option { + unwrap_client_response::>( + RPC.vp() + .pos() + .validator_commission(client, validator, &epoch) + .await, + ) +} + +/// Query a validator's bonds for a given epoch +pub async fn query_bond( + client: &C, + source: &Address, + validator: &Address, + epoch: Option, +) -> token::Amount { + unwrap_client_response::( + RPC.vp().pos().bond(client, source, validator, &epoch).await, + ) +} + +/// Query a validator's unbonds for a given epoch +pub async fn query_and_print_unbonds< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + source: &Address, + validator: &Address, +) { + let unbonds = query_unbond_with_slashing(client, source, validator).await; + let current_epoch = query_epoch(client).await; + + let mut total_withdrawable = token::Amount::default(); + let mut not_yet_withdrawable = HashMap::::new(); + for ((_start_epoch, withdraw_epoch), amount) in unbonds.into_iter() { + if withdraw_epoch <= current_epoch { + total_withdrawable += amount; + } else { + let withdrawable_amount = + not_yet_withdrawable.entry(withdraw_epoch).or_default(); + *withdrawable_amount += amount; + } + } + if total_withdrawable != token::Amount::default() { + println!("Total withdrawable now: {total_withdrawable}."); + } + if !not_yet_withdrawable.is_empty() { + println!("Current epoch: {current_epoch}.") + } + for (withdraw_epoch, amount) in not_yet_withdrawable { + println!( + "Amount {amount} withdrawable starting from epoch \ + {withdraw_epoch}." + ); + } +} + +/// Query withdrawable tokens in a validator account for a given epoch +pub async fn query_withdrawable_tokens< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + bond_source: &Address, + validator: &Address, + epoch: Option, +) -> token::Amount { + unwrap_client_response::( + RPC.vp() + .pos() + .withdrawable_tokens(client, bond_source, validator, &epoch) + .await, + ) +} + +/// Query all unbonds for a validator, applying slashes +pub async fn query_unbond_with_slashing< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, + source: &Address, + validator: &Address, +) -> HashMap<(Epoch, Epoch), token::Amount> { + unwrap_client_response::>( + RPC.vp() + .pos() + .unbond_with_slashing(client, source, validator) + .await, + ) +} + +/// Get the givernance parameters +pub async fn get_governance_parameters< + C: crate::ledger::queries::Client + Sync, +>( + client: &C, +) -> GovParams { + let key = gov_storage::get_max_proposal_code_size_key(); + let max_proposal_code_size = query_storage_value::(client, &key) + .await + .expect("Parameter should be definied."); + + let key = gov_storage::get_max_proposal_content_key(); + let max_proposal_content_size = query_storage_value::(client, &key) + .await + .expect("Parameter should be definied."); + + let key = gov_storage::get_min_proposal_fund_key(); + let min_proposal_fund = query_storage_value::(client, &key) + .await + .expect("Parameter should be definied."); + + let key = gov_storage::get_min_proposal_grace_epoch_key(); + let min_proposal_grace_epochs = query_storage_value::(client, &key) + .await + .expect("Parameter should be definied."); + + let key = gov_storage::get_min_proposal_period_key(); + let min_proposal_period = query_storage_value::(client, &key) + .await + .expect("Parameter should be definied."); + + let key = gov_storage::get_max_proposal_period_key(); + let max_proposal_period = query_storage_value::(client, &key) + .await + .expect("Parameter should be definied."); + + GovParams { + min_proposal_fund: u64::from(min_proposal_fund), + max_proposal_code_size, + min_proposal_period, + max_proposal_period, + max_proposal_content_size, + min_proposal_grace_epochs, + } +} + +/// Get the bond amount at the given epoch +pub async fn get_bond_amount_at( + client: &C, + delegator: &Address, + validator: &Address, + epoch: Epoch, +) -> Option { + let (_total, total_active) = unwrap_client_response::( + RPC.vp() + .pos() + .bond_with_slashing(client, delegator, validator, &Some(epoch)) + .await, + ); + Some(total_active) +} diff --git a/shared/src/ledger/signing.rs b/shared/src/ledger/signing.rs new file mode 100644 index 0000000000..e01e765613 --- /dev/null +++ b/shared/src/ledger/signing.rs @@ -0,0 +1,268 @@ +//! Functions to sign transactions +use borsh::BorshSerialize; +use namada_core::ledger::parameters::storage as parameter_storage; +use namada_core::types::address::{Address, ImplicitAddress}; +use namada_core::types::token::{self, Amount}; +use namada_core::types::transaction::MIN_FEE; + +use crate::ledger::rpc::TxBroadcastData; +use crate::ledger::tx::Error; +use crate::ledger::wallet::{Wallet, WalletUtils}; +use crate::ledger::{args, rpc}; +use crate::proto::Tx; +use crate::types::key::*; +use crate::types::storage::Epoch; +use crate::types::transaction::{hash_tx, Fee, WrapperTx}; + +/// Find the public key for the given address and try to load the keypair +/// for it from the wallet. If the keypair is encrypted but a password is not +/// supplied, then it is interactively prompted. Errors if the key cannot be +/// found or loaded. +pub async fn find_keypair< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + addr: &Address, + password: Option, +) -> Result { + match addr { + Address::Established(_) => { + println!( + "Looking-up public key of {} from the ledger...", + addr.encode() + ); + let public_key = rpc::get_public_key(client, addr).await.ok_or( + Error::Other(format!( + "No public key found for the address {}", + addr.encode() + )), + )?; + wallet.find_key_by_pk(&public_key, password).map_err(|err| { + Error::Other(format!( + "Unable to load the keypair from the wallet for public \ + key {}. Failed with: {}", + public_key, err + )) + }) + } + Address::Implicit(ImplicitAddress(pkh)) => { + wallet.find_key_by_pkh(pkh, password).map_err(|err| { + Error::Other(format!( + "Unable to load the keypair from the wallet for the \ + implicit address {}. Failed with: {}", + addr.encode(), + err + )) + }) + } + Address::Internal(_) => other_err(format!( + "Internal address {} doesn't have any signing keys.", + addr + )), + } +} + +/// Carries types that can be directly/indirectly used to sign a transaction. +#[allow(clippy::large_enum_variant)] +#[derive(Clone)] +pub enum TxSigningKey { + /// Do not sign any transaction + None, + /// Obtain the actual keypair from wallet and use that to sign + WalletKeypair(common::SecretKey), + /// Obtain the keypair corresponding to given address from wallet and sign + WalletAddress(Address), + /// Directly use the given secret key to sign transactions + SecretKey(common::SecretKey), +} + +/// Given CLI arguments and some defaults, determine the rightful transaction +/// signer. Return the given signing key or public key of the given signer if +/// possible. If no explicit signer given, use the `default`. If no `default` +/// is given, an `Error` is returned. +pub async fn tx_signer< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: &args::Tx, + default: TxSigningKey, +) -> Result { + // Override the default signing key source if possible + let default = if let Some(signing_key) = &args.signing_key { + TxSigningKey::WalletKeypair(signing_key.clone()) + } else if let Some(signer) = &args.signer { + TxSigningKey::WalletAddress(signer.clone()) + } else { + default + }; + // Now actually fetch the signing key and apply it + match default { + TxSigningKey::WalletKeypair(signing_key) => Ok(signing_key), + TxSigningKey::WalletAddress(signer) => { + let signer = signer; + let signing_key = find_keypair::( + client, + wallet, + &signer, + args.password.clone(), + ) + .await?; + // Check if the signer is implicit account that needs to reveal its + // PK first + if matches!(signer, Address::Implicit(_)) { + let pk: common::PublicKey = signing_key.ref_to(); + super::tx::reveal_pk_if_needed::( + client, wallet, &pk, args, + ) + .await?; + } + Ok(signing_key) + } + TxSigningKey::SecretKey(signing_key) => { + // Check if the signing key needs to reveal its PK first + let pk: common::PublicKey = signing_key.ref_to(); + super::tx::reveal_pk_if_needed::(client, wallet, &pk, args) + .await?; + Ok(signing_key) + } + TxSigningKey::None => other_err( + "All transactions must be signed; please either specify the key \ + or the address from which to look up the signing key." + .to_string(), + ), + } +} + +/// Sign a transaction with a given signing key or public key of a given signer. +/// If no explicit signer given, use the `default`. If no `default` is given, +/// Error. +/// +/// If this is not a dry run, the tx is put in a wrapper and returned along with +/// hashes needed for monitoring the tx on chain. +/// +/// If it is a dry run, it is not put in a wrapper, but returned as is. +pub async fn sign_tx< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + tx: Tx, + args: &args::Tx, + default: TxSigningKey, + #[cfg(not(feature = "mainnet"))] requires_pow: bool, +) -> Result { + let keypair = tx_signer::(client, wallet, args, default).await?; + let tx = tx.sign(&keypair); + + let epoch = rpc::query_epoch(client).await; + + let broadcast_data = if args.dry_run { + TxBroadcastData::DryRun(tx) + } else { + sign_wrapper( + client, + args, + epoch, + tx, + &keypair, + #[cfg(not(feature = "mainnet"))] + requires_pow, + ) + .await + }; + + Ok(broadcast_data) +} + +/// Create a wrapper tx from a normal tx. Get the hash of the +/// wrapper and its payload which is needed for monitoring its +/// progress on chain. +pub async fn sign_wrapper( + client: &C, + args: &args::Tx, + epoch: Epoch, + tx: Tx, + keypair: &common::SecretKey, + #[cfg(not(feature = "mainnet"))] requires_pow: bool, +) -> TxBroadcastData { + let fee_amount = if cfg!(feature = "mainnet") { + Amount::whole(MIN_FEE) + } else { + let wrapper_tx_fees_key = parameter_storage::get_wrapper_tx_fees_key(); + rpc::query_storage_value::( + client, + &wrapper_tx_fees_key, + ) + .await + .unwrap_or_default() + }; + let fee_token = args.fee_token.clone(); + let source = Address::from(&keypair.ref_to()); + let balance_key = token::balance_key(&fee_token, &source); + let balance = + rpc::query_storage_value::(client, &balance_key) + .await + .unwrap_or_default(); + + // todo: provide sdk clients an error if the fee balance is insufficient + + #[cfg(not(feature = "mainnet"))] + // A PoW solution can be used to allow zero-fee testnet transactions + let pow_solution: Option = { + // If the address derived from the keypair doesn't have enough balance + // to pay for the fee, allow to find a PoW solution instead. + if requires_pow || balance < fee_amount { + println!( + "The transaction requires the completion of a PoW challenge." + ); + // Obtain a PoW challenge for faucet withdrawal + let challenge = + rpc::get_testnet_pow_challenge(client, source).await; + + // Solve the solution, this blocks until a solution is found + let solution = challenge.solve(); + Some(solution) + } else { + None + } + }; + + let tx = { + WrapperTx::new( + Fee { + amount: fee_amount, + token: fee_token, + }, + keypair, + epoch, + args.gas_limit.clone(), + tx, + // TODO: Actually use the fetched encryption key + Default::default(), + #[cfg(not(feature = "mainnet"))] + pow_solution, + ) + }; + + // We use this to determine when the wrapper tx makes it on-chain + let wrapper_hash = hash_tx(&tx.try_to_vec().unwrap()).to_string(); + // We use this to determine when the decrypted inner tx makes it + // on-chain + let decrypted_hash = tx.tx_hash.to_string(); + TxBroadcastData::Wrapper { + tx: tx + .sign(keypair, args.chain_id.clone().unwrap(), args.expiration) + .expect("Wrapper tx signing keypair should be correct"), + wrapper_hash, + decrypted_hash, + } +} + +fn other_err(string: String) -> Result { + Err(Error::Other(string)) +} diff --git a/shared/src/ledger/tx.rs b/shared/src/ledger/tx.rs new file mode 100644 index 0000000000..66e0eab0b0 --- /dev/null +++ b/shared/src/ledger/tx.rs @@ -0,0 +1,1476 @@ +//! SDK functions to construct different types of transactions +use std::borrow::Cow; +use std::collections::BTreeMap; +use std::str::FromStr; + +use borsh::BorshSerialize; +use itertools::Either::*; +use masp_primitives::transaction::builder; +use namada_core::types::address::{masp, masp_tx_key, Address}; +use namada_proof_of_stake::parameters::PosParams; +use namada_proof_of_stake::types::CommissionPair; +use prost::EncodeError; +use rust_decimal::Decimal; +use thiserror::Error; +use tokio::time::Duration; + +use super::rpc::query_wasm_code_hash; +use crate::ibc::applications::transfer::msgs::transfer::MsgTransfer; +use crate::ibc::core::ics04_channel::timeout::TimeoutHeight; +use crate::ibc::signer::Signer; +use crate::ibc::timestamp::Timestamp as IbcTimestamp; +use crate::ibc::tx_msg::Msg; +use crate::ibc::Height as IbcHeight; +use crate::ibc_proto::cosmos::base::v1beta1::Coin; +use crate::ledger::args; +use crate::ledger::governance::storage as gov_storage; +use crate::ledger::masp::{ShieldedContext, ShieldedUtils}; +use crate::ledger::rpc::{self, TxBroadcastData, TxResponse}; +use crate::ledger::signing::{find_keypair, sign_tx, tx_signer, TxSigningKey}; +use crate::ledger::wallet::{Wallet, WalletUtils}; +use crate::proto::Tx; +use crate::tendermint_rpc::endpoint::broadcast::tx_sync::Response; +use crate::tendermint_rpc::error::Error as RpcError; +use crate::types::key::*; +use crate::types::masp::TransferTarget; +use crate::types::storage::{Epoch, RESERVED_ADDRESS_PREFIX}; +use crate::types::time::DateTimeUtc; +use crate::types::transaction::{pos, InitAccount, UpdateVp}; +use crate::types::{storage, token}; +use crate::vm; +use crate::vm::WasmValidationError; + +/// Default timeout in seconds for requests to the `/accepted` +/// and `/applied` ABCI query endpoints. +const DEFAULT_NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS: u64 = 60; + +/// Errors to do with transaction events. +#[derive(Error, Debug)] +pub enum Error { + /// Expect a dry running transaction + #[error( + "Expected a dry-run transaction, received a wrapper transaction \ + instead: {0:?}" + )] + ExpectDryRun(Tx), + /// Expect a wrapped encrypted running transaction + #[error("Cannot broadcast a dry-run transaction")] + ExpectWrappedRun(Tx), + /// Error during broadcasting a transaction + #[error("Encountered error while broadcasting transaction: {0}")] + TxBroadcast(RpcError), + /// Invalid comission rate set + #[error("Invalid new commission rate, received {0}")] + InvalidCommisionRate(Decimal), + /// Invalid validator address + #[error("The address {0} doesn't belong to any known validator account.")] + InvalidValidatorAddress(Address), + /// Rate of epoch change too large for current epoch + #[error( + "New rate, {0}, is too large of a change with respect to the \ + predecessor epoch in which the rate will take effect." + )] + TooLargeOfChange(Decimal), + /// Error retrieving from storage + #[error("Error retrieving from storage")] + Retrival, + /// No unbonded bonds ready to withdraw in the current epoch + #[error( + "There are no unbonded bonds ready to withdraw in the current epoch \ + {0}." + )] + NoUnbondReady(Epoch), + /// No unbonded bonds found + #[error("No unbonded bonds found")] + NoUnbondFound, + /// No bonds found + #[error("No bonds found")] + NoBondFound, + /// Lower bond amount than the unbond + #[error( + "The total bonds of the source {0} is lower than the amount to be \ + unbonded. Amount to unbond is {1} and the total bonds is {2}." + )] + LowerBondThanUnbond(Address, token::Amount, token::Amount), + /// Balance is too low + #[error( + "The balance of the source {0} of token {1} is lower than the amount \ + to be transferred. Amount to transfer is {2} and the balance is {3}." + )] + BalanceTooLow(Address, Address, token::Amount, token::Amount), + /// Token Address does not exist on chain + #[error("The token address {0} doesn't exist on chain.")] + TokenDoesNotExist(Address), + /// Source address does not exist on chain + #[error("The address {0} doesn't exist on chain.")] + LocationDoesNotExist(Address), + /// Target Address does not exist on chain + #[error("The source address {0} doesn't exist on chain.")] + SourceDoesNotExist(Address), + /// Source Address does not exist on chain + #[error("The target address {0} doesn't exist on chain.")] + TargetLocationDoesNotExist(Address), + /// No Balance found for token + #[error("No balance found for the source {0} of token {1}")] + NoBalanceForToken(Address, Address), + /// Negative balance after transfer + #[error( + "The balance of the source {0} is lower than the amount to be \ + transferred and fees. Amount to transfer is {1} {2} and fees are {3} \ + {4}." + )] + NegativeBalanceAfterTransfer( + Address, + token::Amount, + Address, + token::Amount, + Address, + ), + /// No Balance found for token + #[error("{0}")] + MaspError(builder::Error), + /// Wasm validation failed + #[error("Validity predicate code validation failed with {0}")] + WasmValidationFailure(WasmValidationError), + /// Encoding transaction failure + #[error("Encoding tx data, {0}, shouldn't fail")] + EncodeTxFailure(std::io::Error), + /// Like EncodeTxFailure but for the encode error type + #[error("Encoding tx data, {0}, shouldn't fail")] + EncodeFailure(EncodeError), + /// Encoding public key failure + #[error("Encoding a public key, {0}, shouldn't fail")] + EncodeKeyFailure(std::io::Error), + /// Updating an VP of an implicit account + #[error( + "A validity predicate of an implicit address cannot be directly \ + updated. You can use an established address for this purpose." + )] + ImplicitUpdate, + // This should be removed? or rather refactored as it communicates + // the same information as the ImplicitUpdate + /// Updating a VP of an internal implicit address + #[error( + "A validity predicate of an internal address cannot be directly \ + updated." + )] + ImplicitInternalError, + /// Unexpected Error + #[error("Unexpected behavior reading the unbonds data has occurred")] + UnboundError, + /// Epoch not in storage + #[error("Proposal end epoch is not in the storage.")] + EpochNotInStorage, + /// Other Errors that may show up when using the interface + #[error("{0}")] + Other(String), +} + +/// Submit transaction and wait for result. Returns a list of addresses +/// initialized in the transaction if any. In dry run, this is always empty. +pub async fn process_tx< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: &args::Tx, + tx: Tx, + default_signer: TxSigningKey, + #[cfg(not(feature = "mainnet"))] requires_pow: bool, +) -> Result, Error> { + let to_broadcast = sign_tx::( + client, + wallet, + tx, + args, + default_signer, + #[cfg(not(feature = "mainnet"))] + requires_pow, + ) + .await?; + // NOTE: use this to print the request JSON body: + + // let request = + // tendermint_rpc::endpoint::broadcast::tx_commit::Request::new( + // tx_bytes.clone().into(), + // ); + // use tendermint_rpc::Request; + // let request_body = request.into_json(); + // println!("HTTP request body: {}", request_body); + + if args.dry_run { + expect_dry_broadcast(to_broadcast, client, vec![]).await + } else { + // Either broadcast or submit transaction and collect result into + // sum type + let result = if args.broadcast_only { + Left(broadcast_tx(client, &to_broadcast).await) + } else { + Right(submit_tx(client, to_broadcast).await) + }; + // Return result based on executed operation, otherwise deal with + // the encountered errors uniformly + match result { + Right(Ok(result)) => Ok(result.initialized_accounts), + Left(Ok(_)) => Ok(Vec::default()), + Right(Err(err)) => Err(err), + Left(Err(err)) => Err(err), + } + } +} + +/// Submit transaction to reveal public key +pub async fn submit_reveal_pk< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::RevealPk, +) -> Result<(), Error> { + let args::RevealPk { + tx: args, + public_key, + } = args; + let public_key = public_key; + if !reveal_pk_if_needed::(client, wallet, &public_key, &args).await? { + let addr: Address = (&public_key).into(); + println!("PK for {addr} is already revealed, nothing to do."); + Ok(()) + } else { + Ok(()) + } +} + +/// Submit transaction to rveeal public key if needed +pub async fn reveal_pk_if_needed< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + public_key: &common::PublicKey, + args: &args::Tx, +) -> Result { + let addr: Address = public_key.into(); + // Check if PK revealed + if args.force || !has_revealed_pk(client, &addr).await { + // If not, submit it + submit_reveal_pk_aux::(client, wallet, public_key, args).await?; + Ok(true) + } else { + Ok(false) + } +} + +/// Check if the public key for the given address has been revealed +pub async fn has_revealed_pk( + client: &C, + addr: &Address, +) -> bool { + rpc::get_public_key(client, addr).await.is_some() +} + +/// Submit transaction to reveal the given public key +pub async fn submit_reveal_pk_aux< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + public_key: &common::PublicKey, + args: &args::Tx, +) -> Result<(), Error> { + let addr: Address = public_key.into(); + println!("Submitting a tx to reveal the public key for address {addr}..."); + let tx_data = public_key.try_to_vec().map_err(Error::EncodeKeyFailure)?; + let tx_code = args.tx_code_path.clone(); + let tx = Tx::new( + tx_code, + Some(tx_data), + args.chain_id.clone().expect("value should be there"), + args.expiration, + ); + + // submit_tx without signing the inner tx + let keypair = if let Some(signing_key) = &args.signing_key { + Ok(signing_key.clone()) + } else if let Some(signer) = args.signer.as_ref() { + let signer = signer; + find_keypair::(client, wallet, signer, args.password.clone()) + .await + } else { + find_keypair::(client, wallet, &addr, args.password.clone()).await + }?; + let epoch = rpc::query_epoch(client).await; + let to_broadcast = if args.dry_run { + TxBroadcastData::DryRun(tx) + } else { + super::signing::sign_wrapper( + client, + args, + epoch, + tx, + &keypair, + #[cfg(not(feature = "mainnet"))] + false, + ) + .await + }; + + // Logic is the same as process_tx + if args.dry_run { + expect_dry_broadcast(to_broadcast, client, ()).await + } else { + // Either broadcast or submit transaction and collect result into + // sum type + let result = if args.broadcast_only { + Left(broadcast_tx(client, &to_broadcast).await) + } else { + Right(submit_tx(client, to_broadcast).await) + }; + // Return result based on executed operation, otherwise deal with + // the encountered errors uniformly + match result { + Right(Err(err)) => Err(err), + Left(Err(err)) => Err(err), + _ => Ok(()), + } + } +} + +/// Broadcast a transaction to be included in the blockchain and checks that +/// the tx has been successfully included into the mempool of a validator +/// +/// In the case of errors in any of those stages, an error message is returned +pub async fn broadcast_tx( + rpc_cli: &C, + to_broadcast: &TxBroadcastData, +) -> Result { + let (tx, wrapper_tx_hash, decrypted_tx_hash) = match to_broadcast { + TxBroadcastData::Wrapper { + tx, + wrapper_hash, + decrypted_hash, + } => Ok((tx, wrapper_hash, decrypted_hash)), + TxBroadcastData::DryRun(tx) => Err(Error::ExpectWrappedRun(tx.clone())), + }?; + + tracing::debug!( + transaction = ?to_broadcast, + "Broadcasting transaction", + ); + + // TODO: configure an explicit timeout value? we need to hack away at + // `tendermint-rs` for this, which is currently using a hard-coded 30s + // timeout. + let response = + lift_rpc_error(rpc_cli.broadcast_tx_sync(tx.to_bytes().into()).await)?; + + if response.code == 0.into() { + println!("Transaction added to mempool: {:?}", response); + // Print the transaction identifiers to enable the extraction of + // acceptance/application results later + { + println!("Wrapper transaction hash: {:?}", wrapper_tx_hash); + println!("Inner transaction hash: {:?}", decrypted_tx_hash); + } + Ok(response) + } else { + Err(Error::TxBroadcast(RpcError::server( + serde_json::to_string(&response).unwrap(), + ))) + } +} + +/// Broadcast a transaction to be included in the blockchain. +/// +/// Checks that +/// 1. The tx has been successfully included into the mempool of a validator +/// 2. The tx with encrypted payload has been included on the blockchain +/// 3. The decrypted payload of the tx has been included on the blockchain. +/// +/// In the case of errors in any of those stages, an error message is returned +pub async fn submit_tx( + client: &C, + to_broadcast: TxBroadcastData, +) -> Result { + let (_, wrapper_hash, decrypted_hash) = match &to_broadcast { + TxBroadcastData::Wrapper { + tx, + wrapper_hash, + decrypted_hash, + } => Ok((tx, wrapper_hash, decrypted_hash)), + TxBroadcastData::DryRun(tx) => Err(Error::ExpectWrappedRun(tx.clone())), + }?; + + // Broadcast the supplied transaction + broadcast_tx(client, &to_broadcast).await?; + + let deadline = + Duration::from_secs(DEFAULT_NAMADA_EVENTS_MAX_WAIT_TIME_SECONDS); + + tracing::debug!( + transaction = ?to_broadcast, + ?deadline, + "Awaiting transaction approval", + ); + + let parsed = { + let wrapper_query = + crate::ledger::rpc::TxEventQuery::Accepted(wrapper_hash.as_str()); + let event = rpc::query_tx_status(client, wrapper_query, deadline).await; + let parsed = TxResponse::from_event(event); + + println!( + "Transaction accepted with result: {}", + serde_json::to_string_pretty(&parsed).unwrap() + ); + // The transaction is now on chain. We wait for it to be decrypted + // and applied + if parsed.code == 0.to_string() { + // We also listen to the event emitted when the encrypted + // payload makes its way onto the blockchain + let decrypted_query = + rpc::TxEventQuery::Applied(decrypted_hash.as_str()); + let event = + rpc::query_tx_status(client, decrypted_query, deadline).await; + let parsed = TxResponse::from_event(event); + println!( + "Transaction applied with result: {}", + serde_json::to_string_pretty(&parsed).unwrap() + ); + Ok(parsed) + } else { + Ok(parsed) + } + }; + + tracing::debug!( + transaction = ?to_broadcast, + "Transaction approved", + ); + + parsed +} + +/// Save accounts initialized from a tx into the wallet, if any. +pub async fn save_initialized_accounts( + wallet: &mut Wallet, + args: &args::Tx, + initialized_accounts: Vec
, +) { + let len = initialized_accounts.len(); + if len != 0 { + // Store newly initialized account addresses in the wallet + println!( + "The transaction initialized {} new account{}", + len, + if len == 1 { "" } else { "s" } + ); + // Store newly initialized account addresses in the wallet + for (ix, address) in initialized_accounts.iter().enumerate() { + let encoded = address.encode(); + let alias: Cow = match &args.initialized_account_alias { + Some(initialized_account_alias) => { + if len == 1 { + // If there's only one account, use the + // alias as is + initialized_account_alias.into() + } else { + // If there're multiple accounts, use + // the alias as prefix, followed by + // index number + format!("{}{}", initialized_account_alias, ix).into() + } + } + None => U::read_alias(&encoded).into(), + }; + let alias = alias.into_owned(); + let added = wallet.add_address(alias.clone(), address.clone()); + match added { + Some(new_alias) if new_alias != encoded => { + println!( + "Added alias {} for address {}.", + new_alias, encoded + ); + } + _ => println!("No alias added for address {}.", encoded), + }; + } + } +} + +/// Submit validator comission rate change +pub async fn submit_validator_commission_change< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::TxCommissionRateChange, +) -> Result<(), Error> { + let epoch = rpc::query_epoch(client).await; + + let tx_code = args.tx_code_path; + + // TODO: put following two let statements in its own function + let params_key = crate::ledger::pos::params_key(); + let params = rpc::query_storage_value::(client, ¶ms_key) + .await + .expect("Parameter should be defined."); + + let validator = args.validator.clone(); + if rpc::is_validator(client, &validator).await { + if args.rate < Decimal::ZERO || args.rate > Decimal::ONE { + if args.tx.force { + eprintln!( + "Invalid new commission rate, received {}", + args.rate + ); + Ok(()) + } else { + Err(Error::InvalidCommisionRate(args.rate)) + } + } else { + Ok(()) + }?; + + let pipeline_epoch_minus_one = epoch + params.pipeline_len - 1; + + match rpc::query_commission_rate( + client, + &validator, + Some(pipeline_epoch_minus_one), + ) + .await + { + Some(CommissionPair { + commission_rate, + max_commission_change_per_epoch, + }) => { + if (args.rate - commission_rate).abs() + > max_commission_change_per_epoch + { + eprintln!( + "New rate is too large of a change with respect to \ + the predecessor epoch in which the rate will take \ + effect." + ); + if !args.tx.force { + return Err(Error::InvalidCommisionRate(args.rate)); + } + } + } + None => { + eprintln!("Error retrieving from storage"); + if !args.tx.force { + return Err(Error::Retrival); + } + } + } + } else { + eprintln!("The given address {validator} is not a validator."); + if !args.tx.force { + return Err(Error::InvalidValidatorAddress(validator)); + } + } + + let data = pos::CommissionChange { + validator: args.validator.clone(), + new_rate: args.rate, + }; + let data = data.try_to_vec().map_err(Error::EncodeTxFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + let default_signer = args.validator.clone(); + process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + Ok(()) +} + +/// Submit transaction to withdraw an unbond +pub async fn submit_withdraw< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::Withdraw, +) -> Result<(), Error> { + let epoch = rpc::query_epoch(client).await; + + let validator = + known_validator_or_err(args.validator.clone(), args.tx.force, client) + .await?; + + let source = args.source.clone(); + let tx_code = args.tx_code_path; + + // Check the source's current unbond amount + let bond_source = source.clone().unwrap_or_else(|| validator.clone()); + let tokens = rpc::query_withdrawable_tokens( + client, + &bond_source, + &validator, + Some(epoch), + ) + .await; + if tokens == 0.into() { + eprintln!( + "There are no unbonded bonds ready to withdraw in the current \ + epoch {}.", + epoch + ); + rpc::query_and_print_unbonds(client, &bond_source, &validator).await; + if !args.tx.force { + return Err(Error::NoUnbondReady(epoch)); + } + } else { + println!("Found {tokens} tokens that can be withdrawn."); + println!("Submitting transaction to withdraw them..."); + } + + let data = pos::Withdraw { validator, source }; + let data = data.try_to_vec().map_err(Error::EncodeTxFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + let default_signer = args.source.unwrap_or(args.validator); + process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + Ok(()) +} + +/// Submit a transaction to unbond +pub async fn submit_unbond< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::Unbond, +) -> Result<(), Error> { + let validator = + known_validator_or_err(args.validator.clone(), args.tx.force, client) + .await?; + let source = args.source.clone(); + let tx_code = args.tx_code_path; + + // Check the source's current bond amount + let bond_source = source.clone().unwrap_or_else(|| validator.clone()); + let bond_amount = + rpc::query_bond(client, &bond_source, &validator, None).await; + println!("Bond amount available for unbonding: {} NAM", bond_amount); + + if args.amount > bond_amount { + eprintln!( + "The total bonds of the source {} is lower than the amount to be \ + unbonded. Amount to unbond is {} and the total bonds is {}.", + bond_source, args.amount, bond_amount + ); + if !args.tx.force { + return Err(Error::LowerBondThanUnbond( + bond_source, + args.amount, + bond_amount, + )); + } + } + + // Query the unbonds before submitting the tx + let unbonds = + rpc::query_unbond_with_slashing(client, &bond_source, &validator).await; + let mut withdrawable = BTreeMap::::new(); + for ((_start_epoch, withdraw_epoch), amount) in unbonds.into_iter() { + let to_withdraw = withdrawable.entry(withdraw_epoch).or_default(); + *to_withdraw += amount; + } + let latest_withdrawal_pre = withdrawable.into_iter().last(); + + let data = pos::Unbond { + validator: validator.clone(), + amount: args.amount, + source, + }; + let data = data.try_to_vec().map_err(Error::EncodeTxFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + let default_signer = args.source.unwrap_or(args.validator); + process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + + // Query the unbonds post-tx + let unbonds = + rpc::query_unbond_with_slashing(client, &bond_source, &validator).await; + let mut withdrawable = BTreeMap::::new(); + for ((_start_epoch, withdraw_epoch), amount) in unbonds.into_iter() { + let to_withdraw = withdrawable.entry(withdraw_epoch).or_default(); + *to_withdraw += amount; + } + let (latest_withdraw_epoch_post, latest_withdraw_amount_post) = + withdrawable.into_iter().last().unwrap(); + + if let Some((latest_withdraw_epoch_pre, latest_withdraw_amount_pre)) = + latest_withdrawal_pre + { + match latest_withdraw_epoch_post.cmp(&latest_withdraw_epoch_pre) { + std::cmp::Ordering::Less => { + if args.tx.force { + eprintln!( + "Unexpected behavior reading the unbonds data has \ + occurred" + ); + } else { + return Err(Error::UnboundError); + } + } + std::cmp::Ordering::Equal => { + println!( + "Amount {} withdrawable starting from epoch {}", + latest_withdraw_amount_post - latest_withdraw_amount_pre, + latest_withdraw_epoch_post + ); + } + std::cmp::Ordering::Greater => { + println!( + "Amount {} withdrawable starting from epoch {}", + latest_withdraw_amount_post, latest_withdraw_epoch_post + ); + } + } + } else { + println!( + "Amount {} withdrawable starting from epoch {}", + latest_withdraw_amount_post, latest_withdraw_epoch_post + ); + } + + Ok(()) +} + +/// Submit a transaction to bond +pub async fn submit_bond< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::Bond, +) -> Result<(), Error> { + let validator = + known_validator_or_err(args.validator.clone(), args.tx.force, client) + .await?; + + // Check that the source address exists on chain + let source = args.source.clone(); + let source = match args.source.clone() { + Some(source) => source_exists_or_err(source, args.tx.force, client) + .await + .map(Some), + None => Ok(source), + }?; + // Check bond's source (source for delegation or validator for self-bonds) + // balance + let bond_source = source.as_ref().unwrap_or(&validator); + let balance_key = token::balance_key(&args.native_token, bond_source); + + // TODO Should we state the same error message for the native token? + check_balance_too_low_err( + &args.native_token, + bond_source, + args.amount, + balance_key, + args.tx.force, + client, + ) + .await?; + + let tx_code = args.tx_code_path; + let bond = pos::Bond { + validator, + amount: args.amount, + source, + }; + let data = bond.try_to_vec().map_err(Error::EncodeTxFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + let default_signer = args.source.unwrap_or(args.validator); + process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(default_signer), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + Ok(()) +} + +/// Check if current epoch is in the last third of the voting period of the +/// proposal. This ensures that it is safe to optimize the vote writing to +/// storage. +pub async fn is_safe_voting_window( + client: &C, + proposal_id: u64, + proposal_start_epoch: Epoch, +) -> Result { + let current_epoch = rpc::query_epoch(client).await; + + let proposal_end_epoch_key = + gov_storage::get_voting_end_epoch_key(proposal_id); + let proposal_end_epoch = + rpc::query_storage_value::(client, &proposal_end_epoch_key) + .await; + + match proposal_end_epoch { + Some(proposal_end_epoch) => { + Ok(!crate::ledger::native_vp::governance::utils::is_valid_validator_voting_period( + current_epoch, + proposal_start_epoch, + proposal_end_epoch, + )) + } + None => { + Err(Error::EpochNotInStorage) + } + } +} + +/// Submit an IBC transfer +pub async fn submit_ibc_transfer< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::TxIbcTransfer, +) -> Result<(), Error> { + // Check that the source address exists on chain + let source = + source_exists_or_err(args.source.clone(), args.tx.force, client) + .await?; + // We cannot check the receiver + + let token = token_exists_or_err(args.token, args.tx.force, client).await?; + + // Check source balance + let (sub_prefix, balance_key) = match args.sub_prefix { + Some(sub_prefix) => { + let sub_prefix = storage::Key::parse(sub_prefix).unwrap(); + let prefix = token::multitoken_balance_prefix(&token, &sub_prefix); + ( + Some(sub_prefix), + token::multitoken_balance_key(&prefix, &source), + ) + } + None => (None, token::balance_key(&token, &source)), + }; + + check_balance_too_low_err( + &token, + &source, + args.amount, + balance_key, + args.tx.force, + client, + ) + .await?; + + let tx_code = args.tx_code_path; + + let denom = match sub_prefix { + // To parse IbcToken address, remove the address prefix + Some(sp) => sp.to_string().replace(RESERVED_ADDRESS_PREFIX, ""), + None => token.to_string(), + }; + let token = Coin { + denom, + amount: args.amount.to_string(), + }; + + // this height should be that of the destination chain, not this chain + let timeout_height = match args.timeout_height { + Some(h) => { + TimeoutHeight::At(IbcHeight::new(0, h).expect("invalid height")) + } + None => TimeoutHeight::Never, + }; + + let now: crate::tendermint::Time = DateTimeUtc::now().try_into().unwrap(); + let now: IbcTimestamp = now.into(); + let timeout_timestamp = if let Some(offset) = args.timeout_sec_offset { + (now + Duration::new(offset, 0)).unwrap() + } else if timeout_height == TimeoutHeight::Never { + // we cannot set 0 to both the height and the timestamp + (now + Duration::new(3600, 0)).unwrap() + } else { + IbcTimestamp::none() + }; + + let msg = MsgTransfer { + port_id_on_a: args.port_id, + chan_id_on_a: args.channel_id, + token, + sender: Signer::from_str(&source.to_string()).expect("invalid signer"), + receiver: Signer::from_str(&args.receiver).expect("invalid signer"), + timeout_height_on_b: timeout_height, + timeout_timestamp_on_b: timeout_timestamp, + }; + tracing::debug!("IBC transfer message {:?}", msg); + let any_msg = msg.to_any(); + let mut data = vec![]; + prost::Message::encode(&any_msg, &mut data) + .map_err(Error::EncodeFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(args.source), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + Ok(()) +} + +/// Submit an ordinary transfer +pub async fn submit_transfer< + C: crate::ledger::queries::Client + Sync, + V: WalletUtils, + U: ShieldedUtils, +>( + client: &C, + wallet: &mut Wallet, + shielded: &mut ShieldedContext, + args: args::TxTransfer, +) -> Result<(), Error> { + // Check that the source address exists on chain + let force = args.tx.force; + let transfer_source = args.source.clone(); + let source = source_exists_or_err( + transfer_source.effective_address(), + force, + client, + ) + .await?; + // Check that the target address exists on chain + let transfer_target = args.target.clone(); + let target = target_exists_or_err( + transfer_target.effective_address(), + force, + client, + ) + .await?; + + // Check that the token address exists on chain + let token = + &(token_exists_or_err(args.token.clone(), force, client).await?); + + // Check source balance + let (sub_prefix, balance_key) = match &args.sub_prefix { + Some(sub_prefix) => { + let sub_prefix = storage::Key::parse(sub_prefix).unwrap(); + let prefix = token::multitoken_balance_prefix(token, &sub_prefix); + ( + Some(sub_prefix), + token::multitoken_balance_key(&prefix, &source), + ) + } + None => (None, token::balance_key(token, &source)), + }; + + check_balance_too_low_err( + token, + &source, + args.amount, + balance_key, + args.tx.force, + client, + ) + .await?; + + let tx_code = args.tx_code_path.clone(); + let masp_addr = masp(); + // For MASP sources, use a special sentinel key recognized by VPs as default + // signer. Also, if the transaction is shielded, redact the amount and token + // types by setting the transparent value to 0 and token type to a constant. + // This has no side-effect because transaction is to self. + let (default_signer, amount, token) = + if source == masp_addr && target == masp_addr { + // TODO Refactor me, we shouldn't rely on any specific token here. + ( + TxSigningKey::SecretKey(masp_tx_key()), + 0.into(), + args.native_token.clone(), + ) + } else if source == masp_addr { + ( + TxSigningKey::SecretKey(masp_tx_key()), + args.amount, + token.clone(), + ) + } else { + ( + TxSigningKey::WalletAddress(source.clone()), + args.amount, + token.clone(), + ) + }; + // If our chosen signer is the MASP sentinel key, then our shielded inputs + // will need to cover the gas fees. + let chosen_signer = + tx_signer::(client, wallet, &args.tx, default_signer.clone()) + .await? + .ref_to(); + let shielded_gas = masp_tx_key().ref_to() == chosen_signer; + // Determine whether to pin this transaction to a storage key + let key = match &args.target { + TransferTarget::PaymentAddress(pa) if pa.is_pinned() => Some(pa.hash()), + _ => None, + }; + + let stx_result = shielded + .gen_shielded_transfer(client, args.clone(), shielded_gas) + .await; + let shielded = match stx_result { + Ok(stx) => Ok(stx.map(|x| x.0)), + Err(builder::Error::ChangeIsNegative(_)) => { + Err(Error::NegativeBalanceAfterTransfer( + source.clone(), + args.amount, + token.clone(), + args.tx.fee_amount, + args.tx.fee_token.clone(), + )) + } + Err(err) => Err(Error::MaspError(err)), + }?; + + let transfer = token::Transfer { + source: source.clone(), + target, + token, + sub_prefix, + amount, + key, + shielded, + }; + tracing::debug!("Transfer data {:?}", transfer); + let data = transfer.try_to_vec().map_err(Error::EncodeTxFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + #[cfg(not(feature = "mainnet"))] + let is_source_faucet = rpc::is_faucet_account(client, &source).await; + + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + let signing_address = TxSigningKey::WalletAddress(source); + process_tx::( + client, + wallet, + &args.tx, + tx, + signing_address, + #[cfg(not(feature = "mainnet"))] + is_source_faucet, + ) + .await?; + Ok(()) +} + +/// Submit a transaction to initialize an account +pub async fn submit_init_account< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::TxInitAccount, +) -> Result<(), Error> { + let public_key = args.public_key; + let vp_code = args.vp_code; + // Validate the VP code + validate_untrusted_code_err(&vp_code, args.tx.force)?; + let vp_code_path = String::from_utf8(args.vp_code_path).unwrap(); + let vp_code_hash = + query_wasm_code_hash(client, vp_code_path).await.unwrap(); + + let tx_code = args.tx_code_path; + let data = InitAccount { + public_key, + vp_code_hash, + }; + let data = data.try_to_vec().map_err(Error::EncodeTxFailure)?; + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + let tx = Tx::new(tx_code, Some(data), chain_id, expiration); + // TODO Move unwrap to an either + let initialized_accounts = process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(args.source), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await + .unwrap(); + save_initialized_accounts::(wallet, &args.tx, initialized_accounts) + .await; + Ok(()) +} + +/// Submit a transaction to update a VP +pub async fn submit_update_vp< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::TxUpdateVp, +) -> Result<(), Error> { + let addr = args.addr.clone(); + + // Check that the address is established and exists on chain + match &addr { + Address::Established(_) => { + let exists = rpc::known_address::(client, &addr).await; + if !exists { + if args.tx.force { + eprintln!("The address {} doesn't exist on chain.", addr); + Ok(()) + } else { + Err(Error::LocationDoesNotExist(addr.clone())) + } + } else { + Ok(()) + } + } + Address::Implicit(_) => { + if args.tx.force { + eprintln!( + "A validity predicate of an implicit address cannot be \ + directly updated. You can use an established address for \ + this purpose." + ); + Ok(()) + } else { + Err(Error::ImplicitUpdate) + } + } + Address::Internal(_) => { + if args.tx.force { + eprintln!( + "A validity predicate of an internal address cannot be \ + directly updated." + ); + Ok(()) + } else { + Err(Error::ImplicitInternalError) + } + } + }?; + + let vp_code_path = String::from_utf8(args.vp_code_path).unwrap(); + let vp_code_hash = + query_wasm_code_hash(client, vp_code_path).await.unwrap(); + + let tx_code_path = String::from_utf8(args.tx_code_path).unwrap(); + let tx_code_hash = + query_wasm_code_hash(client, tx_code_path).await.unwrap(); + + let data = UpdateVp { addr, vp_code_hash }; + let data = data.try_to_vec().map_err(Error::EncodeTxFailure)?; + + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + + let tx = Tx::new(tx_code_hash.to_vec(), Some(data), chain_id, expiration); + process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::WalletAddress(args.addr), + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + Ok(()) +} + +/// Submit a custom transaction +pub async fn submit_custom< + C: crate::ledger::queries::Client + Sync, + U: WalletUtils, +>( + client: &C, + wallet: &mut Wallet, + args: args::TxCustom, +) -> Result<(), Error> { + let tx_code = args.code_path; + let data = args.data_path; + let chain_id = args.tx.chain_id.clone().unwrap(); + let expiration = args.tx.expiration; + let tx = Tx::new(tx_code, data, chain_id, expiration); + let initialized_accounts = process_tx::( + client, + wallet, + &args.tx, + tx, + TxSigningKey::None, + #[cfg(not(feature = "mainnet"))] + false, + ) + .await?; + save_initialized_accounts::(wallet, &args.tx, initialized_accounts) + .await; + Ok(()) +} + +async fn expect_dry_broadcast( + to_broadcast: TxBroadcastData, + client: &C, + ret: T, +) -> Result { + match to_broadcast { + TxBroadcastData::DryRun(tx) => { + rpc::dry_run_tx(client, tx.to_bytes()).await; + Ok(ret) + } + TxBroadcastData::Wrapper { + tx, + wrapper_hash: _, + decrypted_hash: _, + } => Err(Error::ExpectDryRun(tx)), + } +} + +fn lift_rpc_error(res: Result) -> Result { + res.map_err(Error::TxBroadcast) +} + +/// Returns the given validator if the given address is a validator, +/// otherwise returns an error, force forces the address through even +/// if it isn't a validator +async fn known_validator_or_err( + validator: Address, + force: bool, + client: &C, +) -> Result { + // Check that the validator address exists on chain + let is_validator = rpc::is_validator(client, &validator).await; + if !is_validator { + if force { + eprintln!( + "The address {} doesn't belong to any known validator account.", + validator + ); + Ok(validator) + } else { + Err(Error::InvalidValidatorAddress(validator)) + } + } else { + Ok(validator) + } +} + +/// general pattern for checking if an address exists on the chain, or +/// throwing an error if it's not forced. Takes a generic error +/// message and the error type. +async fn address_exists_or_err( + addr: Address, + force: bool, + client: &C, + message: String, + err: F, +) -> Result +where + C: crate::ledger::queries::Client + Sync, + F: FnOnce(Address) -> Error, +{ + let addr_exists = rpc::known_address::(client, &addr).await; + if !addr_exists { + if force { + eprintln!("{}", message); + Ok(addr) + } else { + Err(err(addr)) + } + } else { + Ok(addr) + } +} + +/// Returns the given token if the given address exists on chain +/// otherwise returns an error, force forces the address through even +/// if it isn't on chain +async fn token_exists_or_err( + token: Address, + force: bool, + client: &C, +) -> Result { + let message = + format!("The token address {} doesn't exist on chain.", token); + address_exists_or_err( + token, + force, + client, + message, + Error::TokenDoesNotExist, + ) + .await +} + +/// Returns the given source address if the given address exists on chain +/// otherwise returns an error, force forces the address through even +/// if it isn't on chain +async fn source_exists_or_err( + token: Address, + force: bool, + client: &C, +) -> Result { + let message = + format!("The source address {} doesn't exist on chain.", token); + address_exists_or_err( + token, + force, + client, + message, + Error::SourceDoesNotExist, + ) + .await +} + +/// Returns the given target address if the given address exists on chain +/// otherwise returns an error, force forces the address through even +/// if it isn't on chain +async fn target_exists_or_err( + token: Address, + force: bool, + client: &C, +) -> Result { + let message = + format!("The target address {} doesn't exist on chain.", token); + address_exists_or_err( + token, + force, + client, + message, + Error::TargetLocationDoesNotExist, + ) + .await +} + +/// checks the balance at the given address is enough to transfer the +/// given amount, along with the balance even existing. force +/// overrides this +async fn check_balance_too_low_err( + token: &Address, + source: &Address, + amount: token::Amount, + balance_key: storage::Key, + force: bool, + client: &C, +) -> Result<(), Error> { + match rpc::query_storage_value::(client, &balance_key) + .await + { + Some(balance) => { + if balance < amount { + if force { + eprintln!( + "The balance of the source {} of token {} is lower \ + than the amount to be transferred. Amount to \ + transfer is {} and the balance is {}.", + source, token, amount, balance + ); + Ok(()) + } else { + Err(Error::BalanceTooLow( + source.clone(), + token.clone(), + amount, + balance, + )) + } + } else { + Ok(()) + } + } + None => { + if force { + eprintln!( + "No balance found for the source {} of token {}", + source, token + ); + Ok(()) + } else { + Err(Error::NoBalanceForToken(source.clone(), token.clone())) + } + } + } +} + +fn validate_untrusted_code_err( + vp_code: &Vec, + force: bool, +) -> Result<(), Error> { + if let Err(err) = vm::validate_untrusted_wasm(vp_code) { + if force { + eprintln!("Validity predicate code validation failed with {}", err); + Ok(()) + } else { + Err(Error::WasmValidationFailure(err)) + } + } else { + Ok(()) + } +} diff --git a/shared/src/ledger/vp_host_fns.rs b/shared/src/ledger/vp_host_fns.rs index 84b3e6f357..de1d7b8c75 100644 --- a/shared/src/ledger/vp_host_fns.rs +++ b/shared/src/ledger/vp_host_fns.rs @@ -67,14 +67,14 @@ where let (log_val, gas) = write_log.read_pre(key); add_gas(gas_meter, gas)?; match log_val { - Some(&write_log::StorageModification::Write { ref value }) => { + Some(write_log::StorageModification::Write { ref value }) => { Ok(Some(value.clone())) } Some(&write_log::StorageModification::Delete) => { // Given key has been deleted Ok(None) } - Some(&write_log::StorageModification::InitAccount { + Some(write_log::StorageModification::InitAccount { ref vp_code_hash, }) => { // Read the VP of a new account @@ -109,14 +109,14 @@ where let (log_val, gas) = write_log.read(key); add_gas(gas_meter, gas)?; match log_val { - Some(&write_log::StorageModification::Write { ref value }) => { + Some(write_log::StorageModification::Write { ref value }) => { Ok(Some(value.clone())) } Some(&write_log::StorageModification::Delete) => { // Given key has been deleted Ok(None) } - Some(&write_log::StorageModification::InitAccount { + Some(write_log::StorageModification::InitAccount { ref vp_code_hash, }) => { // Read the VP code hash of a new account @@ -146,7 +146,7 @@ pub fn read_temp( let (log_val, gas) = write_log.read(key); add_gas(gas_meter, gas)?; match log_val { - Some(&write_log::StorageModification::Temp { ref value }) => { + Some(write_log::StorageModification::Temp { ref value }) => { Ok(Some(value.clone())) } None => Ok(None), diff --git a/shared/src/ledger/wallet/alias.rs b/shared/src/ledger/wallet/alias.rs new file mode 100644 index 0000000000..13d977b852 --- /dev/null +++ b/shared/src/ledger/wallet/alias.rs @@ -0,0 +1,103 @@ +//! Wallet address and key aliases. + +use std::convert::Infallible; +use std::fmt::Display; +use std::hash::Hash; +use std::str::FromStr; + +use serde::{Deserialize, Serialize}; + +/// Aliases created from raw strings are kept in-memory as given, but their +/// `Serialize` and `Display` instance converts them to lowercase. Their +/// `PartialEq` instance is case-insensitive. +#[derive(Clone, Debug, Default, Deserialize, PartialOrd, Ord, Eq)] +#[serde(transparent)] +pub struct Alias(String); + +impl Alias { + /// Normalize an alias to lower-case + pub fn normalize(&self) -> String { + self.0.to_lowercase() + } + + /// Returns the length of the underlying `String`. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Is the underlying `String` empty? + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +impl Serialize for Alias { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.normalize().serialize(serializer) + } +} + +impl PartialEq for Alias { + fn eq(&self, other: &Self) -> bool { + self.normalize() == other.normalize() + } +} + +impl Hash for Alias { + fn hash(&self, state: &mut H) { + self.normalize().hash(state); + } +} + +impl From for Alias +where + T: AsRef, +{ + fn from(raw: T) -> Self { + Self(raw.as_ref().to_owned()) + } +} + +impl From for String { + fn from(alias: Alias) -> Self { + alias.normalize() + } +} + +impl<'a> From<&'a Alias> for String { + fn from(alias: &'a Alias) -> Self { + alias.normalize() + } +} + +impl Display for Alias { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.normalize().fmt(f) + } +} + +impl FromStr for Alias { + type Err = Infallible; + + fn from_str(s: &str) -> Result { + Ok(Self(s.into())) + } +} + +/// Default alias of a validator's account key +pub fn validator_key(validator_alias: &Alias) -> Alias { + format!("{validator_alias}-validator-key").into() +} + +/// Default alias of a validator's consensus key +pub fn validator_consensus_key(validator_alias: &Alias) -> Alias { + format!("{validator_alias}-consensus-key").into() +} + +/// Default alias of a validator's Tendermint node key +pub fn validator_tendermint_node_key(validator_alias: &Alias) -> Alias { + format!("{validator_alias}-tendermint-node-key").into() +} diff --git a/shared/src/ledger/wallet/keys.rs b/shared/src/ledger/wallet/keys.rs new file mode 100644 index 0000000000..ce8c1769dc --- /dev/null +++ b/shared/src/ledger/wallet/keys.rs @@ -0,0 +1,244 @@ +//! Cryptographic keys for digital signatures support for the wallet. + +use std::fmt::Display; +use std::marker::PhantomData; +use std::str::FromStr; + +use borsh::{BorshDeserialize, BorshSerialize}; +use data_encoding::HEXLOWER; +use orion::{aead, kdf}; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use crate::ledger::wallet::WalletUtils; + +const ENCRYPTED_KEY_PREFIX: &str = "encrypted:"; +const UNENCRYPTED_KEY_PREFIX: &str = "unencrypted:"; + +/// A keypair stored in a wallet +#[derive(Debug)] +pub enum StoredKeypair +where + ::Err: Display, +{ + /// An encrypted keypair + Encrypted(EncryptedKeypair), + /// An raw (unencrypted) keypair + Raw(T), +} + +impl Serialize + for StoredKeypair +where + ::Err: Display, +{ + fn serialize( + &self, + serializer: S, + ) -> std::result::Result + where + S: serde::Serializer, + { + // String encoded, because toml doesn't support enums + match self { + StoredKeypair::Encrypted(encrypted) => { + let keypair_string = + format!("{}{}", ENCRYPTED_KEY_PREFIX, encrypted); + serde::Serialize::serialize(&keypair_string, serializer) + } + StoredKeypair::Raw(raw) => { + let keypair_string = + format!("{}{}", UNENCRYPTED_KEY_PREFIX, raw); + serde::Serialize::serialize(&keypair_string, serializer) + } + } + } +} + +impl<'de, T: BorshSerialize + BorshDeserialize + Display + FromStr> + Deserialize<'de> for StoredKeypair +where + ::Err: Display, +{ + fn deserialize(deserializer: D) -> std::result::Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + let keypair_string: String = + serde::Deserialize::deserialize(deserializer) + .map_err(|err| { + DeserializeStoredKeypairError::InvalidStoredKeypairString( + err.to_string(), + ) + }) + .map_err(D::Error::custom)?; + if let Some(raw) = keypair_string.strip_prefix(UNENCRYPTED_KEY_PREFIX) { + FromStr::from_str(raw) + .map(|keypair| Self::Raw(keypair)) + .map_err(|err| { + DeserializeStoredKeypairError::InvalidStoredKeypairString( + err.to_string(), + ) + }) + .map_err(D::Error::custom) + } else if let Some(encrypted) = + keypair_string.strip_prefix(ENCRYPTED_KEY_PREFIX) + { + FromStr::from_str(encrypted) + .map(Self::Encrypted) + .map_err(|err| { + DeserializeStoredKeypairError::InvalidStoredKeypairString( + err.to_string(), + ) + }) + .map_err(D::Error::custom) + } else { + Err(DeserializeStoredKeypairError::MissingPrefix) + .map_err(D::Error::custom) + } + } +} + +#[allow(missing_docs)] +#[derive(Error, Debug)] +pub enum DeserializeStoredKeypairError { + #[error("The stored keypair is not valid: {0}")] + InvalidStoredKeypairString(String), + #[error("The stored keypair is missing a prefix")] + MissingPrefix, +} + +/// An encrypted keypair stored in a wallet +#[derive(Debug)] +pub struct EncryptedKeypair( + Vec, + PhantomData, +); + +impl Display for EncryptedKeypair { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", HEXLOWER.encode(self.0.as_ref())) + } +} + +impl FromStr for EncryptedKeypair { + type Err = data_encoding::DecodeError; + + fn from_str(s: &str) -> Result { + HEXLOWER.decode(s.as_ref()).map(|x| Self(x, PhantomData)) + } +} + +#[allow(missing_docs)] +#[derive(Debug, Error)] +pub enum DecryptionError { + #[error("Unexpected encryption salt")] + BadSalt, + #[error("Unable to decrypt the keypair. Is the password correct?")] + DecryptionError, + #[error("Unable to deserialize the keypair")] + DeserializingError, + #[error("Asked not to decrypt")] + NotDecrypting, +} + +impl + StoredKeypair +where + ::Err: Display, +{ + /// Construct a keypair for storage. If no password is provided, the keypair + /// will be stored raw without encryption. Returns the key for storing and a + /// reference-counting point to the raw key. + pub fn new(keypair: T, password: Option) -> (Self, T) { + match password { + Some(password) => ( + Self::Encrypted(EncryptedKeypair::new(&keypair, password)), + keypair, + ), + None => (Self::Raw(keypair.clone()), keypair), + } + } + + /// Get a raw keypair from a stored keypair. If the keypair is encrypted and + /// no password is provided in the argument, a password will be prompted + /// from stdin. + pub fn get( + &self, + decrypt: bool, + password: Option, + ) -> Result { + match self { + StoredKeypair::Encrypted(encrypted_keypair) => { + if decrypt { + let password = password.unwrap_or_else(|| { + U::read_password("Enter decryption password: ") + }); + let key = encrypted_keypair.decrypt(password)?; + Ok(key) + } else { + Err(DecryptionError::NotDecrypting) + } + } + StoredKeypair::Raw(keypair) => Ok(keypair.clone()), + } + } + + /// Indicates whether this key has been encrypted or not + pub fn is_encrypted(&self) -> bool { + match self { + StoredKeypair::Encrypted(_) => true, + StoredKeypair::Raw(_) => false, + } + } +} + +impl EncryptedKeypair { + /// Encrypt a keypair and store it with its salt. + pub fn new(keypair: &T, password: String) -> Self { + let salt = encryption_salt(); + let encryption_key = encryption_key(&salt, password); + + let data = keypair + .try_to_vec() + .expect("Serializing keypair shouldn't fail"); + + let encrypted_keypair = aead::seal(&encryption_key, &data) + .expect("Encryption of data shouldn't fail"); + + let encrypted_data = [salt.as_ref(), &encrypted_keypair].concat(); + + Self(encrypted_data, PhantomData) + } + + /// Decrypt an encrypted keypair + pub fn decrypt(&self, password: String) -> Result { + let salt_len = encryption_salt().len(); + let (raw_salt, cipher) = self.0.split_at(salt_len); + + let salt = kdf::Salt::from_slice(raw_salt) + .map_err(|_| DecryptionError::BadSalt)?; + + let encryption_key = encryption_key(&salt, password); + + let decrypted_data = aead::open(&encryption_key, cipher) + .map_err(|_| DecryptionError::DecryptionError)?; + + T::try_from_slice(&decrypted_data) + .map_err(|_| DecryptionError::DeserializingError) + } +} + +/// Keypair encryption salt +fn encryption_salt() -> kdf::Salt { + kdf::Salt::default() +} + +/// Make encryption secret key from a password. +fn encryption_key(salt: &kdf::Salt, password: String) -> kdf::SecretKey { + kdf::Password::from_slice(password.as_bytes()) + .and_then(|password| kdf::derive_key(&password, salt, 3, 1 << 17, 32)) + .expect("Generation of encryption secret key shouldn't fail") +} diff --git a/shared/src/ledger/wallet/mod.rs b/shared/src/ledger/wallet/mod.rs new file mode 100644 index 0000000000..5fb2913b45 --- /dev/null +++ b/shared/src/ledger/wallet/mod.rs @@ -0,0 +1,511 @@ +//! Provides functionality for managing keys and addresses for a user +pub mod alias; +mod keys; +pub mod pre_genesis; +pub mod store; + +use std::collections::{HashMap, HashSet}; +use std::fmt::Display; +use std::marker::PhantomData; +use std::str::FromStr; + +use alias::Alias; +use borsh::{BorshDeserialize, BorshSerialize}; +use masp_primitives::zip32::ExtendedFullViewingKey; +pub use pre_genesis::gen_key_to_store; +pub use store::{gen_sk, AddressVpType, Store}; +use thiserror::Error; + +pub use self::keys::{DecryptionError, StoredKeypair}; +pub use self::store::{ConfirmationResponse, ValidatorData, ValidatorKeys}; +use crate::types::address::Address; +use crate::types::key::*; +use crate::types::masp::{ + ExtendedSpendingKey, ExtendedViewingKey, PaymentAddress, +}; + +/// Captures the interactive parts of the wallet's functioning +pub trait WalletUtils { + /// The location where the wallet is stored + type Storage; + /// Read the password for encryption/decryption from the file/env/stdin. + /// Panics if all options are empty/invalid. + fn read_password(prompt_msg: &str) -> String; + + /// Read an alias from the file/env/stdin. + fn read_alias(prompt_msg: &str) -> String; + + /// The given alias has been selected but conflicts with another alias in + /// the store. Offer the user to either replace existing mapping, alter the + /// chosen alias to a name of their chosing, or cancel the aliasing. + fn show_overwrite_confirmation( + alias: &Alias, + alias_for: &str, + ) -> store::ConfirmationResponse; +} + +/// A degenerate implementation of wallet interactivity +pub struct SdkWalletUtils(PhantomData); + +impl WalletUtils for SdkWalletUtils { + type Storage = U; + + fn read_password(_prompt_msg: &str) -> String { + panic!("attempted to prompt for password in non-interactive mode"); + } + + fn read_alias(_prompt_msg: &str) -> String { + panic!("attempted to prompt for alias in non-interactive mode"); + } + + fn show_overwrite_confirmation( + _alias: &Alias, + _alias_for: &str, + ) -> store::ConfirmationResponse { + // Automatically replace aliases in non-interactive mode + store::ConfirmationResponse::Replace + } +} + +/// The error that is produced when a given key cannot be obtained +#[derive(Error, Debug)] +pub enum FindKeyError { + /// Could not find a given key in the wallet + #[error("No matching key found")] + KeyNotFound, + /// Could not decrypt a given key in the wallet + #[error("{0}")] + KeyDecryptionError(keys::DecryptionError), +} + +/// Represents a collection of keys and addresses while caching key decryptions +#[derive(Debug)] +pub struct Wallet { + store_dir: U::Storage, + store: Store, + decrypted_key_cache: HashMap, + decrypted_spendkey_cache: HashMap, +} + +impl Wallet { + /// Create a new wallet from the given backing store and storage location + pub fn new(store_dir: U::Storage, store: Store) -> Self { + Self { + store_dir, + store, + decrypted_key_cache: HashMap::default(), + decrypted_spendkey_cache: HashMap::default(), + } + } + + /// Generate a new keypair and derive an implicit address from its public + /// and insert them into the store with the provided alias, converted to + /// lower case. If none provided, the alias will be the public key hash (in + /// lowercase too). If the key is to be encrypted, will prompt for + /// password from stdin. Stores the key in decrypted key cache and + /// returns the alias of the key and a reference-counting pointer to the + /// key. + pub fn gen_key( + &mut self, + scheme: SchemeType, + alias: Option, + password: Option, + ) -> (String, common::SecretKey) { + let (alias, key) = self.store.gen_key::(scheme, alias, password); + // Cache the newly added key + self.decrypted_key_cache.insert(alias.clone(), key.clone()); + (alias.into(), key) + } + + /// Generate a spending key and store it under the given alias in the wallet + pub fn gen_spending_key( + &mut self, + alias: String, + password: Option, + ) -> (String, ExtendedSpendingKey) { + let (alias, key) = self.store.gen_spending_key::(alias, password); + // Cache the newly added key + self.decrypted_spendkey_cache.insert(alias.clone(), key); + (alias.into(), key) + } + + /// Add validator data to the store + pub fn add_validator_data( + &mut self, + address: Address, + keys: ValidatorKeys, + ) { + self.store.add_validator_data(address, keys); + } + + /// Returns the validator data, if it exists. + pub fn get_validator_data(&self) -> Option<&ValidatorData> { + self.store.get_validator_data() + } + + /// Returns the validator data, if it exists. the save function + /// cannot be called after using this method as it involves a + /// partial move + pub fn take_validator_data(&mut self) -> Option<&mut ValidatorData> { + self.store.validator_data() + } + + /// Find the stored key by an alias, a public key hash or a public key. + /// If the key is encrypted and password not supplied, then password will be + /// interactively prompted. Any keys that are decrypted are stored in and + /// read from a cache to avoid prompting for password multiple times. + pub fn find_key( + &mut self, + alias_pkh_or_pk: impl AsRef, + password: Option, + ) -> Result { + // Try cache first + if let Some(cached_key) = self + .decrypted_key_cache + .get(&alias_pkh_or_pk.as_ref().into()) + { + return Ok(cached_key.clone()); + } + // If not cached, look-up in store + let stored_key = self + .store + .find_key(alias_pkh_or_pk.as_ref()) + .ok_or(FindKeyError::KeyNotFound)?; + Self::decrypt_stored_key::<_>( + &mut self.decrypted_key_cache, + stored_key, + alias_pkh_or_pk.into(), + password, + ) + } + + /// Find the spending key with the given alias in the wallet and return it. + /// If the spending key is encrypted but a password is not supplied, then it + /// will be interactively prompted. + pub fn find_spending_key( + &mut self, + alias: impl AsRef, + password: Option, + ) -> Result { + // Try cache first + if let Some(cached_key) = + self.decrypted_spendkey_cache.get(&alias.as_ref().into()) + { + return Ok(*cached_key); + } + // If not cached, look-up in store + let stored_spendkey = self + .store + .find_spending_key(alias.as_ref()) + .ok_or(FindKeyError::KeyNotFound)?; + Self::decrypt_stored_key::<_>( + &mut self.decrypted_spendkey_cache, + stored_spendkey, + alias.into(), + password, + ) + } + + /// Find the viewing key with the given alias in the wallet and return it + pub fn find_viewing_key( + &mut self, + alias: impl AsRef, + ) -> Result<&ExtendedViewingKey, FindKeyError> { + self.store + .find_viewing_key(alias.as_ref()) + .ok_or(FindKeyError::KeyNotFound) + } + + /// Find the payment address with the given alias in the wallet and return + /// it + pub fn find_payment_addr( + &self, + alias: impl AsRef, + ) -> Option<&PaymentAddress> { + self.store.find_payment_addr(alias.as_ref()) + } + + /// Find the stored key by a public key. + /// If the key is encrypted and password not supplied, then password will be + /// interactively prompted for. Any keys that are decrypted are stored in + /// and read from a cache to avoid prompting for password multiple times. + pub fn find_key_by_pk( + &mut self, + pk: &common::PublicKey, + password: Option, + ) -> Result { + // Try to look-up alias for the given pk. Otherwise, use the PKH string. + let pkh: PublicKeyHash = pk.into(); + let alias = self + .store + .find_alias_by_pkh(&pkh) + .unwrap_or_else(|| pkh.to_string().into()); + // Try read cache + if let Some(cached_key) = self.decrypted_key_cache.get(&alias) { + return Ok(cached_key.clone()); + } + // Look-up from store + let stored_key = self + .store + .find_key_by_pk(pk) + .ok_or(FindKeyError::KeyNotFound)?; + Self::decrypt_stored_key::<_>( + &mut self.decrypted_key_cache, + stored_key, + alias, + password, + ) + } + + /// Find the stored key by a public key hash. + /// If the key is encrypted and password is not supplied, then password will + /// be interactively prompted for. Any keys that are decrypted are stored in + /// and read from a cache to avoid prompting for password multiple times. + pub fn find_key_by_pkh( + &mut self, + pkh: &PublicKeyHash, + password: Option, + ) -> Result { + // Try to look-up alias for the given pk. Otherwise, use the PKH string. + let alias = self + .store + .find_alias_by_pkh(pkh) + .unwrap_or_else(|| pkh.to_string().into()); + // Try read cache + if let Some(cached_key) = self.decrypted_key_cache.get(&alias) { + return Ok(cached_key.clone()); + } + // Look-up from store + let stored_key = self + .store + .find_key_by_pkh(pkh) + .ok_or(FindKeyError::KeyNotFound)?; + Self::decrypt_stored_key::<_>( + &mut self.decrypted_key_cache, + stored_key, + alias, + password, + ) + } + + /// Decrypt stored key, if it's not stored un-encrypted. + /// If a given storage key needs to be decrypted and password is not + /// supplied, then interactively prompt for password and if successfully + /// decrypted, store it in a cache. + fn decrypt_stored_key< + T: FromStr + Display + BorshSerialize + BorshDeserialize + Clone, + >( + decrypted_key_cache: &mut HashMap, + stored_key: &StoredKeypair, + alias: Alias, + password: Option, + ) -> Result + where + ::Err: Display, + { + match stored_key { + StoredKeypair::Encrypted(encrypted) => { + let password = password.unwrap_or_else(|| { + U::read_password("Enter decryption password: ") + }); + let key = encrypted + .decrypt(password) + .map_err(FindKeyError::KeyDecryptionError)?; + decrypted_key_cache.insert(alias.clone(), key); + decrypted_key_cache + .get(&alias) + .cloned() + .ok_or(FindKeyError::KeyNotFound) + } + StoredKeypair::Raw(raw) => Ok(raw.clone()), + } + } + + /// Get all known keys by their alias, paired with PKH, if known. + pub fn get_keys( + &self, + ) -> HashMap< + String, + (&StoredKeypair, Option<&PublicKeyHash>), + > { + self.store + .get_keys() + .into_iter() + .map(|(alias, value)| (alias.into(), value)) + .collect() + } + + /// Find the stored address by an alias. + pub fn find_address(&self, alias: impl AsRef) -> Option<&Address> { + self.store.find_address(alias) + } + + /// Find an alias by the address if it's in the wallet. + pub fn find_alias(&self, address: &Address) -> Option<&Alias> { + self.store.find_alias(address) + } + + /// Get all known addresses by their alias, paired with PKH, if known. + pub fn get_addresses(&self) -> HashMap { + self.store + .get_addresses() + .iter() + .map(|(alias, value)| (alias.into(), value.clone())) + .collect() + } + + /// Get all known payment addresses by their alias + pub fn get_payment_addrs(&self) -> HashMap { + self.store + .get_payment_addrs() + .iter() + .map(|(alias, value)| (alias.into(), *value)) + .collect() + } + + /// Get all known viewing keys by their alias + pub fn get_viewing_keys(&self) -> HashMap { + self.store + .get_viewing_keys() + .iter() + .map(|(alias, value)| (alias.into(), *value)) + .collect() + } + + /// Get all known viewing keys by their alias + pub fn get_spending_keys( + &self, + ) -> HashMap> { + self.store + .get_spending_keys() + .iter() + .map(|(alias, value)| (alias.into(), value)) + .collect() + } + + /// Add a new address with the given alias. If the alias is already used, + /// will ask whether the existing alias should be replaced, a different + /// alias is desired, or the alias creation should be cancelled. Return + /// the chosen alias if the address has been added, otherwise return + /// nothing. + pub fn add_address( + &mut self, + alias: impl AsRef, + address: Address, + ) -> Option { + self.store + .insert_address::(alias.into(), address) + .map(Into::into) + } + + /// Insert a new key with the given alias. If the alias is already used, + /// will prompt for overwrite confirmation. + pub fn insert_keypair( + &mut self, + alias: String, + keypair: StoredKeypair, + pkh: PublicKeyHash, + ) -> Option { + self.store + .insert_keypair::(alias.into(), keypair, pkh) + .map(Into::into) + } + + /// Insert a viewing key into the wallet under the given alias + pub fn insert_viewing_key( + &mut self, + alias: String, + view_key: ExtendedViewingKey, + ) -> Option { + self.store + .insert_viewing_key::(alias.into(), view_key) + .map(Into::into) + } + + /// Insert a spending key into the wallet under the given alias + pub fn insert_spending_key( + &mut self, + alias: String, + spend_key: StoredKeypair, + viewkey: ExtendedViewingKey, + ) -> Option { + self.store + .insert_spending_key::(alias.into(), spend_key, viewkey) + .map(Into::into) + } + + /// Encrypt the given spending key and insert it into the wallet under the + /// given alias + pub fn encrypt_insert_spending_key( + &mut self, + alias: String, + spend_key: ExtendedSpendingKey, + password: Option, + ) -> Option { + self.store + .insert_spending_key::( + alias.into(), + StoredKeypair::new(spend_key, password).0, + ExtendedFullViewingKey::from(&spend_key.into()).into(), + ) + .map(Into::into) + } + + /// Insert a payment address into the wallet under the given alias + pub fn insert_payment_addr( + &mut self, + alias: String, + payment_addr: PaymentAddress, + ) -> Option { + self.store + .insert_payment_addr::(alias.into(), payment_addr) + .map(Into::into) + } + + /// Extend this wallet from pre-genesis validator wallet. + pub fn extend_from_pre_genesis_validator( + &mut self, + validator_address: Address, + validator_alias: Alias, + other: pre_genesis::ValidatorWallet, + ) { + self.store.extend_from_pre_genesis_validator( + validator_address, + validator_alias, + other, + ) + } + + /// Gets all addresses given a vp_type + pub fn get_addresses_with_vp_type( + &self, + vp_type: AddressVpType, + ) -> HashSet
{ + self.store.get_addresses_with_vp_type(vp_type) + } + + /// Add a vp_type to a given address + pub fn add_vp_type_to_address( + &mut self, + vp_type: AddressVpType, + address: Address, + ) { + // defaults to an empty set + self.store.add_vp_type_to_address(vp_type, address) + } + + /// Provide immutable access to the backing store + pub fn store(&self) -> &Store { + &self.store + } + + /// Provide mutable access to the backing store + pub fn store_mut(&mut self) -> &mut Store { + &mut self.store + } + + /// Access storage location data + pub fn store_dir(&self) -> &U::Storage { + &self.store_dir + } +} diff --git a/shared/src/ledger/wallet/pre_genesis.rs b/shared/src/ledger/wallet/pre_genesis.rs new file mode 100644 index 0000000000..333a9f21e7 --- /dev/null +++ b/shared/src/ledger/wallet/pre_genesis.rs @@ -0,0 +1,80 @@ +//! Provides functionality for managing validator keys +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use crate::ledger::wallet; +use crate::ledger::wallet::{store, StoredKeypair}; +use crate::types::key::{common, SchemeType}; + +/// Ways in which wallet store operations can fail +#[derive(Error, Debug)] +pub enum ReadError { + /// Failed decoding the wallet store + #[error("Failed decoding the wallet store: {0}")] + Decode(toml::de::Error), + /// Failed to read the wallet store + #[error("Failed to read the wallet store from {0}: {1}")] + ReadWallet(String, String), + /// Failed to write the wallet store + #[error("Failed to write the wallet store: {0}")] + StoreNewWallet(String), + /// Failed to decode a key + #[error("Failed to decode a key: {0}")] + Decryption(wallet::keys::DecryptionError), +} + +/// Validator pre-genesis wallet includes all the required keys for genesis +/// setup and a cache of decrypted keys. +pub struct ValidatorWallet { + /// The wallet store that can be written/read to/from TOML + pub store: ValidatorStore, + /// Cryptographic keypair for validator account key + pub account_key: common::SecretKey, + /// Cryptographic keypair for consensus key + pub consensus_key: common::SecretKey, + /// Cryptographic keypair for Tendermint node key + pub tendermint_node_key: common::SecretKey, +} + +/// Validator pre-genesis wallet store includes all the required keys for +/// genesis setup. +#[derive(Serialize, Deserialize, Debug)] +pub struct ValidatorStore { + /// Cryptographic keypair for validator account key + pub account_key: wallet::StoredKeypair, + /// Cryptographic keypair for consensus key + pub consensus_key: wallet::StoredKeypair, + /// Cryptographic keypair for Tendermint node key + pub tendermint_node_key: wallet::StoredKeypair, + /// Special validator keys + pub validator_keys: wallet::ValidatorKeys, +} + +impl ValidatorStore { + /// Decode from TOML string bytes + pub fn decode(data: Vec) -> Result { + toml::from_slice(&data) + } + + /// Encode in TOML string bytes + pub fn encode(&self) -> Vec { + toml::to_vec(self).expect( + "Serializing of validator pre-genesis wallet shouldn't fail", + ) + } +} + +/// Generate a key and then encrypt it +pub fn gen_key_to_store( + scheme: SchemeType, + password: &Option, +) -> (StoredKeypair, common::SecretKey) { + let sk = store::gen_sk(scheme); + StoredKeypair::new(sk, password.clone()) +} + +impl From for ReadError { + fn from(err: wallet::keys::DecryptionError) -> Self { + ReadError::Decryption(err) + } +} diff --git a/shared/src/ledger/wallet/store.rs b/shared/src/ledger/wallet/store.rs new file mode 100644 index 0000000000..b4214d5a7d --- /dev/null +++ b/shared/src/ledger/wallet/store.rs @@ -0,0 +1,645 @@ +//! Wallet Store information + +use std::collections::{HashMap, HashSet}; +use std::fmt::Display; +use std::str::FromStr; + +use bimap::BiHashMap; +use masp_primitives::zip32::ExtendedFullViewingKey; +#[cfg(feature = "masp-tx-gen")] +use rand_core::RngCore; +use serde::{Deserialize, Serialize}; + +use super::alias::{self, Alias}; +use super::pre_genesis; +use crate::ledger::wallet::{StoredKeypair, WalletUtils}; +use crate::types::address::{Address, ImplicitAddress}; +use crate::types::key::dkg_session_keys::DkgKeypair; +use crate::types::key::*; +use crate::types::masp::{ + ExtendedSpendingKey, ExtendedViewingKey, PaymentAddress, +}; + +/// Actions that can be taken when there is an alias conflict +pub enum ConfirmationResponse { + /// Replace the existing alias + Replace, + /// Reselect the alias that is ascribed to a given entity + Reselect(Alias), + /// Skip assigning the given entity an alias + Skip, +} + +/// Special keys for a validator +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ValidatorKeys { + /// Special keypair for signing protocol txs + pub protocol_keypair: common::SecretKey, + /// Special session keypair needed by validators for participating + /// in the DKG protocol + pub dkg_keypair: Option, +} + +impl ValidatorKeys { + /// Get the protocol keypair + pub fn get_protocol_keypair(&self) -> &common::SecretKey { + &self.protocol_keypair + } +} + +/// Special data associated with a validator +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ValidatorData { + /// The address associated to a validator + pub address: Address, + /// special keys for a validator + pub keys: ValidatorKeys, +} + +/// A Storage area for keys and addresses +#[derive(Serialize, Deserialize, Debug, Default)] +pub struct Store { + /// Known viewing keys + view_keys: HashMap, + /// Known spending keys + spend_keys: HashMap>, + /// Known payment addresses + payment_addrs: HashMap, + /// Cryptographic keypairs + keys: HashMap>, + /// Namada address book + addresses: BiHashMap, + /// Known mappings of public key hashes to their aliases in the `keys` + /// field. Used for look-up by a public key. + pkhs: HashMap, + /// Special keys if the wallet belongs to a validator + pub(crate) validator_data: Option, + /// Namada address vp type + address_vp_types: HashMap>, +} + +/// Grouping of addresses by validity predicate. +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +pub enum AddressVpType { + /// The Token + Token, +} + +impl Store { + /// Find the stored key by an alias, a public key hash or a public key. + pub fn find_key( + &self, + alias_pkh_or_pk: impl AsRef, + ) -> Option<&StoredKeypair> { + let alias_pkh_or_pk = alias_pkh_or_pk.as_ref(); + // Try to find by alias + self.keys + .get(&alias_pkh_or_pk.into()) + // Try to find by PKH + .or_else(|| { + let pkh = PublicKeyHash::from_str(alias_pkh_or_pk).ok()?; + self.find_key_by_pkh(&pkh) + }) + // Try to find by PK + .or_else(|| { + let pk = common::PublicKey::from_str(alias_pkh_or_pk).ok()?; + self.find_key_by_pk(&pk) + }) + } + + /// Find the spending key with the given alias and return it + pub fn find_spending_key( + &self, + alias: impl AsRef, + ) -> Option<&StoredKeypair> { + self.spend_keys.get(&alias.into()) + } + + /// Find the viewing key with the given alias and return it + pub fn find_viewing_key( + &self, + alias: impl AsRef, + ) -> Option<&ExtendedViewingKey> { + self.view_keys.get(&alias.into()) + } + + /// Find the payment address with the given alias and return it + pub fn find_payment_addr( + &self, + alias: impl AsRef, + ) -> Option<&PaymentAddress> { + self.payment_addrs.get(&alias.into()) + } + + /// Find the stored key by a public key. + pub fn find_key_by_pk( + &self, + pk: &common::PublicKey, + ) -> Option<&StoredKeypair> { + let pkh = PublicKeyHash::from(pk); + self.find_key_by_pkh(&pkh) + } + + /// Find the stored key by a public key hash. + pub fn find_key_by_pkh( + &self, + pkh: &PublicKeyHash, + ) -> Option<&StoredKeypair> { + let alias = self.pkhs.get(pkh)?; + self.keys.get(alias) + } + + /// Find the stored alias for a public key hash. + pub fn find_alias_by_pkh(&self, pkh: &PublicKeyHash) -> Option { + self.pkhs.get(pkh).cloned() + } + + /// Find the stored address by an alias. + pub fn find_address(&self, alias: impl AsRef) -> Option<&Address> { + self.addresses.get_by_left(&alias.into()) + } + + /// Find an alias by the address if it's in the wallet. + pub fn find_alias(&self, address: &Address) -> Option<&Alias> { + self.addresses.get_by_right(address) + } + + /// Get all known keys by their alias, paired with PKH, if known. + pub fn get_keys( + &self, + ) -> HashMap< + Alias, + (&StoredKeypair, Option<&PublicKeyHash>), + > { + let mut keys: HashMap< + Alias, + (&StoredKeypair, Option<&PublicKeyHash>), + > = self + .pkhs + .iter() + .filter_map(|(pkh, alias)| { + let key = &self.keys.get(alias)?; + Some((alias.clone(), (*key, Some(pkh)))) + }) + .collect(); + self.keys.iter().for_each(|(alias, key)| { + if !keys.contains_key(alias) { + keys.insert(alias.clone(), (key, None)); + } + }); + keys + } + + /// Get all known addresses by their alias, paired with PKH, if known. + pub fn get_addresses(&self) -> &BiHashMap { + &self.addresses + } + + /// Get all known payment addresses by their alias. + pub fn get_payment_addrs(&self) -> &HashMap { + &self.payment_addrs + } + + /// Get all known viewing keys by their alias. + pub fn get_viewing_keys(&self) -> &HashMap { + &self.view_keys + } + + /// Get all known spending keys by their alias. + pub fn get_spending_keys( + &self, + ) -> &HashMap> { + &self.spend_keys + } + + #[cfg(feature = "masp-tx-gen")] + fn generate_spending_key() -> ExtendedSpendingKey { + use rand::rngs::OsRng; + let mut spend_key = [0; 32]; + OsRng.fill_bytes(&mut spend_key); + masp_primitives::zip32::ExtendedSpendingKey::master(spend_key.as_ref()) + .into() + } + + /// Generate a new keypair and insert it into the store with the provided + /// alias. If none provided, the alias will be the public key hash. + /// If no password is provided, the keypair will be stored raw without + /// encryption. Returns the alias of the key and a reference-counting + /// pointer to the key. + pub fn gen_key( + &mut self, + scheme: SchemeType, + alias: Option, + password: Option, + ) -> (Alias, common::SecretKey) { + let sk = gen_sk(scheme); + let pkh: PublicKeyHash = PublicKeyHash::from(&sk.ref_to()); + let (keypair_to_store, raw_keypair) = StoredKeypair::new(sk, password); + let address = Address::Implicit(ImplicitAddress(pkh.clone())); + let alias: Alias = alias.unwrap_or_else(|| pkh.clone().into()).into(); + if self + .insert_keypair::(alias.clone(), keypair_to_store, pkh) + .is_none() + { + panic!("Action cancelled, no changes persisted."); + } + if self.insert_address::(alias.clone(), address).is_none() { + panic!("Action cancelled, no changes persisted."); + } + (alias, raw_keypair) + } + + /// Generate a spending key similarly to how it's done for keypairs + pub fn gen_spending_key( + &mut self, + alias: String, + password: Option, + ) -> (Alias, ExtendedSpendingKey) { + let spendkey = Self::generate_spending_key(); + let viewkey = ExtendedFullViewingKey::from(&spendkey.into()).into(); + let (spendkey_to_store, _raw_spendkey) = + StoredKeypair::new(spendkey, password); + let alias = Alias::from(alias); + if self + .insert_spending_key::(alias.clone(), spendkey_to_store, viewkey) + .is_none() + { + panic!("Action cancelled, no changes persisted."); + } + (alias, spendkey) + } + + /// Add validator data to the store + pub fn add_validator_data( + &mut self, + address: Address, + keys: ValidatorKeys, + ) { + self.validator_data = Some(ValidatorData { address, keys }); + } + + /// Returns the validator data, if it exists + pub fn get_validator_data(&self) -> Option<&ValidatorData> { + self.validator_data.as_ref() + } + + /// Returns the validator data, if it exists + pub fn validator_data(&mut self) -> Option<&mut ValidatorData> { + self.validator_data.as_mut() + } + + /// Insert a new key with the given alias. If the alias is already used, + /// will prompt for overwrite/reselection confirmation. If declined, then + /// keypair is not inserted and nothing is returned, otherwise selected + /// alias is returned. + pub fn insert_keypair( + &mut self, + alias: Alias, + keypair: StoredKeypair, + pkh: PublicKeyHash, + ) -> Option { + if alias.is_empty() { + println!( + "Empty alias given, defaulting to {}.", + Into::::into(pkh.to_string()) + ); + } + // Addresses and keypairs can share aliases, so first remove any + // addresses sharing the same namesake before checking if alias has been + // used. + let counterpart_address = self.addresses.remove_by_left(&alias); + if self.contains_alias(&alias) { + match U::show_overwrite_confirmation(&alias, "a key") { + ConfirmationResponse::Replace => {} + ConfirmationResponse::Reselect(new_alias) => { + // Restore the removed address in case the recursive prompt + // terminates with a cancellation + counterpart_address + .map(|x| self.addresses.insert(alias.clone(), x.1)); + return self.insert_keypair::(new_alias, keypair, pkh); + } + ConfirmationResponse::Skip => { + // Restore the removed address since this insertion action + // has now been cancelled + counterpart_address + .map(|x| self.addresses.insert(alias.clone(), x.1)); + return None; + } + } + } + self.remove_alias(&alias); + self.keys.insert(alias.clone(), keypair); + self.pkhs.insert(pkh, alias.clone()); + // Since it is intended for the inserted keypair to share its namesake + // with the pre-existing address + counterpart_address.map(|x| self.addresses.insert(alias.clone(), x.1)); + Some(alias) + } + + /// Insert spending keys similarly to how it's done for keypairs + pub fn insert_spending_key( + &mut self, + alias: Alias, + spendkey: StoredKeypair, + viewkey: ExtendedViewingKey, + ) -> Option { + if alias.is_empty() { + eprintln!("Empty alias given."); + return None; + } + if self.contains_alias(&alias) { + match U::show_overwrite_confirmation(&alias, "a spending key") { + ConfirmationResponse::Replace => {} + ConfirmationResponse::Reselect(new_alias) => { + return self.insert_spending_key::( + new_alias, spendkey, viewkey, + ); + } + ConfirmationResponse::Skip => return None, + } + } + self.remove_alias(&alias); + self.spend_keys.insert(alias.clone(), spendkey); + // Simultaneously add the derived viewing key to ease balance viewing + self.view_keys.insert(alias.clone(), viewkey); + Some(alias) + } + + /// Insert viewing keys similarly to how it's done for keypairs + pub fn insert_viewing_key( + &mut self, + alias: Alias, + viewkey: ExtendedViewingKey, + ) -> Option { + if alias.is_empty() { + eprintln!("Empty alias given."); + return None; + } + if self.contains_alias(&alias) { + match U::show_overwrite_confirmation(&alias, "a viewing key") { + ConfirmationResponse::Replace => {} + ConfirmationResponse::Reselect(new_alias) => { + return self.insert_viewing_key::(new_alias, viewkey); + } + ConfirmationResponse::Skip => return None, + } + } + self.remove_alias(&alias); + self.view_keys.insert(alias.clone(), viewkey); + Some(alias) + } + + /// Check if any map of the wallet contains the given alias + fn contains_alias(&self, alias: &Alias) -> bool { + self.payment_addrs.contains_key(alias) + || self.view_keys.contains_key(alias) + || self.spend_keys.contains_key(alias) + || self.keys.contains_key(alias) + || self.addresses.contains_left(alias) + } + + /// Completely remove the given alias from all maps in the wallet + fn remove_alias(&mut self, alias: &Alias) { + self.payment_addrs.remove(alias); + self.view_keys.remove(alias); + self.spend_keys.remove(alias); + self.keys.remove(alias); + self.addresses.remove_by_left(alias); + self.pkhs.retain(|_key, val| val != alias); + } + + /// Insert payment addresses similarly to how it's done for keypairs + pub fn insert_payment_addr( + &mut self, + alias: Alias, + payment_addr: PaymentAddress, + ) -> Option { + if alias.is_empty() { + eprintln!("Empty alias given."); + return None; + } + if self.contains_alias(&alias) { + match U::show_overwrite_confirmation(&alias, "a payment address") { + ConfirmationResponse::Replace => {} + ConfirmationResponse::Reselect(new_alias) => { + return self + .insert_payment_addr::(new_alias, payment_addr); + } + ConfirmationResponse::Skip => return None, + } + } + self.remove_alias(&alias); + self.payment_addrs.insert(alias.clone(), payment_addr); + Some(alias) + } + + /// Helper function to restore keypair given alias-keypair mapping and the + /// pkhs-alias mapping. + fn restore_keypair( + &mut self, + alias: Alias, + key: Option>, + pkh: Option, + ) { + key.map(|x| self.keys.insert(alias.clone(), x)); + pkh.map(|x| self.pkhs.insert(x, alias.clone())); + } + + /// Insert a new address with the given alias. If the alias is already used, + /// will prompt for overwrite/reselection confirmation, which when declined, + /// the address won't be added. Return the selected alias if the address has + /// been added. + pub fn insert_address( + &mut self, + alias: Alias, + address: Address, + ) -> Option { + if alias.is_empty() { + println!("Empty alias given, defaulting to {}.", address.encode()); + } + // Addresses and keypairs can share aliases, so first remove any keys + // sharing the same namesake before checking if alias has been used. + let counterpart_key = self.keys.remove(&alias); + let mut counterpart_pkh = None; + self.pkhs.retain(|k, v| { + if v == &alias { + counterpart_pkh = Some(k.clone()); + false + } else { + true + } + }); + if self.addresses.contains_left(&alias) { + match U::show_overwrite_confirmation(&alias, "an address") { + ConfirmationResponse::Replace => {} + ConfirmationResponse::Reselect(new_alias) => { + // Restore the removed keypair in case the recursive prompt + // terminates with a cancellation + self.restore_keypair( + alias, + counterpart_key, + counterpart_pkh, + ); + return self.insert_address::(new_alias, address); + } + ConfirmationResponse::Skip => { + // Restore the removed keypair since this insertion action + // has now been cancelled + self.restore_keypair( + alias, + counterpart_key, + counterpart_pkh, + ); + return None; + } + } + } + self.remove_alias(&alias); + self.addresses.insert(alias.clone(), address); + // Since it is intended for the inserted address to share its namesake + // with the pre-existing keypair + self.restore_keypair(alias.clone(), counterpart_key, counterpart_pkh); + Some(alias) + } + + /// Extend this store from pre-genesis validator wallet. + pub fn extend_from_pre_genesis_validator( + &mut self, + validator_address: Address, + validator_alias: Alias, + other: pre_genesis::ValidatorWallet, + ) { + let account_key_alias = alias::validator_key(&validator_alias); + let consensus_key_alias = + alias::validator_consensus_key(&validator_alias); + let tendermint_node_key_alias = + alias::validator_tendermint_node_key(&validator_alias); + + let keys = [ + (account_key_alias.clone(), other.store.account_key), + (consensus_key_alias.clone(), other.store.consensus_key), + ( + tendermint_node_key_alias.clone(), + other.store.tendermint_node_key, + ), + ]; + self.keys.extend(keys.into_iter()); + + let account_pk = other.account_key.ref_to(); + let consensus_pk = other.consensus_key.ref_to(); + let tendermint_node_pk = other.tendermint_node_key.ref_to(); + let addresses = [ + (account_key_alias.clone(), (&account_pk).into()), + (consensus_key_alias.clone(), (&consensus_pk).into()), + ( + tendermint_node_key_alias.clone(), + (&tendermint_node_pk).into(), + ), + ]; + self.addresses.extend(addresses.into_iter()); + + let pkhs = [ + ((&account_pk).into(), account_key_alias), + ((&consensus_pk).into(), consensus_key_alias), + ((&tendermint_node_pk).into(), tendermint_node_key_alias), + ]; + self.pkhs.extend(pkhs.into_iter()); + + self.validator_data = Some(ValidatorData { + address: validator_address, + keys: other.store.validator_keys, + }); + } + + /// get an address with the vp type + pub fn get_addresses_with_vp_type( + &self, + vp_type: AddressVpType, + ) -> HashSet
{ + // defaults to an empty set + self.address_vp_types + .get(&vp_type) + .cloned() + .unwrap_or_default() + } + + /// Adds a VP type to the address + pub fn add_vp_type_to_address( + &mut self, + vp_type: AddressVpType, + address: Address, + ) { + // defaults to an empty set + self.address_vp_types + .entry(vp_type) + .or_default() + .insert(address); + } + + /// Decode a Store from the given bytes + pub fn decode(data: Vec) -> Result { + toml::from_slice(&data) + } + + /// Encode a store into a string of bytes + pub fn encode(&self) -> Vec { + toml::to_vec(self).expect("Serializing of store shouldn't fail") + } +} + +/// Generate a new secret key. +pub fn gen_sk(scheme: SchemeType) -> common::SecretKey { + use rand::rngs::OsRng; + let mut csprng = OsRng {}; + match scheme { + SchemeType::Ed25519 => ed25519::SigScheme::generate(&mut csprng) + .try_to_sk() + .unwrap(), + SchemeType::Secp256k1 => secp256k1::SigScheme::generate(&mut csprng) + .try_to_sk() + .unwrap(), + SchemeType::Common => common::SigScheme::generate(&mut csprng) + .try_to_sk() + .unwrap(), + } +} + +impl Display for AddressVpType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AddressVpType::Token => write!(f, "token"), + } + } +} + +impl FromStr for AddressVpType { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "token" => Ok(Self::Token), + _ => Err("unexpected address VP type"), + } + } +} + +impl Serialize for AddressVpType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + self.to_string().serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for AddressVpType { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error; + + let raw: String = Deserialize::deserialize(deserializer)?; + Self::from_str(&raw).map_err(D::Error::custom) + } +} diff --git a/shared/src/vm/host_env.rs b/shared/src/vm/host_env.rs index 49625b9097..238ba58520 100644 --- a/shared/src/vm/host_env.rs +++ b/shared/src/vm/host_env.rs @@ -604,7 +604,7 @@ where let (log_val, gas) = write_log.read(&key); tx_add_gas(env, gas)?; Ok(match log_val { - Some(&write_log::StorageModification::Write { ref value }) => { + Some(write_log::StorageModification::Write { ref value }) => { let len: i64 = value .len() .try_into() @@ -617,7 +617,7 @@ where // fail, given key has been deleted HostEnvResult::Fail.to_i64() } - Some(&write_log::StorageModification::InitAccount { + Some(write_log::StorageModification::InitAccount { ref vp_code_hash, }) => { // read the VP of a new account @@ -629,7 +629,7 @@ where result_buffer.replace(vp_code_hash.to_vec()); len } - Some(&write_log::StorageModification::Temp { ref value }) => { + Some(write_log::StorageModification::Temp { ref value }) => { let len: i64 = value .len() .try_into() @@ -749,7 +749,7 @@ where ); tx_add_gas(env, iter_gas + log_gas)?; match log_val { - Some(&write_log::StorageModification::Write { ref value }) => { + Some(write_log::StorageModification::Write { ref value }) => { let key_val = KeyVal { key, val: value.clone(), @@ -772,7 +772,7 @@ where // a VP of a new account doesn't need to be iterated continue; } - Some(&write_log::StorageModification::Temp { ref value }) => { + Some(write_log::StorageModification::Temp { ref value }) => { let key_val = KeyVal { key, val: value.clone(), diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 0174bb0afa..84a1402812 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -21,7 +21,7 @@ abciplus = [ wasm-runtime = ["namada/wasm-runtime"] [dependencies] -namada = {path = "../shared", default-features = false, features = ["testing"]} +namada = {path = "../shared", default-features = false, features = ["testing", "namada-sdk"]} namada_core = {path = "../core", default-features = false, features = ["testing"]} namada_test_utils = {path = "../test_utils"} namada_vp_prelude = {path = "../vp_prelude", default-features = false} @@ -44,8 +44,8 @@ tokio = {version = "1.8.2", features = ["full"]} tracing = "0.1.30" tracing-subscriber = {version = "0.3.7", default-features = false, features = ["env-filter", "fmt"]} derivative = "2.2.0" -rust_decimal = "1.26.1" -rust_decimal_macros = "1.26.1" +rust_decimal = "=1.26.1" +rust_decimal_macros = "=1.26.1" [dev-dependencies] namada_apps = {path = "../apps", default-features = false, features = ["testing"]} diff --git a/tests/src/e2e/ibc_tests.rs b/tests/src/e2e/ibc_tests.rs index ea6261aed1..00ee58d52b 100644 --- a/tests/src/e2e/ibc_tests.rs +++ b/tests/src/e2e/ibc_tests.rs @@ -237,14 +237,16 @@ fn make_client_state(test: &Test, height: Height) -> TmClientState { let key = pos::params_key(); let pos_params = Runtime::new() .unwrap() - .block_on(query_storage_value::(&client, &key)) + .block_on(query_storage_value::(&client, &key)) .unwrap(); let pipeline_len = pos_params.pipeline_len; let key = param_storage::get_epoch_duration_storage_key(); let epoch_duration = Runtime::new() .unwrap() - .block_on(query_storage_value::(&client, &key)) + .block_on(query_storage_value::( + &client, &key, + )) .unwrap(); let unbonding_period = pipeline_len * epoch_duration.min_duration.0; diff --git a/tests/src/e2e/ledger_tests.rs b/tests/src/e2e/ledger_tests.rs index a8f9adfb48..3bfe013ebc 100644 --- a/tests/src/e2e/ledger_tests.rs +++ b/tests/src/e2e/ledger_tests.rs @@ -23,7 +23,7 @@ use namada::types::address::{btc, eth, masp_rewards, Address}; use namada::types::governance::ProposalType; use namada::types::storage::Epoch; use namada::types::token; -use namada_apps::client::tx::ShieldedContext; +use namada_apps::client::tx::CLIShieldedUtils; use namada_apps::config::genesis::genesis_config::{ GenesisConfig, ParametersConfig, PosParamsConfig, }; @@ -580,7 +580,7 @@ fn ledger_txs_and_queries() -> Result<()> { #[test] fn masp_txs_and_queries() -> Result<()> { // Download the shielded pool parameters before starting node - let _ = ShieldedContext::new(PathBuf::new()); + let _ = CLIShieldedUtils::new(PathBuf::new()); // Lengthen epoch to ensure that a transaction can be constructed and // submitted within the same block. Necessary to ensure that conversion is // not invalidated. @@ -850,7 +850,7 @@ fn masp_txs_and_queries() -> Result<()> { #[test] fn masp_pinned_txs() -> Result<()> { // Download the shielded pool parameters before starting node - let _ = ShieldedContext::new(PathBuf::new()); + let _ = CLIShieldedUtils::new(PathBuf::new()); // Lengthen epoch to ensure that a transaction can be constructed and // submitted within the same block. Necessary to ensure that conversion is // not invalidated. @@ -1011,7 +1011,7 @@ fn masp_pinned_txs() -> Result<()> { #[test] fn masp_incentives() -> Result<()> { // Download the shielded pool parameters before starting node - let _ = ShieldedContext::new(PathBuf::new()); + let _ = CLIShieldedUtils::new(PathBuf::new()); // Lengthen epoch to ensure that a transaction can be constructed and // submitted within the same block. Necessary to ensure that conversion is // not invalidated. diff --git a/tx_prelude/Cargo.toml b/tx_prelude/Cargo.toml index 52461df5ed..31619f6398 100644 --- a/tx_prelude/Cargo.toml +++ b/tx_prelude/Cargo.toml @@ -23,4 +23,4 @@ namada_vm_env = {path = "../vm_env", default-features = false} borsh = "0.9.0" sha2 = "0.10.1" thiserror = "1.0.38" -rust_decimal = "1.26.1" +rust_decimal = "=1.26.1" diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index aba2858dfb..446358015f 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.26.2", + "gimli 0.27.2", ] [[package]] @@ -44,16 +44,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "ark-bls12-381" @@ -98,6 +98,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ed-on-bls12-381" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b7ada17db3854f5994e74e60b18e10e818594935ee7e1d329800c117b32970" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-std", +] + [[package]] name = "ark-ff" version = "0.3.0" @@ -123,7 +135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -135,7 +147,20 @@ dependencies = [ "num-bigint", "num-traits", "quote", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0f78f47537c2f15706db7e98fe64cc1711dbf9def81218194e17239e53e5aa" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.11.2", ] [[package]] @@ -157,7 +182,7 @@ checksum = "8dd4e5f0bf8285d5ed538d27fab7411f3e297908fd93c62195de8bee3f199e82" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -172,9 +197,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" @@ -188,36 +213,138 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils 0.8.15", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", + "pin-project-lite", ] [[package]] name = "async-stream-impl" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -236,6 +363,12 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "autocfg" version = "1.1.0" @@ -244,9 +377,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.7" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fb79c228270dcf2426e74864cabc94babb5dbab01a4314e702d2f16540e1591" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", @@ -266,16 +399,15 @@ dependencies = [ "serde", "sync_wrapper", "tower", - "tower-http", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cae3e661676ffbacb30f1a824089a8c9150e71017f7e1e38f2aa32009188d34" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", @@ -290,16 +422,16 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.29.0", + "object 0.30.3", "rustc-demangle", ] @@ -348,7 +480,7 @@ dependencies = [ "bitvec 0.22.3", "blake2s_simd 0.5.11", "byteorder", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "ff 0.11.1", "group 0.11.0", "lazy_static", @@ -370,6 +502,24 @@ dependencies = [ "crunchy 0.1.6", ] +[[package]] +name = "bimap" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bip0039" version = "0.9.0" @@ -407,7 +557,7 @@ checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" dependencies = [ "bech32 0.9.1", "bitcoin_hashes", - "secp256k1", + "secp256k1 0.24.3", "serde", ] @@ -450,6 +600,15 @@ dependencies = [ "wyz 0.5.1", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "blake2b_simd" version = "0.5.11" @@ -458,18 +617,18 @@ checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake2b_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.2.5", ] [[package]] @@ -480,31 +639,31 @@ checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake2s_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.2.5", ] [[package]] name = "blake3" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" dependencies = [ "arrayref", "arrayvec 0.7.2", "cc", "cfg-if 1.0.0", - "constant_time_eq", + "constant_time_eq 0.2.5", "digest 0.10.6", ] @@ -519,9 +678,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -542,6 +701,21 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "bls12_381" version = "0.6.1" @@ -573,7 +747,7 @@ dependencies = [ "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -583,7 +757,7 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -593,7 +767,7 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -604,9 +778,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "byte-slice-cast" @@ -616,23 +790,24 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -658,9 +833,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" dependencies = [ "serde", ] @@ -682,16 +857,16 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.14", + "semver 1.0.17", "serde", "serde_json", ] [[package]] name = "cc" -version = "1.0.76" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -732,9 +907,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "num-integer", @@ -766,23 +941,22 @@ version = "0.5.0" source = "git+https://github.com/marmeladema/clru-rs.git?rev=71ca566#71ca566915f21f3c308091ca7756a91b0f8b5afc" [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "concat-idents" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832" dependencies = [ - "termcolor", - "unicode-width", + "quote", + "syn 1.0.109", ] [[package]] -name = "concat-idents" -version = "1.1.4" +name = "concurrent-queue" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" dependencies = [ - "quote", - "syn", + "crossbeam-utils 0.8.15", ] [[package]] @@ -797,6 +971,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + [[package]] name = "contracts" version = "0.6.3" @@ -805,7 +985,7 @@ checksum = "f1d1429e3bd78171c65aa010eabcdf8f863ba3254728dbfb0ad4b1545beac15c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -820,15 +1000,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -914,35 +1094,35 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", ] [[package]] name = "crossbeam-epoch" -version = "0.9.11" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", - "memoffset", + "crossbeam-utils 0.8.15", + "memoffset 0.8.0", "scopeguard", ] @@ -959,9 +1139,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if 1.0.0", ] @@ -1035,6 +1215,12 @@ dependencies = [ "crypto_api", ] +[[package]] +name = "ct-codecs" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" + [[package]] name = "ct-logs" version = "0.8.0" @@ -1044,6 +1230,16 @@ dependencies = [ "sct 0.6.1", ] +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1070,55 +1266,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "cxx" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "darling" -version = "0.14.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ "darling_core", "darling_macro", @@ -1126,33 +1278,33 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "der" @@ -1177,7 +1329,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1188,7 +1340,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1206,7 +1358,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", "subtle", ] @@ -1254,13 +1406,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1281,7 +1433,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1340,6 +1492,7 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", "ed25519", + "merlin", "rand 0.7.3", "serde", "serde_bytes", @@ -1361,9 +1514,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -1401,28 +1554,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1430,19 +1583,40 @@ name = "equihash" version = "0.1.0" source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "byteorder", ] [[package]] name = "erased-serde" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ca605381c017ec7a5fef5e548f1cfaa419ed0f6df6367339300db74c92aa7d" +checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" dependencies = [ "serde", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "error-chain" version = "0.12.4" @@ -1452,6 +1626,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "eyre" version = "0.6.8" @@ -1470,13 +1650,50 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] +[[package]] +name = "ferveo" +version = "0.1.1" +source = "git+https://github.com/anoma/ferveo?rev=e5abd0acc938da90140351a65a26472eb495ce4d#e5abd0acc938da90140351a65a26472eb495ce4d" +dependencies = [ + "anyhow", + "ark-bls12-381", + "ark-ec", + "ark-ed-on-bls12-381", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "bincode", + "blake2", + "blake2b_simd 1.0.1", + "borsh", + "digest 0.10.6", + "ed25519-dalek", + "either", + "ferveo-common", + "group-threshold-cryptography", + "hex", + "itertools", + "measure_time", + "miracl_core", + "num", + "rand 0.7.3", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_json", + "subproductdomain", + "subtle", + "zeroize", +] + [[package]] name = "ferveo-common" version = "0.1.0" @@ -1571,8 +1788,7 @@ dependencies = [ [[package]] name = "funty" version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" +source = "git+https://github.com/bitvecto-rs/funty/?rev=7ef0d890fbcd8b3def1635ac1a877fc298488446#7ef0d890fbcd8b3def1635ac1a877fc298488446" [[package]] name = "funty" @@ -1582,9 +1798,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -1597,9 +1813,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -1607,15 +1823,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -1624,38 +1840,53 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] [[package]] name = "futures-macro" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "futures-sink" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.26" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -1671,9 +1902,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1692,9 +1923,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1716,15 +1947,27 @@ dependencies = [ [[package]] name = "gimli" -version = "0.26.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] [[package]] name = "group" @@ -1749,6 +1992,30 @@ dependencies = [ "subtle", ] +[[package]] +name = "group-threshold-cryptography" +version = "0.1.0" +source = "git+https://github.com/anoma/ferveo?rev=e5abd0acc938da90140351a65a26472eb495ce4d#e5abd0acc938da90140351a65a26472eb495ce4d" +dependencies = [ + "anyhow", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "blake2b_simd 1.0.1", + "chacha20", + "hex", + "itertools", + "miracl_core", + "rand 0.8.5", + "rand_core 0.6.4", + "rayon", + "subproductdomain", + "thiserror", +] + [[package]] name = "gumdrop" version = "0.8.1" @@ -1766,14 +2033,14 @@ checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "h2" -version = "0.3.15" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -1828,9 +2095,9 @@ dependencies = [ [[package]] name = "hdpath" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dafb09e5d85df264339ad786a147d9de1da13687a3697c52244297e5e7c32d9c" +checksum = "09ae1615f843ce3981b47468f3f7c435ac17deb33c2261e64d7f1e87f5c11acc" dependencies = [ "byteorder", ] @@ -1868,13 +2135,19 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -1923,9 +2196,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -1943,12 +2216,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - [[package]] name = "httparse" version = "1.8.0" @@ -1979,9 +2246,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", @@ -2052,32 +2319,31 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "ibc" version = "0.36.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=dcce4ac23d4d0a4324d23c54a1a99d41f0be2076#dcce4ac23d4d0a4324d23c54a1a99d41f0be2076" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9#2d7edc16412b60cabf78163fe24a6264e11f77a9" dependencies = [ "bytes", "cfg-if 1.0.0", @@ -2125,7 +2391,7 @@ dependencies = [ [[package]] name = "ibc-proto" version = "0.26.0" -source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb#acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb" +source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f#7e527b5b8c95d83351e93ceafc14ac853224283f" dependencies = [ "base64 0.13.1", "bytes", @@ -2148,7 +2414,7 @@ dependencies = [ "bitcoin", "bs58", "bytes", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "digest 0.10.6", "dirs-next", "ed25519", @@ -2172,8 +2438,8 @@ dependencies = [ "regex", "retry", "ripemd", - "secp256k1", - "semver 1.0.14", + "secp256k1 0.24.3", + "semver 1.0.17", "serde", "serde_derive", "serde_json", @@ -2192,7 +2458,7 @@ dependencies = [ "toml", "tonic", "tracing", - "uuid 1.2.1", + "uuid 1.3.2", ] [[package]] @@ -2283,7 +2549,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2312,9 +2578,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", @@ -2328,6 +2594,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -2341,15 +2621,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -2382,9 +2662,21 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] [[package]] name = "lazy_static" @@ -2400,9 +2692,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libloading" @@ -2465,13 +2757,10 @@ dependencies = [ ] [[package]] -name = "link-cplusplus" -version = "1.0.7" +name = "linux-raw-sys" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "lock_api" @@ -2490,6 +2779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", + "value-bag", ] [[package]] @@ -2510,7 +2800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2530,8 +2820,8 @@ dependencies = [ "aes", "bip0039", "bitvec 0.22.3", - "blake2b_simd 1.0.0", - "blake2s_simd 1.0.0", + "blake2b_simd 1.0.1", + "blake2s_simd 1.0.1", "bls12_381", "borsh", "byteorder", @@ -2546,6 +2836,8 @@ dependencies = [ "lazy_static", "rand 0.8.5", "rand_core 0.6.4", + "ripemd160", + "secp256k1 0.20.3", "serde", "sha2 0.9.9", "subtle", @@ -2559,7 +2851,7 @@ version = "0.5.0" source = "git+https://github.com/anoma/masp?rev=bee40fc465f6afbd10558d12fe96eb1742eee45c#bee40fc465f6afbd10558d12fe96eb1742eee45c" dependencies = [ "bellman", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "bls12_381", "byteorder", "directories", @@ -2595,6 +2887,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +[[package]] +name = "measure_time" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852" +dependencies = [ + "instant", + "log", +] + [[package]] name = "memchr" version = "2.5.0" @@ -2603,9 +2905,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] @@ -2619,6 +2921,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "memory_units" version = "0.4.0" @@ -2634,42 +2945,60 @@ dependencies = [ "nonempty", ] +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.5.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] +[[package]] +name = "miracl_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c7128ba23c81f6471141b90f17654f89ef44a56e14b8a4dd0fddfccd655277" + [[package]] name = "moka" version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b9268097a2cf211ac9955b1cc95e80fa84fff5c2d13ba292916445dc8a311f" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "num_cpus", "once_cell", "parking_lot", @@ -2681,7 +3010,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.2.1", + "uuid 1.3.2", ] [[package]] @@ -2700,8 +3029,10 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" name = "namada" version = "0.15.3" dependencies = [ + "async-std", "async-trait", "bellman", + "bimap", "bls12_381", "borsh", "circular-queue", @@ -2716,20 +3047,27 @@ dependencies = [ "masp_proofs", "namada_core", "namada_proof_of_stake", + "orion", "parity-wasm", "paste", "proptest", "prost", "pwasm-utils", + "rand 0.8.5", + "rand_core 0.6.4", "rayon", "rust_decimal", "rust_decimal_macros", + "serde", "serde_json", "sha2 0.9.9", "tempfile", "tendermint 0.23.6", "tendermint-proto 0.23.6", + "tendermint-rpc 0.23.6", "thiserror", + "tokio", + "toml", "tracing", "wasmer", "wasmer-cache", @@ -2746,6 +3084,7 @@ name = "namada_core" version = "0.15.3" dependencies = [ "ark-bls12-381", + "ark-ec", "ark-serialize", "bech32 0.8.1", "bellman", @@ -2754,7 +3093,9 @@ dependencies = [ "data-encoding", "derivative", "ed25519-consensus", + "ferveo", "ferveo-common", + "group-threshold-cryptography", "ibc", "ibc-proto 0.26.0", "ics23", @@ -2789,7 +3130,7 @@ version = "0.15.3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2893,7 +3234,7 @@ name = "namada_wasm" version = "0.15.3" dependencies = [ "borsh", - "getrandom 0.2.8", + "getrandom 0.2.9", "masp_primitives", "masp_proofs", "namada", @@ -2916,6 +3257,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -2928,6 +3283,15 @@ dependencies = [ "serde", ] +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2936,7 +3300,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2949,6 +3313,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.1" @@ -2974,11 +3349,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -2996,18 +3371,18 @@ dependencies = [ [[package]] name = "object" -version = "0.29.0" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -3031,7 +3406,7 @@ dependencies = [ "arrayvec 0.7.2", "bigint", "bitvec 0.22.3", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "ff 0.11.1", "fpe", "group 0.11.0", @@ -3048,6 +3423,18 @@ dependencies = [ "zcash_note_encryption 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "orion" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c" +dependencies = [ + "ct-codecs", + "getrandom 0.2.9", + "subtle", + "zeroize", +] + [[package]] name = "pairing" version = "0.21.0" @@ -3059,9 +3446,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" +checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -3080,7 +3467,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3089,6 +3476,12 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parking_lot" version = "0.12.1" @@ -3101,15 +3494,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3140,9 +3533,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" @@ -3198,9 +3591,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" dependencies = [ "thiserror", "ucd-trie", @@ -3208,9 +3601,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", "indexmap", @@ -3233,7 +3626,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3248,6 +3641,22 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if 1.0.0", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "poly1305" version = "0.7.2" @@ -3272,7 +3681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -3315,7 +3724,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -3332,9 +3741,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -3352,7 +3761,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax", + "regex-syntax 0.6.29", "rusty-fork", "tempfile", "unarray", @@ -3360,9 +3769,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", "prost-derive", @@ -3370,9 +3779,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck", @@ -3385,29 +3794,29 @@ dependencies = [ "prost", "prost-types", "regex", - "syn", + "syn 1.0.109", "tempfile", "which", ] [[package]] name = "prost-derive" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "prost-types" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379119666929a1afd7a043aa6cf96fa67a6dce9af60c88095a4686dbce4c9c88" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ "prost", ] @@ -3429,7 +3838,7 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3459,7 +3868,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e31331286705f455e56cca62e0e717158474ff02b7936c1fa596d983f4ae27" dependencies = [ - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "libc", "mach", "once_cell", @@ -3477,9 +3886,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.21" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -3555,7 +3964,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", ] [[package]] @@ -3578,9 +3987,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "10.6.0" +version = "10.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6823ea29436221176fe662da99998ad3b4db2c7f31e7b6f5fe43adccd6320bb" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" dependencies = [ "bitflags", ] @@ -3599,13 +4008,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-deque", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "num_cpus", ] @@ -3636,14 +4045,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.8", - "redox_syscall", + "getrandom 0.2.9", + "redox_syscall 0.2.16", "thiserror", ] @@ -3660,13 +4078,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -3675,14 +4093,20 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "region" @@ -3696,20 +4120,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" dependencies = [ "bytecheck", ] @@ -3768,9 +4183,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" dependencies = [ "bytecheck", "hashbrown 0.12.3", @@ -3782,13 +4197,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3815,9 +4230,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -3846,7 +4261,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver 1.0.17", +] + +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3909,9 +4338,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rusty-fork" @@ -3927,9 +4356,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "safe-proc-macro2" @@ -3989,19 +4418,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "scheduled-thread-pool" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ "parking_lot", ] @@ -4012,12 +4440,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - [[package]] name = "sct" version = "0.6.1" @@ -4057,6 +4479,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "secp256k1-sys 0.4.2", +] + [[package]] name = "secp256k1" version = "0.24.3" @@ -4065,10 +4496,19 @@ checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ "bitcoin_hashes", "rand 0.8.5", - "secp256k1-sys", + "secp256k1-sys 0.6.1", "serde", ] +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + [[package]] name = "secp256k1-sys" version = "0.6.1" @@ -4080,9 +4520,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -4093,9 +4533,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -4112,9 +4552,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" dependencies = [ "serde", ] @@ -4130,18 +4570,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.7" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ "serde", ] @@ -4158,20 +4598,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -4180,13 +4620,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -4237,9 +4677,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.6", "keccak", @@ -4256,9 +4696,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -4273,6 +4713,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "simple-error" version = "0.2.3" @@ -4296,9 +4742,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -4311,9 +4757,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -4367,7 +4813,20 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "subproductdomain" +version = "0.1.0" +source = "git+https://github.com/anoma/ferveo?rev=e5abd0acc938da90140351a65a26472eb495ce4d#e5abd0acc938da90140351a65a26472eb495ce4d" +dependencies = [ + "anyhow", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", ] [[package]] @@ -4393,9 +4852,9 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -4403,23 +4862,22 @@ dependencies = [ ] [[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", - "syn", - "unicode-xid", + "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "tagptr" version = "0.2.0" @@ -4434,28 +4892,27 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if 1.0.0", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] name = "tendermint" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "async-trait", "bytes", @@ -4513,7 +4970,7 @@ dependencies = [ [[package]] name = "tendermint-config" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "flex-error", "serde", @@ -4562,7 +5019,7 @@ dependencies = [ [[package]] name = "tendermint-light-client-verifier" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "derive_more", "flex-error", @@ -4587,7 +5044,7 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "bytes", "flex-error", @@ -4622,13 +5079,13 @@ dependencies = [ [[package]] name = "tendermint-rpc" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "async-trait", "bytes", "flex-error", "futures", - "getrandom 0.2.8", + "getrandom 0.2.9", "http", "hyper", "hyper-proxy", @@ -4662,7 +5119,7 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom 0.2.8", + "getrandom 0.2.9", "http", "hyper", "hyper-proxy", @@ -4688,7 +5145,7 @@ dependencies = [ [[package]] name = "tendermint-testgen" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "ed25519-dalek", "gumdrop", @@ -4716,15 +5173,6 @@ dependencies = [ "time", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "test-log" version = "0.2.11" @@ -4733,35 +5181,36 @@ checksum = "38f0c854faeb68a048f0f2dc410c5ddae3bf83854ef0e4977d58306a5edef50e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if 1.0.0", "once_cell", ] @@ -4830,20 +5279,19 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.21.2" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", "parking_lot", @@ -4851,7 +5299,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -4866,13 +5314,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -4899,9 +5347,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", "pin-project-lite", @@ -4910,9 +5358,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -4924,9 +5372,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -4939,9 +5387,9 @@ checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" [[package]] name = "toml_edit" -version = "0.19.4" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ "indexmap", "toml_datetime", @@ -4993,7 +5441,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -5016,25 +5464,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - [[package]] name = "tower-layer" version = "0.3.2" @@ -5062,20 +5491,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -5092,9 +5521,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "once_cell", @@ -5113,9 +5542,9 @@ checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" @@ -5143,7 +5572,7 @@ name = "tx_template" version = "0.15.3" dependencies = [ "borsh", - "getrandom 0.2.8", + "getrandom 0.2.9", "namada_tests", "namada_tx_prelude", "wee_alloc", @@ -5151,9 +5580,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -5163,9 +5592,9 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "uint" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45526d29728d135c2900b0d30573fe3ee79fceb12ef534c7bb30e810a91b601" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder", "crunchy 0.2.2", @@ -5190,15 +5619,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -5262,11 +5691,21 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", +] + +[[package]] +name = "value-bag" +version = "1.0.0-alpha.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +dependencies = [ + "ctor", + "version_check", ] [[package]] @@ -5280,7 +5719,7 @@ name = "vp_template" version = "0.15.3" dependencies = [ "borsh", - "getrandom 0.2.8", + "getrandom 0.2.9", "namada_tests", "namada_vp_prelude", "wee_alloc", @@ -5295,14 +5734,19 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -5336,9 +5780,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -5346,24 +5790,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.15", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5371,28 +5827,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-encoder" -version = "0.19.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9424cdab516a16d4ea03c8f4a01b14e7b2d04a129dcc2bcdde5bcc5f68f06c41" +checksum = "d05d0b6fcd0aeb98adf16e7975331b3c17222aa815148f5b976370ce589d80ef" dependencies = [ "leb128", ] @@ -5503,7 +5959,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -5611,7 +6067,7 @@ dependencies = [ "indexmap", "libc", "loupe", - "memoffset", + "memoffset 0.6.5", "more-asserts", "region", "rkyv", @@ -5635,9 +6091,9 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wast" -version = "49.0.0" +version = "57.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ef81fcd60d244cafffeafac3d17615fdb2fddda6aca18f34a8ae233353587c" +checksum = "6eb0f5ed17ac4421193c7477da05892c2edafd67f9639e3c11a82086416662dc" dependencies = [ "leb128", "memchr", @@ -5647,18 +6103,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.51" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c347c4460ffb311e95aafccd8c29e4888f241b9e4b3bb0e0ccbd998de2c8c0d" +checksum = "ab9ab0d87337c3be2bb6fc5cd331c4ba9fd6bcb4ee85048a0dd59ed9ecf92e53" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" dependencies = [ "js-sys", "wasm-bindgen", @@ -5707,9 +6163,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", @@ -5748,16 +6204,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets 0.48.0", ] [[package]] @@ -5766,92 +6218,152 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.3.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf09497b8f8b5ac5d3bb4d05c0a99be20f26fd3d5f2db7b0716e946d5103658" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" dependencies = [ "memchr", ] @@ -5914,8 +6426,8 @@ dependencies = [ "aes", "bip0039", "bitvec 0.22.3", - "blake2b_simd 1.0.0", - "blake2s_simd 1.0.0", + "blake2b_simd 1.0.1", + "blake2s_simd 1.0.1", "bls12_381", "byteorder", "chacha20poly1305", @@ -5944,7 +6456,7 @@ version = "0.5.0" source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ "bellman", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "bls12_381", "byteorder", "directories", @@ -5958,21 +6470,20 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.15", ] diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index de05a41f2c..2fd275d11b 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -14,16 +14,19 @@ borsh-derive = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223 borsh-derive-internal = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"} borsh-schema-derive-internal = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"} # patched to a commit on the `eth-bridge-integration+consensus-timeout` branch of our fork -tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} +tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} # patched to a commit on the `eth-bridge-integration` branch of our fork -ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "dcce4ac23d4d0a4324d23c54a1a99d41f0be2076"} -ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb"} +ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "2d7edc16412b60cabf78163fe24a6264e11f77a9"} +ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "7e527b5b8c95d83351e93ceafc14ac853224283f"} + +# patched to the yanked 1.2.0 until masp updates bitvec +funty = { git = "https://github.com/bitvecto-rs/funty/", rev = "7ef0d890fbcd8b3def1635ac1a877fc298488446" } [profile.release] # smaller and faster wasm (https://rustwasm.github.io/book/reference/code-size.html#compiling-with-link-time-optimizations-lto) diff --git a/wasm/checksums.json b/wasm/checksums.json index 5156181446..96ec20afa5 100644 --- a/wasm/checksums.json +++ b/wasm/checksums.json @@ -1,20 +1,20 @@ { - "tx_bond.wasm": "tx_bond.766c266dac74447b48fb5401f1f67edf436038b0292de40b7aafe8ad76903b74.wasm", - "tx_change_validator_commission.wasm": "tx_change_validator_commission.6989e7d9d25ee5fc29364c70e17ca266fd92611f3cca62012c24334e7cee67d4.wasm", - "tx_ibc.wasm": "tx_ibc.3e01ccbe6c5f539afbce2857b18d9a149f52332ff09021c8c2afdee1abed91ee.wasm", - "tx_init_account.wasm": "tx_init_account.09f02eadea696fe300eab95e0ce2d9d22e4d914c423d44156785a3ee7f64c9b9.wasm", - "tx_init_proposal.wasm": "tx_init_proposal.697028cf9388cfe6b89837371bc8167777ec9c22b0eca30d0729313e7660cb0f.wasm", - "tx_init_validator.wasm": "tx_init_validator.494e7067d4362aba561f237915966822228c2f41f0fb2b846f281c828d566b73.wasm", - "tx_reveal_pk.wasm": "tx_reveal_pk.a539cd4b6744a259dc9b9f3402affa0fec479d265bed39064e5fbee5f5bcf3eb.wasm", - "tx_transfer.wasm": "tx_transfer.52812e357c04decfc43d5b281f08757fec89dbbc6da6c76ff7584993fd412bc8.wasm", - "tx_unbond.wasm": "tx_unbond.c848a3d9474c76d7d45ca06bf78ed24262dd7a55975d52b96430f6c53208ede1.wasm", - "tx_update_vp.wasm": "tx_update_vp.bfcf8672a62187858551fc914b675a9dbfd581d65daffbbbebcedcc28f7aa339.wasm", - "tx_vote_proposal.wasm": "tx_vote_proposal.137a4e3473fd7230f7002a2ca57cd24a95a242268ab165d2ba00c23d69755169.wasm", - "tx_withdraw.wasm": "tx_withdraw.db024017a54ad3798dd05fdcab5db902cf9b12de904e7c8d633d4af7fa3326fd.wasm", - "vp_implicit.wasm": "vp_implicit.f20e20de62050eb8c81ef4ffdf6d1193595303520b528afe98247917c069450a.wasm", - "vp_masp.wasm": "vp_masp.dcdb00cd513d50033396fa88350b4a8ab4e707131b0c0006993f56224d33d599.wasm", - "vp_testnet_faucet.wasm": "vp_testnet_faucet.e2738bf3a7fa464380d7c0e7faa0ff216dc3986f8615c6b908191c7bb439654d.wasm", - "vp_token.wasm": "vp_token.9bfbe62310e60012afd333d2758b4a8cd74e948adb38afef93535e183c6b04ef.wasm", - "vp_user.wasm": "vp_user.11ef5db18c02a3760b9ba3f645ec215d182bcbcd7454586dca22d5bcab18e37c.wasm", - "vp_validator.wasm": "vp_validator.ab366db26b11d4f7d4e8bba912d8ca84ae49de93f8f5251d68c430b44e59ef1c.wasm" + "tx_bond.wasm": "tx_bond.88a929425f99c55daa19b61fe5f0705c1fde945ebb998e98ed1361c9a66d5b37.wasm", + "tx_change_validator_commission.wasm": "tx_change_validator_commission.08cb964e182c6403f8261ce0c381d2b24683310e62fc6412c3379e8ed2f96db1.wasm", + "tx_ibc.wasm": "tx_ibc.d1dc1ca394515105d07e7f0da9d4c2e48f27bc4cedd71300a49b2b67868dfde0.wasm", + "tx_init_account.wasm": "tx_init_account.a09ca05a0e67e20efb9cba6e1af07999ff4969b04126fbac049dcde336d2d2a0.wasm", + "tx_init_proposal.wasm": "tx_init_proposal.bab091b3ea111ae57ae9985a48e90f901776d18e08feb91cd9ff3546f89b01a2.wasm", + "tx_init_validator.wasm": "tx_init_validator.c9dcd475043a76e02aeaa649ea1175f95d9b56030acefb0c8d94d68fc9b6945e.wasm", + "tx_reveal_pk.wasm": "tx_reveal_pk.102b68342cccd7f41a38b83cdb2ac6f208fe7289a57adc91e28196efdf3f5805.wasm", + "tx_transfer.wasm": "tx_transfer.7e138d16b6abb093427bba152097e6558696f61b08be7d659b7d899218393930.wasm", + "tx_unbond.wasm": "tx_unbond.bf3bfab82fd5808cfb51f6e10f01c11641a8e05d57007a908287647302a01dca.wasm", + "tx_update_vp.wasm": "tx_update_vp.4b9950d863f2d764e33396e17edbc06b7a2c1e6b47eb2e09819ab3e646cdb518.wasm", + "tx_vote_proposal.wasm": "tx_vote_proposal.e6c166d7188cfacdc5ea0f62095c8a36f6e2eb790994d42b38f1d2959d91f944.wasm", + "tx_withdraw.wasm": "tx_withdraw.ab82116c3f0639f31d8bdb946cf2311dafddae1fc277c3942e30c75be3812fd7.wasm", + "vp_implicit.wasm": "vp_implicit.fc18b5ad2a884670dfb17cdf72ae7c5159fb31a9615f492992ab39aa5807818a.wasm", + "vp_masp.wasm": "vp_masp.d25b2ceed9e016c6ec0b39dfe6d9d7b1a0cfd2828f78bb27e0abdac46e87aee6.wasm", + "vp_testnet_faucet.wasm": "vp_testnet_faucet.9058366ab6ecdea0cbd720b7be550a3381d98b0b84a331c9b6f84978bf774ff7.wasm", + "vp_token.wasm": "vp_token.05b4dc03a9f0d64045df07e99d0ffdcacbe2e9e966eef8cbcfe025b7ccdb3b55.wasm", + "vp_user.wasm": "vp_user.3bc306a99e30a7847152f82002dd2faf25ff0f64d1100efa6ccad576705dd968.wasm", + "vp_validator.wasm": "vp_validator.112db733a8a5e497987b087b842105ea9b93e1644b6afdb1b8aaac0cfef3b66c.wasm" } \ No newline at end of file diff --git a/wasm/wasm_source/Cargo.toml b/wasm/wasm_source/Cargo.toml index 5a8d2e9245..ddfd56d102 100644 --- a/wasm/wasm_source/Cargo.toml +++ b/wasm/wasm_source/Cargo.toml @@ -37,7 +37,7 @@ namada_tx_prelude = {path = "../../tx_prelude", optional = true} namada_vp_prelude = {path = "../../vp_prelude", optional = true} borsh = "0.9.0" once_cell = {version = "1.8.0", optional = true} -rust_decimal = {version = "1.26.1", optional = true} +rust_decimal = {version = "=1.26.1", optional = true} wee_alloc = "0.4.5" getrandom = { version = "0.2", features = ["custom"] } masp_proofs = { git = "https://github.com/anoma/masp", rev = "bee40fc465f6afbd10558d12fe96eb1742eee45c", optional = true } diff --git a/wasm_for_tests/wasm_source/Cargo.lock b/wasm_for_tests/wasm_source/Cargo.lock index 597695235b..1eb2d81a31 100644 --- a/wasm_for_tests/wasm_source/Cargo.lock +++ b/wasm_for_tests/wasm_source/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.17.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ - "gimli 0.26.2", + "gimli 0.27.2", ] [[package]] @@ -44,16 +44,16 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.19" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "ark-bls12-381" @@ -98,6 +98,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ed-on-bls12-381" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b7ada17db3854f5994e74e60b18e10e818594935ee7e1d329800c117b32970" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-std", +] + [[package]] name = "ark-ff" version = "0.3.0" @@ -123,7 +135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -135,7 +147,20 @@ dependencies = [ "num-bigint", "num-traits", "quote", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0f78f47537c2f15706db7e98fe64cc1711dbf9def81218194e17239e53e5aa" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.11.2", ] [[package]] @@ -157,7 +182,7 @@ checksum = "8dd4e5f0bf8285d5ed538d27fab7411f3e297908fd93c62195de8bee3f199e82" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -172,9 +197,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" @@ -188,36 +213,138 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" +[[package]] +name = "async-channel" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-executor" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +dependencies = [ + "async-channel", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-std" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +dependencies = [ + "async-channel", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils 0.8.15", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + [[package]] name = "async-stream" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" dependencies = [ "async-stream-impl", "futures-core", + "pin-project-lite", ] [[package]] name = "async-stream-impl" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + [[package]] name = "async-trait" -version = "0.1.58" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e805d94e6b5001b651426cf4cd446b1ab5f319d27bab5c644f61de0a804360c" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -236,6 +363,12 @@ dependencies = [ "tungstenite", ] +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + [[package]] name = "autocfg" version = "1.1.0" @@ -244,9 +377,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.7" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fb79c228270dcf2426e74864cabc94babb5dbab01a4314e702d2f16540e1591" +checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" dependencies = [ "async-trait", "axum-core", @@ -266,16 +399,15 @@ dependencies = [ "serde", "sync_wrapper", "tower", - "tower-http", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ "async-trait", "bytes", @@ -290,16 +422,16 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", - "object 0.29.0", + "object 0.30.3", "rustc-demangle", ] @@ -348,7 +480,7 @@ dependencies = [ "bitvec 0.22.3", "blake2s_simd 0.5.11", "byteorder", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "ff 0.11.1", "group 0.11.0", "lazy_static", @@ -370,6 +502,24 @@ dependencies = [ "crunchy 0.1.6", ] +[[package]] +name = "bimap" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bip0039" version = "0.9.0" @@ -407,7 +557,7 @@ checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" dependencies = [ "bech32 0.9.1", "bitcoin_hashes", - "secp256k1", + "secp256k1 0.24.3", "serde", ] @@ -450,6 +600,15 @@ dependencies = [ "wyz 0.5.1", ] +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.6", +] + [[package]] name = "blake2b_simd" version = "0.5.11" @@ -458,18 +617,18 @@ checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake2b_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72936ee4afc7f8f736d1c38383b56480b5497b4617b4a77bdbf1d2ababc76127" +checksum = "3c2f0dc9a68c6317d884f97cc36cf5a3d20ba14ce404227df55e1af708ab04bc" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.2.5", ] [[package]] @@ -480,31 +639,31 @@ checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" dependencies = [ "arrayref", "arrayvec 0.5.2", - "constant_time_eq", + "constant_time_eq 0.1.5", ] [[package]] name = "blake2s_simd" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db539cc2b5f6003621f1cd9ef92d7ded8ea5232c7de0f9faa2de251cd98730d4" +checksum = "6637f448b9e61dfadbdcbae9a885fadee1f3eaffb1f8d3c1965d3ade8bdfd44f" dependencies = [ "arrayref", "arrayvec 0.7.2", - "constant_time_eq", + "constant_time_eq 0.2.5", ] [[package]] name = "blake3" -version = "1.3.1" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +checksum = "42ae2468a89544a466886840aa467a25b766499f4f04bf7d9fcd10ecee9fccef" dependencies = [ "arrayref", "arrayvec 0.7.2", "cc", "cfg-if 1.0.0", - "constant_time_eq", + "constant_time_eq 0.2.5", "digest 0.10.6", ] @@ -519,9 +678,9 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] @@ -542,6 +701,21 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + [[package]] name = "bls12_381" version = "0.6.1" @@ -573,7 +747,7 @@ dependencies = [ "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -583,7 +757,7 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -593,7 +767,7 @@ source = "git+https://github.com/heliaxdev/borsh-rs.git?rev=cd5223e5103c4f139e0c dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -604,9 +778,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" [[package]] name = "byte-slice-cast" @@ -616,23 +790,24 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -658,9 +833,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.1" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ad0e1e3e88dd237a156ab9f571021b8a158caa0ae44b1968a241efb5144c1e" +checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" dependencies = [ "serde", ] @@ -682,16 +857,16 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.14", + "semver 1.0.17", "serde", "serde_json", ] [[package]] name = "cc" -version = "1.0.76" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a284da2e6fe2092f2353e51713435363112dfd60030e22add80be333fb928f" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" @@ -732,9 +907,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "4e3c5919066adf22df73762e50cffcde3a758f2a848b113b586d1f86728b673b" dependencies = [ "iana-time-zone", "num-integer", @@ -766,23 +941,22 @@ version = "0.5.0" source = "git+https://github.com/marmeladema/clru-rs.git?rev=71ca566#71ca566915f21f3c308091ca7756a91b0f8b5afc" [[package]] -name = "codespan-reporting" -version = "0.11.1" +name = "concat-idents" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832" dependencies = [ - "termcolor", - "unicode-width", + "quote", + "syn 1.0.109", ] [[package]] -name = "concat-idents" -version = "1.1.4" +name = "concurrent-queue" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fe0e1d9f7de897d18e590a7496b5facbe87813f746cf4b8db596ba77e07e832" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" dependencies = [ - "quote", - "syn", + "crossbeam-utils 0.8.15", ] [[package]] @@ -797,6 +971,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +[[package]] +name = "constant_time_eq" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13418e745008f7349ec7e449155f419a61b92b58a99cc3616942b926825ec76b" + [[package]] name = "contracts" version = "0.6.3" @@ -805,7 +985,7 @@ checksum = "f1d1429e3bd78171c65aa010eabcdf8f863ba3254728dbfb0ad4b1545beac15c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -820,15 +1000,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -914,35 +1094,35 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if 1.0.0", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", ] [[package]] name = "crossbeam-epoch" -version = "0.9.11" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if 1.0.0", - "crossbeam-utils 0.8.12", - "memoffset", + "crossbeam-utils 0.8.15", + "memoffset 0.8.0", "scopeguard", ] @@ -959,9 +1139,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if 1.0.0", ] @@ -1035,6 +1215,12 @@ dependencies = [ "crypto_api", ] +[[package]] +name = "ct-codecs" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" + [[package]] name = "ct-logs" version = "0.8.0" @@ -1044,6 +1230,16 @@ dependencies = [ "sct 0.6.1", ] +[[package]] +name = "ctor" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -1070,55 +1266,11 @@ dependencies = [ "zeroize", ] -[[package]] -name = "cxx" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888" -dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", -] - -[[package]] -name = "cxx-build" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3" -dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", -] - -[[package]] -name = "cxxbridge-flags" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f" - -[[package]] -name = "cxxbridge-macro" -version = "1.0.81" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "darling" -version = "0.14.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ "darling_core", "darling_macro", @@ -1126,33 +1278,33 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "data-encoding" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" +checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb" [[package]] name = "der" @@ -1177,7 +1329,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1188,7 +1340,7 @@ checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1206,7 +1358,7 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", "crypto-common", "subtle", ] @@ -1254,13 +1406,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1281,7 +1433,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1340,6 +1492,7 @@ checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek", "ed25519", + "merlin", "rand 0.7.3", "serde", "serde_bytes", @@ -1361,9 +1514,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -1401,28 +1554,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1430,7 +1583,7 @@ name = "equihash" version = "0.1.0" source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "byteorder", ] @@ -1443,6 +1596,27 @@ dependencies = [ "serde", ] +[[package]] +name = "errno" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "error-chain" version = "0.12.4" @@ -1452,6 +1626,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "eyre" version = "0.6.8" @@ -1470,13 +1650,50 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] +[[package]] +name = "ferveo" +version = "0.1.1" +source = "git+https://github.com/anoma/ferveo?rev=e5abd0acc938da90140351a65a26472eb495ce4d#e5abd0acc938da90140351a65a26472eb495ce4d" +dependencies = [ + "anyhow", + "ark-bls12-381", + "ark-ec", + "ark-ed-on-bls12-381", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "bincode", + "blake2", + "blake2b_simd 1.0.1", + "borsh", + "digest 0.10.6", + "ed25519-dalek", + "either", + "ferveo-common", + "group-threshold-cryptography", + "hex", + "itertools", + "measure_time", + "miracl_core", + "num", + "rand 0.7.3", + "rand 0.8.5", + "serde", + "serde_bytes", + "serde_json", + "subproductdomain", + "subtle", + "zeroize", +] + [[package]] name = "ferveo-common" version = "0.1.0" @@ -1571,8 +1788,7 @@ dependencies = [ [[package]] name = "funty" version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" +source = "git+https://github.com/bitvecto-rs/funty/?rev=7ef0d890fbcd8b3def1635ac1a877fc298488446#7ef0d890fbcd8b3def1635ac1a877fc298488446" [[package]] name = "funty" @@ -1582,9 +1798,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", @@ -1597,9 +1813,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", "futures-sink", @@ -1607,15 +1823,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-executor" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" dependencies = [ "futures-core", "futures-task", @@ -1624,38 +1840,53 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d422fa3cbe3b40dca574ab087abb5bc98258ea57eea3fd6f1fa7162c778b91" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] [[package]] name = "futures-macro" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "futures-sink" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" [[package]] name = "futures-task" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" [[package]] name = "futures-util" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ "futures-channel", "futures-core", @@ -1671,9 +1902,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1692,9 +1923,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -1716,15 +1947,27 @@ dependencies = [ [[package]] name = "gimli" -version = "0.26.2" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "glob" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] [[package]] name = "group" @@ -1749,6 +1992,30 @@ dependencies = [ "subtle", ] +[[package]] +name = "group-threshold-cryptography" +version = "0.1.0" +source = "git+https://github.com/anoma/ferveo?rev=e5abd0acc938da90140351a65a26472eb495ce4d#e5abd0acc938da90140351a65a26472eb495ce4d" +dependencies = [ + "anyhow", + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "blake2b_simd 1.0.1", + "chacha20", + "hex", + "itertools", + "miracl_core", + "rand 0.8.5", + "rand_core 0.6.4", + "rayon", + "subproductdomain", + "thiserror", +] + [[package]] name = "gumdrop" version = "0.8.1" @@ -1766,14 +2033,14 @@ checksum = "729f9bd3449d77e7831a18abfb7ba2f99ee813dfd15b8c2167c9a54ba20aa99d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "h2" -version = "0.3.15" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -1828,9 +2095,9 @@ dependencies = [ [[package]] name = "hdpath" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dafb09e5d85df264339ad786a147d9de1da13687a3697c52244297e5e7c32d9c" +checksum = "09ae1615f843ce3981b47468f3f7c435ac17deb33c2261e64d7f1e87f5c11acc" dependencies = [ "byteorder", ] @@ -1868,13 +2135,19 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -1923,9 +2196,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -1943,12 +2216,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "http-range-header" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" - [[package]] name = "httparse" version = "1.8.0" @@ -1979,9 +2246,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.23" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", @@ -2052,32 +2319,31 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "winapi", + "windows", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "cxx", - "cxx-build", + "cc", ] [[package]] name = "ibc" version = "0.36.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=dcce4ac23d4d0a4324d23c54a1a99d41f0be2076#dcce4ac23d4d0a4324d23c54a1a99d41f0be2076" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs.git?rev=2d7edc16412b60cabf78163fe24a6264e11f77a9#2d7edc16412b60cabf78163fe24a6264e11f77a9" dependencies = [ "bytes", "cfg-if 1.0.0", @@ -2125,7 +2391,7 @@ dependencies = [ [[package]] name = "ibc-proto" version = "0.26.0" -source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb#acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb" +source = "git+https://github.com/heliaxdev/ibc-proto-rs.git?rev=7e527b5b8c95d83351e93ceafc14ac853224283f#7e527b5b8c95d83351e93ceafc14ac853224283f" dependencies = [ "base64 0.13.1", "bytes", @@ -2148,7 +2414,7 @@ dependencies = [ "bitcoin", "bs58", "bytes", - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "digest 0.10.6", "dirs-next", "ed25519", @@ -2172,8 +2438,8 @@ dependencies = [ "regex", "retry", "ripemd", - "secp256k1", - "semver 1.0.14", + "secp256k1 0.24.3", + "semver 1.0.17", "serde", "serde_derive", "serde_json", @@ -2192,7 +2458,7 @@ dependencies = [ "toml", "tonic", "tracing", - "uuid 1.2.1", + "uuid 1.3.2", ] [[package]] @@ -2283,7 +2549,7 @@ checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2312,9 +2578,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", @@ -2328,6 +2594,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" +dependencies = [ + "hermit-abi 0.3.1", + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -2341,15 +2621,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "68c16e1bfd491478ab155fd8b4896b86f9ede344949b641e61501e07c2b8b4d5" dependencies = [ "wasm-bindgen", ] @@ -2382,9 +2662,21 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] [[package]] name = "lazy_static" @@ -2400,9 +2692,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.144" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" [[package]] name = "libloading" @@ -2465,13 +2757,10 @@ dependencies = [ ] [[package]] -name = "link-cplusplus" -version = "1.0.7" +name = "linux-raw-sys" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" -dependencies = [ - "cc", -] +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "lock_api" @@ -2490,6 +2779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if 1.0.0", + "value-bag", ] [[package]] @@ -2510,7 +2800,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" dependencies = [ "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2530,8 +2820,8 @@ dependencies = [ "aes", "bip0039", "bitvec 0.22.3", - "blake2b_simd 1.0.0", - "blake2s_simd 1.0.0", + "blake2b_simd 1.0.1", + "blake2s_simd 1.0.1", "bls12_381", "borsh", "byteorder", @@ -2546,6 +2836,8 @@ dependencies = [ "lazy_static", "rand 0.8.5", "rand_core 0.6.4", + "ripemd160", + "secp256k1 0.20.3", "serde", "sha2 0.9.9", "subtle", @@ -2559,7 +2851,7 @@ version = "0.5.0" source = "git+https://github.com/anoma/masp?rev=bee40fc465f6afbd10558d12fe96eb1742eee45c#bee40fc465f6afbd10558d12fe96eb1742eee45c" dependencies = [ "bellman", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "bls12_381", "byteorder", "directories", @@ -2595,6 +2887,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +[[package]] +name = "measure_time" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56220900f1a0923789ecd6bf25fbae8af3b2f1ff3e9e297fc9b6b8674dd4d852" +dependencies = [ + "instant", + "log", +] + [[package]] name = "memchr" version = "2.5.0" @@ -2603,9 +2905,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] @@ -2619,6 +2921,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "memory_units" version = "0.4.0" @@ -2634,42 +2945,60 @@ dependencies = [ "nonempty", ] +[[package]] +name = "merlin" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e261cf0f8b3c42ded9f7d2bb59dea03aa52bc8a1cbc7482f9fc3fd1229d3b42" +dependencies = [ + "byteorder", + "keccak", + "rand_core 0.5.1", + "zeroize", +] + [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.5.4" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" dependencies = [ "adler", ] [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] +[[package]] +name = "miracl_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94c7128ba23c81f6471141b90f17654f89ef44a56e14b8a4dd0fddfccd655277" + [[package]] name = "moka" version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b9268097a2cf211ac9955b1cc95e80fa84fff5c2d13ba292916445dc8a311f" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-epoch", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "num_cpus", "once_cell", "parking_lot", @@ -2681,7 +3010,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.2.1", + "uuid 1.3.2", ] [[package]] @@ -2700,8 +3029,10 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" name = "namada" version = "0.15.3" dependencies = [ + "async-std", "async-trait", "bellman", + "bimap", "bls12_381", "borsh", "circular-queue", @@ -2716,20 +3047,27 @@ dependencies = [ "masp_proofs", "namada_core", "namada_proof_of_stake", + "orion", "parity-wasm", "paste", "proptest", "prost", "pwasm-utils", + "rand 0.8.5", + "rand_core 0.6.4", "rayon", "rust_decimal", "rust_decimal_macros", + "serde", "serde_json", "sha2 0.9.9", "tempfile", "tendermint 0.23.6", "tendermint-proto 0.23.6", + "tendermint-rpc 0.23.6", "thiserror", + "tokio", + "toml", "tracing", "wasmer", "wasmer-cache", @@ -2746,6 +3084,7 @@ name = "namada_core" version = "0.15.3" dependencies = [ "ark-bls12-381", + "ark-ec", "ark-serialize", "bech32 0.8.1", "bellman", @@ -2754,7 +3093,9 @@ dependencies = [ "data-encoding", "derivative", "ed25519-consensus", + "ferveo", "ferveo-common", + "group-threshold-cryptography", "ibc", "ibc-proto 0.26.0", "ics23", @@ -2789,7 +3130,7 @@ version = "0.15.3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2893,7 +3234,7 @@ name = "namada_wasm_for_tests" version = "0.15.3" dependencies = [ "borsh", - "getrandom 0.2.8", + "getrandom 0.2.9", "namada_test_utils", "namada_tests", "namada_tx_prelude", @@ -2907,6 +3248,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" +[[package]] +name = "num" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -2919,6 +3274,15 @@ dependencies = [ "serde", ] +[[package]] +name = "num-complex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02e0d21255c828d6f128a1e41534206671e8c3ea0c62f32291e808dc82cff17d" +dependencies = [ + "num-traits", +] + [[package]] name = "num-derive" version = "0.3.3" @@ -2927,7 +3291,7 @@ checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -2940,6 +3304,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-rational" version = "0.4.1" @@ -2965,11 +3340,11 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" dependencies = [ - "hermit-abi", + "hermit-abi 0.2.6", "libc", ] @@ -2987,18 +3362,18 @@ dependencies = [ [[package]] name = "object" -version = "0.29.0" +version = "0.30.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opaque-debug" @@ -3022,7 +3397,7 @@ dependencies = [ "arrayvec 0.7.2", "bigint", "bitvec 0.22.3", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "ff 0.11.1", "fpe", "group 0.11.0", @@ -3039,6 +3414,18 @@ dependencies = [ "zcash_note_encryption 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "orion" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c" +dependencies = [ + "ct-codecs", + "getrandom 0.2.9", + "subtle", + "zeroize", +] + [[package]] name = "pairing" version = "0.21.0" @@ -3050,9 +3437,9 @@ dependencies = [ [[package]] name = "parity-scale-codec" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637935964ff85a605d114591d4d2c13c5d1ba2806dae97cea6bf180238a749ac" +checksum = "5ddb756ca205bd108aee3c62c6d3c994e1df84a59b9d6d4a5ea42ee1fd5a9a28" dependencies = [ "arrayvec 0.7.2", "bitvec 1.0.1", @@ -3071,7 +3458,7 @@ dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3080,6 +3467,12 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1ad0aff30c1da14b1254fcb2af73e1fa9a28670e584a626f53a369d0e157304" +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + [[package]] name = "parking_lot" version = "0.12.1" @@ -3092,15 +3485,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.4" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -3131,9 +3524,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1" +checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" [[package]] name = "pbkdf2" @@ -3189,9 +3582,9 @@ checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" [[package]] name = "pest" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a528564cc62c19a7acac4d81e01f39e53e25e17b934878f4c6d25cc2836e62f8" +checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" dependencies = [ "thiserror", "ucd-trie", @@ -3199,9 +3592,9 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", "indexmap", @@ -3224,7 +3617,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3239,6 +3632,22 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if 1.0.0", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + [[package]] name = "poly1305" version = "0.7.2" @@ -3263,7 +3672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ "proc-macro2", - "syn", + "syn 1.0.109", ] [[package]] @@ -3306,7 +3715,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -3323,9 +3732,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] @@ -3343,7 +3752,7 @@ dependencies = [ "rand 0.8.5", "rand_chacha 0.3.1", "rand_xorshift", - "regex-syntax", + "regex-syntax 0.6.29", "rusty-fork", "tempfile", "unarray", @@ -3351,9 +3760,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48e50df39172a3e7eb17e14642445da64996989bc212b583015435d39a58537" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", "prost-derive", @@ -3361,9 +3770,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c828f93f5ca4826f97fedcbd3f9a536c16b12cff3dbbb4a007f932bbad95b12" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck", @@ -3376,29 +3785,29 @@ dependencies = [ "prost", "prost-types", "regex", - "syn", + "syn 1.0.109", "tempfile", "which", ] [[package]] name = "prost-derive" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea9b0f8cbe5e15a8a042d030bd96668db28ecb567ec37d691971ff5731d2b1b" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "prost-types" -version = "0.11.8" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379119666929a1afd7a043aa6cf96fa67a6dce9af60c88095a4686dbce4c9c88" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ "prost", ] @@ -3420,7 +3829,7 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3450,7 +3859,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e31331286705f455e56cca62e0e717158474ff02b7936c1fa596d983f4ae27" dependencies = [ - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "libc", "mach", "once_cell", @@ -3468,9 +3877,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.21" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -3546,7 +3955,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", ] [[package]] @@ -3569,9 +3978,9 @@ dependencies = [ [[package]] name = "raw-cpuid" -version = "10.6.0" +version = "10.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6823ea29436221176fe662da99998ad3b4db2c7f31e7b6f5fe43adccd6320bb" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" dependencies = [ "bitflags", ] @@ -3590,13 +3999,13 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.3" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ - "crossbeam-channel 0.5.6", + "crossbeam-channel 0.5.8", "crossbeam-deque", - "crossbeam-utils 0.8.12", + "crossbeam-utils 0.8.15", "num_cpus", ] @@ -3627,14 +4036,23 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_users" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ - "getrandom 0.2.8", - "redox_syscall", + "getrandom 0.2.9", + "redox_syscall 0.2.16", "thiserror", ] @@ -3651,13 +4069,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -3666,14 +4084,20 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.29", ] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "region" @@ -3687,20 +4111,11 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" dependencies = [ "bytecheck", ] @@ -3759,9 +4174,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" dependencies = [ "bytecheck", "hashbrown 0.12.3", @@ -3773,13 +4188,13 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -3806,9 +4221,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -3837,7 +4252,21 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.14", + "semver 1.0.17", +] + +[[package]] +name = "rustix" +version = "0.37.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3900,9 +4329,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rusty-fork" @@ -3918,9 +4347,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "safe-proc-macro2" @@ -3980,19 +4409,18 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] name = "scheduled-thread-pool" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ "parking_lot", ] @@ -4003,12 +4431,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "scratch" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" - [[package]] name = "sct" version = "0.6.1" @@ -4048,6 +4470,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "secp256k1-sys 0.4.2", +] + [[package]] name = "secp256k1" version = "0.24.3" @@ -4056,10 +4487,19 @@ checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ "bitcoin_hashes", "rand 0.8.5", - "secp256k1-sys", + "secp256k1-sys 0.6.1", "serde", ] +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + [[package]] name = "secp256k1-sys" version = "0.6.1" @@ -4071,9 +4511,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.7.0" +version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" dependencies = [ "bitflags", "core-foundation", @@ -4084,9 +4524,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.6.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" dependencies = [ "core-foundation-sys", "libc", @@ -4103,9 +4543,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" dependencies = [ "serde", ] @@ -4121,18 +4561,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.147" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +checksum = "2113ab51b87a539ae008b5c6c02dc020ffa39afd2d83cffcb3f4eb2722cebec2" dependencies = [ "serde_derive", ] [[package]] name = "serde_bytes" -version = "0.11.7" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" dependencies = [ "serde", ] @@ -4149,20 +4589,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.147" +version = "1.0.163" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +checksum = "8c805777e3930c8883389c602315a24224bcc738b63905ef87cd1420353ea93e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.87" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -4171,13 +4611,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fe39d9fbb0ebf5eb2c7cb7e2a47e4f462fad1379f1166b8ae49ad9eae89a7ca" +checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -4228,9 +4668,9 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.6", "keccak", @@ -4247,9 +4687,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] @@ -4264,6 +4704,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + [[package]] name = "simple-error" version = "0.2.3" @@ -4287,9 +4733,9 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -4302,9 +4748,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -4358,7 +4804,20 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", +] + +[[package]] +name = "subproductdomain" +version = "0.1.0" +source = "git+https://github.com/anoma/ferveo?rev=e5abd0acc938da90140351a65a26472eb495ce4d#e5abd0acc938da90140351a65a26472eb495ce4d" +dependencies = [ + "anyhow", + "ark-ec", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", ] [[package]] @@ -4384,9 +4843,9 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "syn" -version = "1.0.103" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -4394,23 +4853,22 @@ dependencies = [ ] [[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "synstructure" -version = "0.12.6" +name = "syn" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", - "syn", - "unicode-xid", + "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "tagptr" version = "0.2.0" @@ -4425,28 +4883,27 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" dependencies = [ "cfg-if 1.0.0", "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", + "redox_syscall 0.3.5", + "rustix", + "windows-sys 0.45.0", ] [[package]] name = "tendermint" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "async-trait", "bytes", @@ -4504,7 +4961,7 @@ dependencies = [ [[package]] name = "tendermint-config" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "flex-error", "serde", @@ -4553,7 +5010,7 @@ dependencies = [ [[package]] name = "tendermint-light-client-verifier" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "derive_more", "flex-error", @@ -4578,7 +5035,7 @@ dependencies = [ [[package]] name = "tendermint-proto" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "bytes", "flex-error", @@ -4613,13 +5070,13 @@ dependencies = [ [[package]] name = "tendermint-rpc" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "async-trait", "bytes", "flex-error", "futures", - "getrandom 0.2.8", + "getrandom 0.2.9", "http", "hyper", "hyper-proxy", @@ -4653,7 +5110,7 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom 0.2.8", + "getrandom 0.2.9", "http", "hyper", "hyper-proxy", @@ -4679,7 +5136,7 @@ dependencies = [ [[package]] name = "tendermint-testgen" version = "0.23.6" -source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=a2cd889ae706854e7bf476880a37408d75b4a8e1#a2cd889ae706854e7bf476880a37408d75b4a8e1" +source = "git+https://github.com/heliaxdev/tendermint-rs.git?rev=4db3c5ea09fae4057008d22bf9e96bf541b55b35#4db3c5ea09fae4057008d22bf9e96bf541b55b35" dependencies = [ "ed25519-dalek", "gumdrop", @@ -4707,15 +5164,6 @@ dependencies = [ "time", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - [[package]] name = "test-log" version = "0.2.11" @@ -4724,35 +5172,36 @@ checksum = "38f0c854faeb68a048f0f2dc410c5ddae3bf83854ef0e4977d58306a5edef50e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "thiserror" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "thread_local" -version = "1.1.4" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" dependencies = [ + "cfg-if 1.0.0", "once_cell", ] @@ -4821,20 +5270,19 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.21.2" +version = "1.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" +checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105" dependencies = [ "autocfg", "bytes", "libc", - "memchr", "mio", "num_cpus", "parking_lot", @@ -4842,7 +5290,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -4857,13 +5305,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.8.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -4890,9 +5338,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" dependencies = [ "futures-core", "pin-project-lite", @@ -4901,9 +5349,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -4915,9 +5363,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] @@ -4930,9 +5378,9 @@ checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" [[package]] name = "toml_edit" -version = "0.19.6" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08de71aa0d6e348f070457f85af8bd566e2bc452156a423ddf22861b3a953fae" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" dependencies = [ "indexmap", "toml_datetime", @@ -4984,7 +5432,7 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -5007,25 +5455,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - [[package]] name = "tower-layer" version = "0.3.2" @@ -5053,20 +5482,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" dependencies = [ "once_cell", ] @@ -5083,9 +5512,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" dependencies = [ "matchers", "once_cell", @@ -5104,9 +5533,9 @@ checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "tungstenite" @@ -5131,9 +5560,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] name = "ucd-trie" @@ -5143,9 +5572,9 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" [[package]] name = "uint" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45526d29728d135c2900b0d30573fe3ee79fceb12ef534c7bb30e810a91b601" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" dependencies = [ "byteorder", "crunchy 0.2.2", @@ -5170,15 +5599,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -5242,11 +5671,21 @@ checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" [[package]] name = "uuid" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb41e78f93363bb2df8b0e86a2ca30eed7806ea16ea0c790d757cf93f79be83" +checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2" dependencies = [ - "getrandom 0.2.8", + "getrandom 0.2.9", +] + +[[package]] +name = "value-bag" +version = "1.0.0-alpha.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +dependencies = [ + "ctor", + "version_check", ] [[package]] @@ -5264,14 +5703,19 @@ dependencies = [ "libc", ] +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "walkdir" -version = "2.3.2" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -5305,9 +5749,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "5b6cb788c4e39112fbe1822277ef6fb3c55cd86b95cb3d3c4c1c9597e4ac74b4" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -5315,24 +5759,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "35e522ed4105a9d626d885b35d62501b30d9666283a5c8be12c14a8bdafe7822" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.15", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "083abe15c5d88556b77bdf7aef403625be9e327ad37c62c4e4129af740168163" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "358a79a0cb89d21db8120cbfb91392335913e4890665b1a7981d9e956903b434" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5340,28 +5796,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "4783ce29f09b9d93134d41297aded3a712b7b979e9c6f28c32cb88c973a94869" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" [[package]] name = "wasm-encoder" -version = "0.19.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9424cdab516a16d4ea03c8f4a01b14e7b2d04a129dcc2bcdde5bcc5f68f06c41" +checksum = "d05d0b6fcd0aeb98adf16e7975331b3c17222aa815148f5b976370ce589d80ef" dependencies = [ "leb128", ] @@ -5472,7 +5928,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -5580,7 +6036,7 @@ dependencies = [ "indexmap", "libc", "loupe", - "memoffset", + "memoffset 0.6.5", "more-asserts", "region", "rkyv", @@ -5604,9 +6060,9 @@ checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" [[package]] name = "wast" -version = "49.0.0" +version = "57.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05ef81fcd60d244cafffeafac3d17615fdb2fddda6aca18f34a8ae233353587c" +checksum = "6eb0f5ed17ac4421193c7477da05892c2edafd67f9639e3c11a82086416662dc" dependencies = [ "leb128", "memchr", @@ -5616,18 +6072,18 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.51" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c347c4460ffb311e95aafccd8c29e4888f241b9e4b3bb0e0ccbd998de2c8c0d" +checksum = "ab9ab0d87337c3be2bb6fc5cd331c4ba9fd6bcb4ee85048a0dd59ed9ecf92e53" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "16b5f940c7edfdc6d12126d98c9ef4d1b3d470011c47c76a6581df47ad9ba721" dependencies = [ "js-sys", "wasm-bindgen", @@ -5676,9 +6132,9 @@ dependencies = [ [[package]] name = "which" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ "either", "libc", @@ -5717,16 +6173,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows-sys" -version = "0.36.1" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", + "windows-targets 0.48.0", ] [[package]] @@ -5735,92 +6187,152 @@ version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.3.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee7b2c67f962bf5042bfd8b6a916178df33a26eec343ae064cb8e069f638fa6f" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" dependencies = [ "memchr", ] @@ -5883,8 +6395,8 @@ dependencies = [ "aes", "bip0039", "bitvec 0.22.3", - "blake2b_simd 1.0.0", - "blake2s_simd 1.0.0", + "blake2b_simd 1.0.1", + "blake2s_simd 1.0.1", "bls12_381", "byteorder", "chacha20poly1305", @@ -5913,7 +6425,7 @@ version = "0.5.0" source = "git+https://github.com/zcash/librustzcash/?rev=2425a08#2425a0869098e3b0588ccd73c42716bcf418612c" dependencies = [ "bellman", - "blake2b_simd 1.0.0", + "blake2b_simd 1.0.1", "bls12_381", "byteorder", "directories", @@ -5927,21 +6439,20 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] [[package]] name = "zeroize_derive" -version = "1.3.2" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn", - "synstructure", + "syn 2.0.15", ] diff --git a/wasm_for_tests/wasm_source/Cargo.toml b/wasm_for_tests/wasm_source/Cargo.toml index ab389f04fe..09e3316f33 100644 --- a/wasm_for_tests/wasm_source/Cargo.toml +++ b/wasm_for_tests/wasm_source/Cargo.toml @@ -39,16 +39,19 @@ borsh-derive = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223 borsh-derive-internal = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"} borsh-schema-derive-internal = {git = "https://github.com/heliaxdev/borsh-rs.git", rev = "cd5223e5103c4f139e0c54cf8259b7ec5ec4073a"} # patched to a commit on the `eth-bridge-integration+consensus-timeout` branch of our fork -tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} -tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "a2cd889ae706854e7bf476880a37408d75b4a8e1"} +tendermint = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-config = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-proto = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-rpc = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-testgen = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} +tendermint-light-client-verifier = {git = "https://github.com/heliaxdev/tendermint-rs.git", rev = "4db3c5ea09fae4057008d22bf9e96bf541b55b35"} # patched to a commit on the `eth-bridge-integration` branch of our fork -ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "dcce4ac23d4d0a4324d23c54a1a99d41f0be2076"} -ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "acc378e5e1865fbf559fa4e36e3c2b0dc1da51bb"} +ibc = {git = "https://github.com/heliaxdev/cosmos-ibc-rs.git", rev = "2d7edc16412b60cabf78163fe24a6264e11f77a9"} +ibc-proto = {git = "https://github.com/heliaxdev/ibc-proto-rs.git", rev = "7e527b5b8c95d83351e93ceafc14ac853224283f"} + +# patched to the yanked 1.2.0 until masp updates bitvec +funty = { git = "https://github.com/bitvecto-rs/funty/", rev = "7ef0d890fbcd8b3def1635ac1a877fc298488446" } [dev-dependencies] namada_tests = {path = "../../tests"}