From 02a99e0888c702e28bbb8ae451123d8665aae3e1 Mon Sep 17 00:00:00 2001 From: Gianmarco Fraccaroli Date: Wed, 21 Aug 2024 15:24:26 +0200 Subject: [PATCH] added shield txs --- .github/workflows/build-and-push.yml | 2 +- Cargo.lock | 445 ++++++++++++++----------- Cargo.toml | 1 + local_run.sh | 4 +- src/checks/reveal_pk.rs | 2 +- src/entity/address.rs | 42 ++- src/gen/entity.rs | 54 +++ src/gen/hooks/mod.rs | 1 + src/gen/hooks/shielded_sync.rs | 32 ++ src/gen/main.rs | 31 +- src/gen/state.rs | 103 +++++- src/gen/step.rs | 88 ++++- src/gen/steps/claim_rewards.rs | 7 +- src/gen/steps/init_default_proposal.rs | 6 +- src/gen/steps/init_funding_proposal.rs | 6 +- src/gen/steps/init_steward_proposal.rs | 6 +- src/gen/steps/mod.rs | 2 + src/gen/steps/shielding_transfer.rs | 83 +++++ src/gen/steps/unshielding_transfer.rs | 90 +++++ src/gen/utils.rs | 7 + src/main.rs | 14 +- src/runner.rs | 11 +- src/scenario.rs | 54 +++ src/state/state.rs | 16 +- src/tasks/become_validator.rs | 2 +- src/tasks/bond.rs | 7 +- src/tasks/change_consensus_key.rs | 4 +- src/tasks/change_metadata.rs | 8 +- src/tasks/claim_rewards.rs | 6 +- src/tasks/init_default_proposal.rs | 2 +- src/tasks/init_pgf_funding_proposal.rs | 2 +- src/tasks/init_pgf_steward_proposal.rs | 2 +- src/tasks/mod.rs | 23 +- src/tasks/redelegate.rs | 7 +- src/tasks/shielded_sync.rs | 88 +++++ src/tasks/tx_shielded_transfer.rs | 226 +++++++++++++ src/tasks/tx_shielding_transfer.rs | 228 +++++++++++++ src/tasks/tx_transparent_transfer.rs | 2 +- src/tasks/tx_unshielding_transfer.rs | 258 ++++++++++++++ src/tasks/update_account.rs | 5 +- src/tasks/wallet_new_key.rs | 41 +++ 41 files changed, 1724 insertions(+), 294 deletions(-) create mode 100644 src/gen/hooks/shielded_sync.rs create mode 100644 src/gen/steps/shielding_transfer.rs create mode 100644 src/gen/steps/unshielding_transfer.rs create mode 100644 src/tasks/shielded_sync.rs create mode 100644 src/tasks/tx_shielded_transfer.rs create mode 100644 src/tasks/tx_shielding_transfer.rs create mode 100644 src/tasks/tx_unshielding_transfer.rs diff --git a/.github/workflows/build-and-push.yml b/.github/workflows/build-and-push.yml index e8adf3b..de942ee 100644 --- a/.github/workflows/build-and-push.yml +++ b/.github/workflows/build-and-push.yml @@ -31,7 +31,7 @@ env: jobs: docker-namada: - runs-on: [ubuntu-latest] + runs-on: [ubuntu-latest] steps: - name: Checkout repo diff --git a/Cargo.lock b/Cargo.lock index ff0ba9a..43038f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,6 +27,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "aead" version = "0.5.2" @@ -74,9 +80,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", @@ -89,33 +95,33 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -214,15 +220,15 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ascii-canvas" @@ -287,7 +293,7 @@ checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ "async-channel 2.3.1", "async-executor", - "async-io 2.3.3", + "async-io 2.3.4", "async-lock 3.4.0", "blocking", "futures-lite 2.3.0", @@ -317,9 +323,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d6baa8f0178795da0e71bc42c9e5d13261aac7ee549853162e66a241ba17964" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" dependencies = [ "async-lock 3.4.0", "cfg-if", @@ -327,11 +333,11 @@ dependencies = [ "futures-io", "futures-lite 2.3.0", "parking", - "polling 3.7.2", + "polling 3.7.3", "rustix 0.38.34", "slab", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -362,7 +368,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -406,7 +412,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -434,7 +440,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -453,7 +459,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -620,9 +626,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ec96fe9a81b5e365f9db71fe00edc4fe4ca2cc7dcb7861f0603012a7caa210" +checksum = "d82033247fd8e890df8f740e407ad4d038debb9eb1f40533fffb32e7d17dc6f7" dependencies = [ "arrayref", "arrayvec", @@ -705,7 +711,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", "syn_derive", ] @@ -747,9 +753,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" dependencies = [ "serde", ] @@ -777,9 +783,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -818,12 +824,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.5" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" +checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -898,9 +905,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.9" +version = "4.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462" +checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" dependencies = [ "clap_builder", "clap_derive", @@ -908,9 +915,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.9" +version = "4.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942" +checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" dependencies = [ "anstream", "anstyle", @@ -920,21 +927,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.8" +version = "4.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" +checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "clap_lex" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" [[package]] name = "clru" @@ -995,9 +1002,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "concurrent-queue" @@ -1057,15 +1064,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] @@ -1206,7 +1213,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1217,7 +1224,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1293,7 +1300,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1303,7 +1310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" dependencies = [ "derive_builder_core", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1314,7 +1321,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1414,14 +1421,14 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "dunce" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "duration-str" @@ -1434,7 +1441,7 @@ dependencies = [ "serde", "thiserror", "time", - "winnow 0.6.13", + "winnow 0.6.18", ] [[package]] @@ -1729,8 +1736,8 @@ dependencies = [ "reqwest", "serde", "serde_json", - "syn 2.0.71", - "toml 0.8.14", + "syn 2.0.75", + "toml 0.8.19", "walkdir", ] @@ -1747,7 +1754,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -1773,7 +1780,7 @@ dependencies = [ "serde", "serde_json", "strum", - "syn 2.0.71", + "syn 2.0.75", "tempfile", "thiserror", "tiny-keccak", @@ -2015,12 +2022,12 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "9c0596c1eac1f9e04ed902702e9878208b336edc9d6fddc8a48387349bab3666" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] @@ -2199,7 +2206,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -2336,7 +2343,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.2.6", + "indexmap 2.4.0", "slab", "tokio", "tokio-util", @@ -2971,7 +2978,7 @@ source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=0c3b3c0ab598e1e6270 dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -3015,9 +3022,9 @@ dependencies = [ [[package]] name = "ics23" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc3b8be84e7285c73b88effdc3294b552277d6b0ec728ee016c861b7b9a2c19c" +checksum = "18798160736c1e368938ba6967dbcb3c7afb3256b442a5506ba5222eebb68a5a" dependencies = [ "anyhow", "blake2", @@ -3144,9 +3151,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown 0.14.5", @@ -3217,9 +3224,9 @@ checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -3247,18 +3254,18 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -3405,9 +3412,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libm" @@ -3612,11 +3619,20 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "minreq" -version = "2.11.2" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fdef521c74c2884a4f3570bcdb6d2a77b3c533feb6b27ac2ae72673cc221c64" +checksum = "763d142cdff44aaadd9268bebddb156ef6c65a0e13486bb81673cf2d8739f9b0" dependencies = [ "log", "once_cell", @@ -3627,13 +3643,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi 0.3.9", "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3661,6 +3678,7 @@ dependencies = [ "dyn-clone", "fake", "futures", + "indexmap 2.4.0", "itertools 0.12.1", "markdown-gen", "minio", @@ -4307,7 +4325,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4385,23 +4403,23 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4415,9 +4433,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.1" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -4461,9 +4479,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -4482,7 +4500,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4493,9 +4511,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -4692,9 +4710,9 @@ dependencies = [ [[package]] name = "peg" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a625d12ad770914cbf7eff6f9314c3ef803bfe364a1b20bc36ddf56673e71e5" +checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f" dependencies = [ "peg-macros", "peg-runtime", @@ -4702,9 +4720,9 @@ dependencies = [ [[package]] name = "peg-macros" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f241d42067ed3ab6a4fece1db720838e1418f36d868585a27931f95d6bc03582" +checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426" dependencies = [ "peg-runtime", "proc-macro2", @@ -4750,7 +4768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.2.6", + "indexmap 2.4.0", ] [[package]] @@ -4793,7 +4811,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4831,7 +4849,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -4848,9 +4866,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1d5c74c9876f070d3e8fd503d748c7d974c3e48da8f41350fa5222ef9b4391" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", "fastrand 2.1.0", @@ -4891,9 +4909,9 @@ dependencies = [ [[package]] name = "polling" -version = "3.7.2" +version = "3.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3ed00ed3fbf728b5816498ecd316d1716eecaced9c0c8d2c5a6740ca214985b" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" dependencies = [ "cfg-if", "concurrent-queue", @@ -4901,7 +4919,7 @@ dependencies = [ "pin-project-lite", "rustix 0.38.34", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4929,9 +4947,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "precomputed-hash" @@ -4946,7 +4967,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" dependencies = [ "proc-macro2", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5047,7 +5068,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.71", + "syn 2.0.75", "tempfile", ] @@ -5061,7 +5082,7 @@ dependencies = [ "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5230,9 +5251,9 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", @@ -5241,9 +5262,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -5388,9 +5409,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", "num-traits 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5586,7 +5607,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5696,9 +5717,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.204" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" dependencies = [ "serde_derive", ] @@ -5723,13 +5744,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.208" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -5740,16 +5761,17 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -5762,14 +5784,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -5841,6 +5863,12 @@ dependencies = [ "keccak", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -5917,7 +5945,7 @@ source = "git+https://github.com/heliaxdev/smooth-operator?tag=v0.7.0#0e182707f5 dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6035,7 +6063,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6092,9 +6120,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.71" +version = "2.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462" +checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" dependencies = [ "proc-macro2", "quote", @@ -6110,7 +6138,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6148,14 +6176,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand 2.1.0", + "once_cell", "rustix 0.38.34", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -6199,7 +6228,7 @@ dependencies = [ "serde", "serde_json", "tendermint", - "toml 0.8.14", + "toml 0.8.19", "url", ] @@ -6303,7 +6332,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6395,32 +6424,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.39.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6482,21 +6510,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.14" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.15", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -6507,22 +6535,22 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "toml_datetime", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.15" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap 2.2.6", + "indexmap 2.4.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow 0.6.18", ] [[package]] @@ -6535,14 +6563,14 @@ dependencies = [ "proc-macro2", "prost-build", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -6563,7 +6591,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6628,7 +6656,7 @@ checksum = "f9534daa9fd3ed0bd911d462a37f172228077e7abf18c18a5f67199d959205f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -6699,9 +6727,9 @@ dependencies = [ [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "universal-hash" @@ -6796,9 +6824,9 @@ dependencies = [ [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "waker-fn" @@ -6839,34 +6867,35 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -6876,9 +6905,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6886,22 +6915,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-streams" @@ -6942,9 +6971,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -6984,11 +7013,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -7024,6 +7053,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -7156,9 +7194,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] @@ -7203,9 +7241,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791978798f0597cfc70478424c2b4fdc2b7a8024aaff78497ef00f24ef674193" +checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" [[package]] name = "xmltree" @@ -7242,6 +7280,27 @@ dependencies = [ "nonempty", ] +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.75", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -7259,7 +7318,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.71", + "syn 2.0.75", ] [[package]] @@ -7303,9 +7362,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.12+zstd.1.5.6" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e40c320c3cb459d9a9ff6de98cff88f4751ee9275d140e2be94a2b74e4c13" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 9960cba..d9d8174 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ fake = "2.9.2" futures = "0.3.30" itertools = "0.12.1" thiserror = "1.0.63" +indexmap = "2.3.0" [[bin]] name = "scenario-tester" diff --git a/local_run.sh b/local_run.sh index 3a41cc2..4495b98 100755 --- a/local_run.sh +++ b/local_run.sh @@ -4,7 +4,7 @@ CHAIN_ID=${1} SK=${2} RPC=${3} -OUTPUT=$(cargo run --bin scenario-generator -- --steps 200) +OUTPUT=$(cargo run --bin scenario-generator -- --steps 30) SCENARIO_NAME="$(cut -d' ' -f2 <<<"$OUTPUT")" echo "Using scenario $SCENARIO_NAME" -cargo run --bin scenario-tester -- --rpc $RPC --chain-id $CHAIN_ID --faucet-sk ${SK} --scenario scenarios/$SCENARIO_NAME.json --workers 1 \ No newline at end of file +RUST_BACKTRACE=full cargo run --bin scenario-tester --release -- --rpc ${RPC} --chain-id $CHAIN_ID --faucet-sk ${SK} --scenario scenarios/$SCENARIO_NAME.json --workers 1 diff --git a/src/checks/reveal_pk.rs b/src/checks/reveal_pk.rs index 364fb0c..ae8db8b 100644 --- a/src/checks/reveal_pk.rs +++ b/src/checks/reveal_pk.rs @@ -1,6 +1,6 @@ use async_trait::async_trait; -use namada_sdk::{rpc, Namada}; +use namada_sdk::rpc; use serde::{Deserialize, Serialize}; use crate::entity::address::{AccountIndentifier, ADDRESS_PREFIX}; diff --git a/src/entity/address.rs b/src/entity/address.rs index 686890d..11dc4f4 100644 --- a/src/entity/address.rs +++ b/src/entity/address.rs @@ -3,6 +3,8 @@ use std::str::FromStr; use namada_sdk::{ address::Address, key::common::{self, PublicKey}, + masp::ExtendedSpendingKey, + masp::PaymentAddress, rpc, Namada, }; @@ -16,6 +18,8 @@ pub enum AccountIndentifier { Address(String), PublicKey(String), StateAddress(StateAddress), + PaymentAddress(String), + SpendingKey(String), } impl AccountIndentifier { @@ -35,6 +39,36 @@ impl AccountIndentifier { AccountIndentifier::StateAddress(metadata) => { Address::decode(metadata.address.clone()).unwrap() } + AccountIndentifier::PaymentAddress(_) => unimplemented!(), + AccountIndentifier::SpendingKey(_) => unimplemented!(), + } + } + + pub async fn to_payment_address(&self, sdk: &Sdk) -> PaymentAddress { + match self { + AccountIndentifier::Alias(alias) => { + let wallet = sdk.namada.wallet.read().await; + *wallet.find_payment_addr(alias).unwrap() + } + AccountIndentifier::Address(_) => unimplemented!(), + AccountIndentifier::PublicKey(_) => unimplemented!(), + AccountIndentifier::StateAddress(_) => unimplemented!(), + AccountIndentifier::PaymentAddress(pa) => PaymentAddress::from_str(pa).unwrap(), + AccountIndentifier::SpendingKey(_) => unimplemented!(), + } + } + + pub async fn to_spending_key(&self, sdk: &Sdk) -> ExtendedSpendingKey { + match self { + AccountIndentifier::Alias(alias) => { + let mut wallet = sdk.namada.wallet.write().await; + wallet.find_spending_key(alias, None).unwrap().key + } + AccountIndentifier::Address(_) => unimplemented!(), + AccountIndentifier::PublicKey(_) => unimplemented!(), + AccountIndentifier::StateAddress(_) => unimplemented!(), + AccountIndentifier::PaymentAddress(_) => unimplemented!(), + AccountIndentifier::SpendingKey(sk) => ExtendedSpendingKey::from_str(sk).unwrap(), } } @@ -54,7 +88,9 @@ impl AccountIndentifier { let sk = wallet.find_key_by_pk(&public_key, None).unwrap(); return sk; } - AccountIndentifier::StateAddress(_metadata) => unimplemented!(), + AccountIndentifier::StateAddress(_) => unimplemented!(), + AccountIndentifier::PaymentAddress(_) => unimplemented!(), + AccountIndentifier::SpendingKey(_) => unimplemented!(), }; let mut wallet = sdk.namada.wallet.write().await; wallet.find_secret_key(&alias, None).unwrap() @@ -80,6 +116,8 @@ impl AccountIndentifier { return PublicKey::from_str(public_key).unwrap() } AccountIndentifier::StateAddress(_metadata) => unimplemented!(), + AccountIndentifier::PaymentAddress(_) => unimplemented!(), + AccountIndentifier::SpendingKey(_) => unimplemented!(), }; let wallet = sdk.namada.wallet.read().await; wallet.find_public_key(&alias).unwrap() @@ -114,6 +152,8 @@ impl AccountIndentifier { return vec![PublicKey::from_str(public_key).unwrap()] } AccountIndentifier::StateAddress(_metadata) => unimplemented!(), + AccountIndentifier::PaymentAddress(_) => unimplemented!(), + AccountIndentifier::SpendingKey(_) => unimplemented!(), }; let wallet = sdk.namada.wallet.read().await; vec![wallet.find_public_key(&alias).unwrap()] diff --git a/src/gen/entity.rs b/src/gen/entity.rs index 21c68b0..c648bd3 100644 --- a/src/gen/entity.rs +++ b/src/gen/entity.rs @@ -34,6 +34,60 @@ impl Display for Alias { } } +#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct SpendingKey { + inner: Alias, +} + +impl SpendingKey { + pub fn new(alias: Alias) -> Self { + Self { inner: alias } + } +} + +impl Display for SpendingKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.inner) + } +} + +impl From for Alias { + fn from(value: SpendingKey) -> Self { + value.inner + } +} + +impl From for SpendingKey { + fn from(value: String) -> Self { + SpendingKey { + inner: Alias { inner: value }, + } + } +} + +#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub struct PaymentAddress { + pub inner: Alias, +} + +impl PaymentAddress { + pub fn new(alias: Alias) -> Self { + Self { inner: alias } + } +} + +impl Display for PaymentAddress { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.inner) + } +} + +impl From for Alias { + fn from(value: PaymentAddress) -> Self { + value.inner + } +} + #[derive(Clone, Debug, Default, Hash, PartialEq, Eq)] pub enum AddressType { Enstablished, diff --git a/src/gen/hooks/mod.rs b/src/gen/hooks/mod.rs index b3bb99d..477c73d 100644 --- a/src/gen/hooks/mod.rs +++ b/src/gen/hooks/mod.rs @@ -6,4 +6,5 @@ pub mod query_balance; pub mod query_proposals; pub mod query_validators; pub mod reveal_pk; +pub mod shielded_sync; pub mod storage_check; diff --git a/src/gen/hooks/shielded_sync.rs b/src/gen/hooks/shielded_sync.rs new file mode 100644 index 0000000..d982176 --- /dev/null +++ b/src/gen/hooks/shielded_sync.rs @@ -0,0 +1,32 @@ +use std::fmt::Display; + +use namada_scenario_tester::scenario::StepType; + +use crate::step::Hook; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ShieldedSync {} + +impl Default for ShieldedSync { + fn default() -> Self { + Self::new() + } +} + +impl ShieldedSync { + pub fn new() -> Self { + Self {} + } +} + +impl Hook for ShieldedSync { + fn to_step_type(&self) -> StepType { + StepType::ShieldedSync + } +} + +impl Display for ShieldedSync { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "synchronizing the state of the masp") + } +} diff --git a/src/gen/main.rs b/src/gen/main.rs index 566e386..6c65c74 100644 --- a/src/gen/main.rs +++ b/src/gen/main.rs @@ -3,7 +3,6 @@ use std::collections::HashMap; use clap::Parser; use itertools::Itertools; -use namada_scenario_tester::tasks::Task; use scenario_builder::ScenarioBuilder; use step::TaskType; @@ -44,21 +43,23 @@ fn main() { (TaskType::NewWalletKey, 1.into()), (TaskType::FaucetTransafer, 2.into()), (TaskType::TransparentTransfer, 3.into()), - (TaskType::InitAccount, 4.into()), - (TaskType::Bond, 4.into()), - (TaskType::InitDefaultProposal, 3.into()), - (TaskType::Unbond, 4.into()), + (TaskType::ShieldingTransfer, 6.into()), + (TaskType::UnshieldingTransfer, 6.into()), + // (TaskType::InitAccount, 4.into()), + // (TaskType::Bond, 5.into()), + // (TaskType::InitDefaultProposal, 6.into()), + // (TaskType::Unbond, 4.into()), // (TaskType::Withdraw, 4.into()), - (TaskType::VoteProposal, 3.into()), - (TaskType::Redelegate, 5.into()), - (TaskType::InitPgfStewardProposal, 3.into()), - (TaskType::InitPgfFundingProposal, 3.into()), - (TaskType::BecomeValidator, 5.into()), - (TaskType::UpdateAccount, 3.into()), - (TaskType::DeactivateValidator, 2.into()), - (TaskType::ChangeConsensusKey, 5.into()), - (TaskType::ChangeMetadata, 4.into()), - (TaskType::ClaimRewards, 5.into()), + + // (TaskType::VoteProposal, 3.into()), + // (TaskType::Redelegate, 4.into()), + // (TaskType::InitPgfStewardProposal, 5.into()), + // (TaskType::InitPgfFundingProposal, 4.into()), + // (TaskType::BecomeValidator, 5.into()), + // (TaskType::UpdateAccount, 5.into()), + // (TaskType::DeactivateValidator, 5.into()), + // (TaskType::ChangeMetadata, 4.into()), + // (TaskType::ClaimRewards, 5.into()), ]); let mut scenario_builder = ScenarioBuilder::new( diff --git a/src/gen/state.rs b/src/gen/state.rs index 7168b2e..145b18d 100644 --- a/src/gen/state.rs +++ b/src/gen/state.rs @@ -5,11 +5,11 @@ use std::{ use crate::{ constants::{DEFAULT_GAS_LIMIT, DEFAULT_GAS_PRICE}, - entity::{Account, Alias, Bond, TxSettings, Unbond}, + entity::{Account, Alias, Bond, PaymentAddress, TxSettings, Unbond}, }; use namada_sdk::token::NATIVE_SCALE; -use rand::prelude::SliceRandom; +use rand::{prelude::SliceRandom, seq::IteratorRandom}; pub type StepId = u64; pub type ProposalId = u64; @@ -17,10 +17,13 @@ pub type ProposalId = u64; #[derive(Clone, Debug, Default)] pub struct State { pub sks: Vec, + pub pasks: Vec, pub pks: Vec, pub implicit_addresses: HashMap, pub enstablished_addresses: HashMap, + pub payment_addresses: HashMap, pub balances: HashMap>, + pub shielded_balances: HashMap>, pub bonds: HashMap>, pub unbonds: HashMap>, pub redelegations: HashMap>, @@ -45,7 +48,10 @@ impl State { self.balances .iter() .fold(vec![], |mut acc, (alias, token_balances)| { - if token_balances.values().any(|balance| *balance > amount) { + if token_balances + .values() + .any(|balance| *balance > amount && !alias.to_string().ends_with("-pa")) + { let account = self.get_account_from_alias(alias); acc.push(account); acc @@ -63,6 +69,9 @@ impl State { self.balances .iter() .fold(vec![], |mut acc, (alias, token_balances)| { + if alias.to_string().ends_with("-pa") { + return acc; + } if let Some(balance) = token_balances.get(&Alias::native_token()) { if *balance > amount { let account = self.get_account_from_alias(alias); @@ -75,6 +84,29 @@ impl State { }) } + pub fn payment_address_with_at_least_native_token_balance( + &self, + amount: u64, + ) -> Vec { + self.shielded_balances + .iter() + .fold(vec![], |mut acc, (alias, token_balances)| { + if !alias.to_string().ends_with("-pa") { + return acc; + } + if let Some(balance) = token_balances.get(&Alias::native_token()) { + if *balance > amount { + if let Some(pa) = self.payment_addresses.get(alias) { + acc.push(pa.clone()); + } + } + acc + } else { + acc + } + }) + } + pub fn implicit_addresses_with_at_least_native_token_balance( &self, amount: u64, @@ -83,6 +115,9 @@ impl State { .iter() .filter(|(alias, _)| !alias.to_string().starts_with("load-tester-enst")) .fold(vec![], |mut acc, (alias, token_balances)| { + if alias.to_string().ends_with("-pa") { + return acc; + } if let Some(balance) = token_balances.get(&Alias::native_token()) { if *balance > amount { let account = self.get_account_from_alias(alias); @@ -239,6 +274,15 @@ impl State { account } + pub fn random_payment_address(&self) -> PaymentAddress { + let all_addresses = self.payment_addresses.values(); + + all_addresses + .choose(&mut rand::thread_rng()) + .unwrap() + .clone() + } + pub fn random_accounts(&self, total: u64, blacklist: Vec) -> Vec { let all_addresses = self.any_address(); let total = min(total as usize, all_addresses.len() - blacklist.len()); @@ -308,6 +352,18 @@ impl State { .clone() } + pub fn random_payment_address_with_at_least_native_token_balance( + &self, + amount: u64, + ) -> PaymentAddress { + let all_payment_addresses_with_native_token_balance = + self.payment_address_with_at_least_native_token_balance(amount); + all_payment_addresses_with_native_token_balance + .choose(&mut rand::thread_rng()) + .unwrap() + .clone() + } + pub fn random_implicit_account_with_at_least_native_token_balance( &self, amount: u64, @@ -329,7 +385,11 @@ impl State { } pub fn random_token_balance_for_alias(&self, alias: &Alias) -> AccountBalance { - let balances = self.balances.get(alias).unwrap(); + let balances = if alias.to_string().ends_with("-pa") { + self.shielded_balances.get(alias).unwrap() + } else { + self.balances.get(alias).unwrap() + }; balances .iter() .next() @@ -373,6 +433,20 @@ impl State { .unwrap() -= amount; } + pub fn decrease_shielded_account_token_balance( + &mut self, + address_alias: &Alias, + token_alias: &Alias, + amount: u64, + ) { + *self + .shielded_balances + .get_mut(address_alias) + .unwrap() + .get_mut(token_alias) + .unwrap() -= amount; + } + pub fn decrease_account_fees( &mut self, address_alias: &Alias, @@ -542,11 +616,30 @@ impl State { .or_insert(0) += amount; } + pub fn increase_shielded_account_token_balance( + &mut self, + address_alias: &Alias, + token_alias: &Alias, + amount: u64, + ) { + *self + .shielded_balances + .entry(address_alias.clone()) + .or_insert(HashMap::from_iter([(token_alias.clone(), 0)])) + .entry(token_alias.clone()) + .or_insert(0) += amount; + } + pub fn insert_new_key(&mut self, alias: Alias) { + let shielded_alias = Alias::from(format!("{}-masp", alias)); + let pa_alias = Alias::from(format!("{}-pa", alias)); self.sks.push(alias.clone()); + self.pasks.push(shielded_alias.clone()); self.pks.push(alias.clone()); self.implicit_addresses - .insert(alias.clone(), Account::new_implicit_address(alias)); + .insert(alias.clone(), Account::new_implicit_address(alias.clone())); + self.payment_addresses + .insert(pa_alias.clone(), PaymentAddress::new(pa_alias)); } pub fn add_new_account(&mut self, alias: Alias, pks: BTreeSet, threshold: u64) { diff --git a/src/gen/step.rs b/src/gen/step.rs index 37e470c..2f45c06 100644 --- a/src/gen/step.rs +++ b/src/gen/step.rs @@ -1,5 +1,5 @@ use dyn_clone::DynClone; -use namada_scenario_tester::{scenario::StepType, tasks::Task}; +use namada_scenario_tester::scenario::StepType; use namada_sdk::token::NATIVE_SCALE; use crate::{ @@ -14,9 +14,10 @@ use crate::{ init_default_proposal::InitDefaultProposalBuilder, init_funding_proposal::InitPgfFundingProposalBuilder, init_steward_proposal::InitPgfStewardProposalBuilder, new_wallet_key::NewWalletStepBuilder, - redelegate::RedelegateBuilder, transparent_transfer::TransparentTransferBuilder, - unbond::UnbondBuilder, update_account::UpdateAccountBuilder, vote::VoteProposalBuilder, - withdraw::WithdrawBuilder, + redelegate::RedelegateBuilder, shielding_transfer::ShieldingTransferBuilder, + transparent_transfer::TransparentTransferBuilder, unbond::UnbondBuilder, + unshielding_transfer::UnshieldingTransferBuilder, update_account::UpdateAccountBuilder, + vote::VoteProposalBuilder, withdraw::WithdrawBuilder, }, utils, }; @@ -32,6 +33,8 @@ pub enum TaskType { NewWalletKey, FaucetTransafer, TransparentTransfer, + ShieldingTransfer, + UnshieldingTransfer, Bond, InitAccount, InitDefaultProposal, @@ -63,6 +66,22 @@ impl TaskType { .is_empty() && state.any_address().len() > 1 } + TaskType::ShieldingTransfer => { + !state + .implicit_addresses_with_at_least_native_token_balance(MIN_FEE) + .is_empty() + && !state + .addresses_with_at_least_native_token_balance(MIN_FEE * 2) + .is_empty() + } + TaskType::UnshieldingTransfer => { + !state + .implicit_addresses_with_at_least_native_token_balance(MIN_FEE) + .is_empty() + && !state + .payment_address_with_at_least_native_token_balance(1) + .is_empty() + } TaskType::Bond => !state .implicit_addresses_with_at_least_native_token_balance(MIN_FEE) .is_empty(), @@ -173,6 +192,67 @@ impl TaskType { Box::new(step) } + TaskType::ShieldingTransfer => { + let source = state.random_account_with_at_least_native_token_balance(MIN_FEE * 2); + let token_balance = state.random_token_balance_for_alias(&source.alias); + let target = state.random_payment_address(); + + let tx_settings = if source.clone().address_type.is_implicit() { + let gas_payer = source.alias.clone(); + TxSettings::default_from_implicit(gas_payer) + } else { + let gas_payer = state + .random_implicit_account_with_at_least_native_token_balance(MIN_FEE) + .alias; + TxSettings::default_from_enstablished( + source.clone().implicit_addresses, + gas_payer, + ) + }; + + let amount = if source.clone().address_type.is_implicit() { + utils::random_between(0, token_balance.balance - MIN_FEE) + } else { + utils::random_between(0, token_balance.balance) + }; + + let step = ShieldingTransferBuilder::default() + .source(source.alias) + .target(target) + .token(token_balance.token) + .amount(amount) + .tx_settings(tx_settings) + .build() + .unwrap(); + + Box::new(step) + } + TaskType::UnshieldingTransfer => { + let source = + state.random_payment_address_with_at_least_native_token_balance(MIN_FEE * 2); + let spending_key_source = + format!("{}-masp", source.to_string().strip_suffix("-pa").unwrap()); + let token_balance = state.random_token_balance_for_alias(&source.inner); + let target = state.random_account(vec![]); + + let gas_payer = state + .random_implicit_account_with_at_least_native_token_balance(MIN_FEE) + .alias; + let tx_settings = TxSettings::default_from_enstablished(BTreeSet::new(), gas_payer); + + let amount = utils::random_between(0, token_balance.balance); + + let step = UnshieldingTransferBuilder::default() + .source(spending_key_source.into()) + .target(target.alias) + .token(token_balance.token) + .amount(amount) + .tx_settings(tx_settings) + .build() + .unwrap(); + + Box::new(step) + } TaskType::TransparentTransfer => { let source = state.random_account_with_at_least_native_token_balance(MIN_FEE * 2); let target = state.random_account(vec![source.alias.clone()]); diff --git a/src/gen/steps/claim_rewards.rs b/src/gen/steps/claim_rewards.rs index 1d38298..25481d0 100644 --- a/src/gen/steps/claim_rewards.rs +++ b/src/gen/steps/claim_rewards.rs @@ -5,12 +5,7 @@ use namada_scenario_tester::{ scenario::StepType, tasks::claim_rewards::TxClaimRewardsteParametersDto, utils::value::Value, }; -use crate::{ - entity::{Alias, TxSettings}, - hooks::{check_step::CheckStep, query_validators::QueryValidatorSet}, - state::State, - step::Step, -}; +use crate::{entity::TxSettings, hooks::check_step::CheckStep, state::State, step::Step}; #[derive(Clone, Debug, PartialEq, Eq, Builder)] pub struct ClaimRewards { diff --git a/src/gen/steps/init_default_proposal.rs b/src/gen/steps/init_default_proposal.rs index 82e4d4d..584281c 100644 --- a/src/gen/steps/init_default_proposal.rs +++ b/src/gen/steps/init_default_proposal.rs @@ -51,11 +51,7 @@ impl Step for InitDefaultProposal { } fn total_post_hooks(&self) -> u64 { - if self.author.eq(&self.tx_settings.gas_payer) { - 1 - } else { - 1 - } + 1 } fn total_pre_hooks(&self) -> u64 { diff --git a/src/gen/steps/init_funding_proposal.rs b/src/gen/steps/init_funding_proposal.rs index 679bb47..fe3e6a3 100644 --- a/src/gen/steps/init_funding_proposal.rs +++ b/src/gen/steps/init_funding_proposal.rs @@ -84,11 +84,7 @@ impl Step for InitPgfFundingProposal { } fn total_post_hooks(&self) -> u64 { - if self.author.eq(&self.tx_settings.gas_payer) { - 1 - } else { - 1 - } + 1 } fn total_pre_hooks(&self) -> u64 { diff --git a/src/gen/steps/init_steward_proposal.rs b/src/gen/steps/init_steward_proposal.rs index b041839..e5fdea0 100644 --- a/src/gen/steps/init_steward_proposal.rs +++ b/src/gen/steps/init_steward_proposal.rs @@ -57,11 +57,7 @@ impl Step for InitPgfStewardProposal { } fn total_post_hooks(&self) -> u64 { - if self.author.eq(&self.tx_settings.gas_payer) { - 1 - } else { - 1 - } + 1 } fn total_pre_hooks(&self) -> u64 { diff --git a/src/gen/steps/mod.rs b/src/gen/steps/mod.rs index 8b64b6d..befa7da 100644 --- a/src/gen/steps/mod.rs +++ b/src/gen/steps/mod.rs @@ -11,8 +11,10 @@ pub mod init_funding_proposal; pub mod init_steward_proposal; pub mod new_wallet_key; pub mod redelegate; +pub mod shielding_transfer; pub mod transparent_transfer; pub mod unbond; +pub mod unshielding_transfer; pub mod update_account; pub mod vote; pub mod withdraw; diff --git a/src/gen/steps/shielding_transfer.rs b/src/gen/steps/shielding_transfer.rs new file mode 100644 index 0000000..530922a --- /dev/null +++ b/src/gen/steps/shielding_transfer.rs @@ -0,0 +1,83 @@ +use std::fmt::Display; + +use derive_builder::Builder; +use namada_scenario_tester::{ + scenario::StepType, tasks::tx_shielding_transfer::TxShieldingTransferParametersDto, + utils::value::Value, +}; + +use crate::{ + entity::{Alias, PaymentAddress, TxSettings}, + hooks::{check_balance::CheckBalance, check_step::CheckStep, query_balance::QueryBalance}, + state::State, + step::Step, +}; + +#[derive(Clone, Debug, PartialEq, Eq, Builder)] +pub struct ShieldingTransfer { + pub source: Alias, + pub target: PaymentAddress, + pub token: Alias, + pub amount: u64, + pub tx_settings: TxSettings, +} + +impl Step for ShieldingTransfer { + fn to_step_type(&self, _step_index: u64) -> StepType { + StepType::ShieldingTransfer { + parameters: TxShieldingTransferParametersDto { + source: Value::v(self.source.to_string()), + target: Value::v(self.target.to_string()), + amount: Value::v(self.amount.to_string()), + token: Value::v(self.token.to_string()), + }, + settings: Some(self.tx_settings.clone().into()), + } + } + + fn update_state(&self, state: &mut crate::state::State) { + state.decrease_account_fees(&self.tx_settings.gas_payer, &None); + state.decrease_account_token_balance(&self.source, &self.token, self.amount); + state.increase_shielded_account_token_balance( + &self.target.clone().into(), + &self.token, + self.amount, + ); + } + + fn post_hooks(&self, step_index: u64, _state: &State) -> Vec> { + let check_balance_source = CheckBalance::new( + step_index - 1, + self.source.clone(), + self.token.clone(), + "le".to_string(), + ); + vec![ + Box::new(CheckStep::new(step_index)), + Box::new(check_balance_source), + ] + } + + fn pre_hooks(&self, _state: &State) -> Vec> { + let query_balance_source = QueryBalance::new(self.source.to_owned(), Alias::native_token()); + vec![Box::new(query_balance_source)] + } + + fn total_post_hooks(&self) -> u64 { + 2 + } + + fn total_pre_hooks(&self) -> u64 { + 1 + } +} + +impl Display for ShieldingTransfer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "shielded transfer {} {} from {} to {}", + self.amount, self.token, self.source, self.target + ) + } +} diff --git a/src/gen/steps/unshielding_transfer.rs b/src/gen/steps/unshielding_transfer.rs new file mode 100644 index 0000000..d71d740 --- /dev/null +++ b/src/gen/steps/unshielding_transfer.rs @@ -0,0 +1,90 @@ +use std::fmt::Display; + +use derive_builder::Builder; +use namada_scenario_tester::{ + scenario::StepType, tasks::tx_unshielding_transfer::TxUnshieldingTransferParametersDto, + utils::value::Value, +}; + +use crate::{ + entity::{Alias, SpendingKey, TxSettings}, + hooks::{ + check_balance::CheckBalance, check_step::CheckStep, query_balance::QueryBalance, + shielded_sync::ShieldedSync, + }, + state::State, + step::Step, +}; + +#[derive(Clone, Debug, PartialEq, Eq, Builder)] +pub struct UnshieldingTransfer { + pub source: SpendingKey, + pub target: Alias, + pub token: Alias, + pub amount: u64, + pub tx_settings: TxSettings, +} + +impl Step for UnshieldingTransfer { + fn to_step_type(&self, _step_index: u64) -> StepType { + StepType::UnshieldingTransfer { + parameters: TxUnshieldingTransferParametersDto { + source: Value::v(self.source.to_string()), + target: Value::v(self.target.to_string()), + amount: Value::v(self.amount.to_string()), + token: Value::v(self.token.to_string()), + }, + settings: Some(self.tx_settings.clone().into()), + } + } + + fn update_state(&self, state: &mut crate::state::State) { + state.decrease_account_fees(&self.tx_settings.gas_payer, &None); + state.increase_account_token_balance(&self.target, self.token.clone(), self.amount); + let pa_alias = format!( + "{}-pa", + self.source.to_string().strip_suffix("-masp").unwrap() + ) + .into(); + state.decrease_shielded_account_token_balance(&pa_alias, &self.token, self.amount); + } + + fn post_hooks(&self, step_index: u64, _state: &State) -> Vec> { + let check_balance_target = CheckBalance::new( + step_index - 2, + self.target.clone(), + self.token.clone(), + "ge".to_string(), + ); + vec![ + Box::new(CheckStep::new(step_index)), + Box::new(check_balance_target), + ] + } + + fn pre_hooks(&self, _state: &State) -> Vec> { + let query_balance_source = QueryBalance::new(self.target.to_owned(), Alias::native_token()); + vec![ + Box::new(query_balance_source), + Box::new(ShieldedSync::new()), + ] + } + + fn total_post_hooks(&self) -> u64 { + 2 + } + + fn total_pre_hooks(&self) -> u64 { + 2 + } +} + +impl Display for UnshieldingTransfer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "unshielded transfer {} {} from {} to {}", + self.amount, self.token, self.source, self.target + ) + } +} diff --git a/src/gen/utils.rs b/src/gen/utils.rs index 3b42c1e..369abc8 100644 --- a/src/gen/utils.rs +++ b/src/gen/utils.rs @@ -10,6 +10,13 @@ pub fn random_alias() -> String { ) } +pub fn random_pa_alias() -> String { + format!( + "load-tester-pa-{}", + Alphanumeric.sample_string(&mut rand::thread_rng(), 8) + ) +} + pub fn random_with_namespace(ns: &str) -> String { format!( "scenario-{}-{}", diff --git a/src/main.rs b/src/main.rs index a3dbf77..dbdfe27 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use clap::Parser; use namada_scenario_tester::{config::AppConfig, runner::Runner, scenario::Scenario}; +use namada_sdk::control_flow::{install_shutdown_signal, ShutdownSignal}; use rand::Rng; use std::{env, fs, io::Read, path::PathBuf}; @@ -62,7 +63,14 @@ async fn run(worker_id: u64) { let scenario: Scenario = serde_json::from_str(&scenario_json).unwrap(); - Runner::default() - .run(worker_id, scenario, &config, scenario_path) - .await; + let mut runner = Runner::default(); + let run_future = runner.run(worker_id, scenario, &config, scenario_path); + + let mut shutdown_signal = install_shutdown_signal(true); + let interrupt_future = shutdown_signal.wait_for_shutdown(); + + tokio::select! { + _ = run_future => {} + _ = interrupt_future => {} + } } diff --git a/src/runner.rs b/src/runner.rs index b169a1c..d8e657e 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -1,13 +1,8 @@ use std::{str::FromStr, thread, time::Duration}; use namada_sdk::{ - io::NullIo, - masp::fs::FsShieldedUtils, - queries::Client, - rpc::{self, is_public_key_revealed}, - signing::default_sign, - wallet::fs::FsWalletUtils, - Namada, + io::NullIo, masp::fs::FsShieldedUtils, queries::Client, rpc::is_public_key_revealed, + signing::default_sign, wallet::fs::FsWalletUtils, Namada, }; use tempfile::tempdir; use tendermint_rpc::{HttpClient, Url}; @@ -42,7 +37,7 @@ impl Runner { let wallet = FsWalletUtils::new(wallet_path); // Setup shielded context storage - let shielded_ctx_path = base_dir.join("masp"); + let shielded_ctx_path = base_dir.as_path().to_owned(); let shielded_ctx = FsShieldedUtils::new(shielded_ctx_path); let io = NullIo; diff --git a/src/scenario.rs b/src/scenario.rs index 42c1992..ff3a7b5 100644 --- a/src/scenario.rs +++ b/src/scenario.rs @@ -40,7 +40,11 @@ use crate::{ reactivate_validator::{ReactivateValidatorParametersDto, TxReactivateValidator}, redelegate::{TxRedelegate, TxRedelegateParametersDto}, reveal_pk::{RevealPkParametersDto, TxRevealPk}, + shielded_sync::{ShieldedSync, ShieldedSyncParametersDto}, + tx_shielded_transfer::{TxShieldedTransfer, TxShieldedTransferParametersDto}, + tx_shielding_transfer::{TxShieldingTransfer, TxShieldingTransferParametersDto}, tx_transparent_transfer::{TxTransparentTransfer, TxTransparentTransferParametersDto}, + tx_unshielding_transfer::{TxUnshieldingTransfer, TxUnshieldingTransferParametersDto}, unbond::{TxUnbond, TxUnbondParametersDto}, update_account::{TxUpdateAccount, TxUpdateAccountParametersDto}, vote::{TxVoteProposal, TxVoteProposalParametersDto}, @@ -59,6 +63,8 @@ use crate::{ #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(tag = "type")] pub enum StepType { + #[serde(rename = "shielded-sync")] + ShieldedSync, #[serde(rename = "wallet-new-key")] WalletNewKey { parameters: WalletNewKeyParametersDto, @@ -79,6 +85,21 @@ pub enum StepType { parameters: TxTransparentTransferParametersDto, settings: Option, }, + #[serde(rename = "tx-shielding-transfer")] + ShieldingTransfer { + parameters: TxShieldingTransferParametersDto, + settings: Option, + }, + #[serde(rename = "tx-shielded-transfer")] + ShieldedTransfer { + parameters: TxShieldedTransferParametersDto, + settings: Option, + }, + #[serde(rename = "tx-unshielding-transfer")] + UnshieldingTransfer { + parameters: TxUnshieldingTransferParametersDto, + settings: Option, + }, #[serde(rename = "reveal-pk")] RevealPk { parameters: RevealPkParametersDto, @@ -203,9 +224,13 @@ pub enum StepType { impl Display for StepType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + StepType::ShieldedSync => write!(f, "shielded-sync"), StepType::WalletNewKey { .. } => write!(f, "wallet-new-key"), StepType::InitAccount { .. } => write!(f, "tx-init-account"), StepType::TransparentTransfer { .. } => write!(f, "tx-transparent-transfer"), + StepType::ShieldingTransfer { .. } => write!(f, "tx-shielding-transfer"), + StepType::ShieldedTransfer { .. } => write!(f, "tx-shielded-transfer"), + StepType::UnshieldingTransfer { .. } => write!(f, "tx-unshielding-transfer"), StepType::RevealPk { .. } => write!(f, "tx-reveal-pk"), StepType::Bond { .. } => write!(f, "tx-bond"), StepType::Unbond { .. } => write!(f, "tx-unbond"), @@ -248,6 +273,11 @@ pub struct Step { impl Step { pub async fn run(&self, storage: &Storage, sdk: &Sdk) -> StepResult { match self.config.to_owned() { + StepType::ShieldedSync => { + ShieldedSync::default() + .run(sdk, ShieldedSyncParametersDto, Default::default(), storage) + .await + } StepType::WalletNewKey { parameters: dto, settings, @@ -280,6 +310,30 @@ impl Step { .run(sdk, dto, settings, storage) .await } + StepType::ShieldingTransfer { + parameters: dto, + settings, + } => { + TxShieldingTransfer::default() + .run(sdk, dto, settings, storage) + .await + } + StepType::ShieldedTransfer { + parameters: dto, + settings, + } => { + TxShieldedTransfer::default() + .run(sdk, dto, settings, storage) + .await + } + StepType::UnshieldingTransfer { + parameters: dto, + settings, + } => { + TxUnshieldingTransfer::default() + .run(sdk, dto, settings, storage) + .await + } StepType::RevealPk { parameters: dto, settings, diff --git a/src/state/state.rs b/src/state/state.rs index 99b2dc0..deddc73 100644 --- a/src/state/state.rs +++ b/src/state/state.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, fmt::Display}; +use std::fmt::Display; + +use indexmap::IndexMap as HashMap; +use namada_sdk::storage::BlockHeight; use crate::scenario::StepResult; @@ -222,6 +225,17 @@ impl Storage { }) } + pub fn get_last_masp_tx_height(&self) -> Option { + self.step_states + .iter() + .rev() + .find_map(|(_step_id, step_storage)| { + let stx_height = step_storage.storage.get("stx-height")?; + + stx_height.parse().ok() + }) + } + pub fn get_address(&self, alias: &str) -> StateAddress { self.accounts .get(alias) diff --git a/src/tasks/become_validator.rs b/src/tasks/become_validator.rs index 7003cea..8123350 100644 --- a/src/tasks/become_validator.rs +++ b/src/tasks/become_validator.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; use namada_sdk::{ - args::{TxBecomeValidator as SdkBecomeValidatorTx, TxBuilder}, + args::TxBecomeValidator as SdkBecomeValidatorTx, dec::Dec, key::{RefTo, SchemeType}, signing::default_sign, diff --git a/src/tasks/bond.rs b/src/tasks/bond.rs index 943de07..004f7b6 100644 --- a/src/tasks/bond.rs +++ b/src/tasks/bond.rs @@ -1,10 +1,5 @@ use async_trait::async_trait; -use namada_sdk::{ - args::{Bond, TxBuilder}, - signing::default_sign, - token::Amount, - Namada, -}; +use namada_sdk::{args::Bond, signing::default_sign, token::Amount, Namada}; use rand::Rng; use serde::{Deserialize, Serialize}; diff --git a/src/tasks/change_consensus_key.rs b/src/tasks/change_consensus_key.rs index 49744e3..13a04a5 100644 --- a/src/tasks/change_consensus_key.rs +++ b/src/tasks/change_consensus_key.rs @@ -1,11 +1,9 @@ use async_trait::async_trait; use namada_sdk::{ - args::{ConsensusKeyChange, TxBuilder}, - dec::Dec, + args::ConsensusKeyChange, key::{RefTo, SchemeType}, signing::default_sign, - tendermint_proto::consensus, Namada, }; diff --git a/src/tasks/change_metadata.rs b/src/tasks/change_metadata.rs index 8ff181b..4656450 100644 --- a/src/tasks/change_metadata.rs +++ b/src/tasks/change_metadata.rs @@ -6,13 +6,7 @@ use fake::{ }, Fake, }; -use namada_sdk::{ - args::{MetaDataChange, TxBuilder}, - dec::Dec, - signing::default_sign, - Namada, -}; -use rand::Rng; +use namada_sdk::{args::MetaDataChange, signing::default_sign, Namada}; use serde::{Deserialize, Serialize}; use crate::{ diff --git a/src/tasks/claim_rewards.rs b/src/tasks/claim_rewards.rs index 84e7d54..e1cd6bc 100644 --- a/src/tasks/claim_rewards.rs +++ b/src/tasks/claim_rewards.rs @@ -1,9 +1,5 @@ use async_trait::async_trait; -use namada_sdk::{ - args::{ClaimRewards, TxBuilder}, - signing::default_sign, - Namada, -}; +use namada_sdk::{args::ClaimRewards, signing::default_sign, Namada}; use serde::{Deserialize, Serialize}; use super::{Task, TaskError, TaskParam}; diff --git a/src/tasks/init_default_proposal.rs b/src/tasks/init_default_proposal.rs index e13d586..674be75 100644 --- a/src/tasks/init_default_proposal.rs +++ b/src/tasks/init_default_proposal.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use async_trait::async_trait; use namada_sdk::{ - args::{InitProposal, TxBuilder}, + args::InitProposal, governance::{ cli::onchain::{DefaultProposal, OnChainProposal}, storage::keys::get_counter_key, diff --git a/src/tasks/init_pgf_funding_proposal.rs b/src/tasks/init_pgf_funding_proposal.rs index 1b239d0..9a958e8 100644 --- a/src/tasks/init_pgf_funding_proposal.rs +++ b/src/tasks/init_pgf_funding_proposal.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use async_trait::async_trait; use namada_sdk::{ - args::{InitProposal, TxBuilder}, + args::InitProposal, governance::{ cli::onchain::{OnChainProposal, PgfFunding, PgfFundingProposal}, storage::{ diff --git a/src/tasks/init_pgf_steward_proposal.rs b/src/tasks/init_pgf_steward_proposal.rs index 8e7b0cb..71f03ee 100644 --- a/src/tasks/init_pgf_steward_proposal.rs +++ b/src/tasks/init_pgf_steward_proposal.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; use async_trait::async_trait; use namada_sdk::{ - args::{InitProposal, TxBuilder}, + args::InitProposal, governance::{ cli::onchain::{OnChainProposal, PgfStewardProposal, StewardsUpdate}, storage::keys::get_counter_key, diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 6ce943a..045fafb 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -31,7 +31,11 @@ pub mod init_pgf_steward_proposal; pub mod reactivate_validator; pub mod redelegate; pub mod reveal_pk; +pub mod shielded_sync; +pub mod tx_shielded_transfer; +pub mod tx_shielding_transfer; pub mod tx_transparent_transfer; +pub mod tx_unshielding_transfer; pub mod unbond; pub mod update_account; pub mod vote; @@ -42,6 +46,8 @@ pub mod withdraw; pub enum TaskError { #[error("error building tx `{0}`")] Build(String), + #[error("error fetching shielded context data `{0}`")] + ShieldedSync(String), } #[async_trait(?Send)] @@ -84,14 +90,25 @@ pub trait Task { match self.execute(sdk, parameters, settings, state).await { Ok(step_result) => step_result, - Err(e) => match e { - TaskError::Build(_) => StepResult::no_op(), - }, + Err(e) => { + match e { + TaskError::Build(e) => { + println!("tx build error: {e}"); + } + TaskError::ShieldedSync(e) => { + println!("shielded sync error: {e}"); + } + } + StepResult::no_op() + } } } async fn add_settings(&self, sdk: &Sdk, builder: Self::B, settings: TxSettings) -> Self::B { let builder = if let Some(signers) = settings.signers { + if signers.is_empty() { + return builder; + } let mut signing_keys = vec![]; for signer in signers { let public_key = signer.to_public_key(sdk).await; diff --git a/src/tasks/redelegate.rs b/src/tasks/redelegate.rs index 4fbf18e..e230155 100644 --- a/src/tasks/redelegate.rs +++ b/src/tasks/redelegate.rs @@ -1,10 +1,5 @@ use async_trait::async_trait; -use namada_sdk::{ - args::{Redelegate, TxBuilder}, - signing::default_sign, - token::Amount, - Namada, -}; +use namada_sdk::{args::Redelegate, signing::default_sign, token::Amount, Namada}; use rand::Rng; use serde::{Deserialize, Serialize}; diff --git a/src/tasks/shielded_sync.rs b/src/tasks/shielded_sync.rs new file mode 100644 index 0000000..7464d14 --- /dev/null +++ b/src/tasks/shielded_sync.rs @@ -0,0 +1,88 @@ +use async_trait::async_trait; +use namada_sdk::args::Bond; +use namada_sdk::control_flow::install_shutdown_signal; +use namada_sdk::io::DevNullProgressBar; +use namada_sdk::masp::utils::LedgerMaspClient; +use namada_sdk::masp::MaspLocalTaskEnv; +use namada_sdk::masp::ShieldedSyncConfig; +use namada_sdk::Namada; +use serde::{Deserialize, Serialize}; + +use super::{Task, TaskError, TaskParam}; +use crate::utils::settings::TxSettings; +use crate::{scenario::StepResult, sdk::namada::Sdk, state::state::Storage}; + +#[derive(Clone, Debug, Default)] +pub struct ShieldedSync {} + +impl ShieldedSync { + pub fn new() -> Self { + Self {} + } +} + +#[async_trait(?Send)] +impl Task for ShieldedSync { + type P = ShieldedSyncParameters; + type B = Bond; // just a placeholder + + async fn execute( + &self, + sdk: &Sdk, + _dto: Self::P, + _settings: TxSettings, + state: &Storage, + ) -> Result { + let maybe_height_to_sync = state.get_last_masp_tx_height(); + + let vks: Vec<_> = sdk + .namada + .wallet() + .await + .get_viewing_keys() + .values() + .map(|evk| evk.map(|key| key.as_viewing_key())) + .collect(); + + let mut shielded_ctx = sdk.namada.shielded_mut().await; + + let masp_client = LedgerMaspClient::new(sdk.namada.clone_client(), 100); + let task_env = + MaspLocalTaskEnv::new(4).map_err(|e| TaskError::ShieldedSync(e.to_string()))?; + let shutdown_signal = install_shutdown_signal(true); + + let config = ShieldedSyncConfig::builder() + .client(masp_client) + .fetched_tracker(DevNullProgressBar) + .scanned_tracker(DevNullProgressBar) + .applied_tracker(DevNullProgressBar) + .shutdown_signal(shutdown_signal); + + let config = if maybe_height_to_sync.is_some() { + config.wait_for_last_query_height(true).build() + } else { + config.build() + }; + + shielded_ctx + .sync(task_env, config, maybe_height_to_sync, &[], &vks) + .await + .map_err(|e| TaskError::ShieldedSync(e.to_string()))?; + + Ok(StepResult::default()) + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct ShieldedSyncParametersDto; + +#[derive(Clone, Debug)] +pub struct ShieldedSyncParameters; + +impl TaskParam for ShieldedSyncParameters { + type D = ShieldedSyncParametersDto; + + fn parameter_from_dto(_dto: Self::D, _state: &Storage) -> Option { + Some(ShieldedSyncParameters) + } +} diff --git a/src/tasks/tx_shielded_transfer.rs b/src/tasks/tx_shielded_transfer.rs new file mode 100644 index 0000000..1bbea0c --- /dev/null +++ b/src/tasks/tx_shielded_transfer.rs @@ -0,0 +1,226 @@ +use async_trait::async_trait; +use namada_sdk::rpc::TxResponse; +use namada_sdk::string_encoding::MASP_EXT_SPENDING_KEY_HRP; +use namada_sdk::tx::ProcessTxResponse; +use namada_sdk::{ + args::{InputAmount, TxShieldedTransfer as NamadaTxShieldedTransfer, TxShieldedTransferData}, + signing::default_sign, + string_encoding::MASP_PAYMENT_ADDRESS_HRP, + token::{self, DenominatedAmount}, + Namada, +}; +use serde::{Deserialize, Serialize}; + +use crate::utils::settings::TxSettings; +use crate::{ + entity::address::{AccountIndentifier, ADDRESS_PREFIX}, + scenario::StepResult, + sdk::namada::Sdk, + state::state::{StepStorage, Storage}, + utils::value::Value, +}; + +use super::{Task, TaskError, TaskParam}; + +pub enum TxShieldedTransferStorageKeys { + Source, + Target, + Amount, + Token, +} + +impl ToString for TxShieldedTransferStorageKeys { + fn to_string(&self) -> String { + match self { + TxShieldedTransferStorageKeys::Source => "source".to_string(), + TxShieldedTransferStorageKeys::Target => "target".to_string(), + TxShieldedTransferStorageKeys::Amount => "amount".to_string(), + TxShieldedTransferStorageKeys::Token => "token".to_string(), + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct TxShieldedTransfer {} + +impl TxShieldedTransfer { + pub fn new() -> Self { + Self {} + } +} + +#[async_trait(?Send)] +impl Task for TxShieldedTransfer { + type P = TxShieldedTransferParameters; + type B = NamadaTxShieldedTransfer; + + async fn execute( + &self, + sdk: &Sdk, + parameters: Self::P, + settings: TxSettings, + _state: &Storage, + ) -> Result { + let source_address = parameters.source.to_spending_key(sdk).await; + let target_address = parameters.target.to_payment_address(sdk).await; + let token_address = parameters.token.to_namada_address(sdk).await; + + let token_amount = token::Amount::from_u64(parameters.amount); + let denominated_amount = DenominatedAmount::native(token_amount); + + let tx_transfer_data = TxShieldedTransferData { + source: source_address.clone(), + target: target_address.clone(), + token: token_address.clone(), + amount: InputAmount::Validated(denominated_amount), + }; + + let transfer_tx_builder = sdk + .namada + .new_shielded_transfer(vec![tx_transfer_data], vec![]); + + let mut transfer_tx_builder = self.add_settings(sdk, transfer_tx_builder, settings).await; + + let (mut transfer_tx, signing_data) = transfer_tx_builder + .build(&sdk.namada) + .await + .map_err(|err| TaskError::Build(err.to_string()))?; + + sdk.namada + .sign( + &mut transfer_tx, + &transfer_tx_builder.tx, + signing_data, + default_sign, + (), + ) + .await + .map_err(|err| TaskError::Build(err.to_string()))?; + let tx = sdk + .namada + .submit(transfer_tx.clone(), &transfer_tx_builder.tx) + .await; + + let mut storage = StepStorage::default(); + self.fetch_info(sdk, &mut storage).await; + + if Self::is_tx_rejected(&transfer_tx, &tx) { + let errors = Self::get_tx_errors(&transfer_tx, &tx.unwrap()).unwrap_or_default(); + return Ok(StepResult::fail(errors)); + } + + let Ok(ProcessTxResponse::Applied(TxResponse { height, .. })) = &tx else { + unreachable!() + }; + + storage.add( + TxShieldedTransferStorageKeys::Source.to_string(), + source_address.to_string(), + ); + storage.add( + TxShieldedTransferStorageKeys::Target.to_string(), + target_address.to_string(), + ); + storage.add( + TxShieldedTransferStorageKeys::Amount.to_string(), + token_amount.raw_amount().to_string(), + ); + storage.add( + TxShieldedTransferStorageKeys::Token.to_string(), + token_address.to_string(), + ); + storage.add("stx-height".to_string(), height.to_string()); + + Ok(StepResult::success(storage)) + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct TxShieldedTransferParametersDto { + pub source: Value, + pub target: Value, + pub amount: Value, + pub token: Value, +} + +#[derive(Clone, Debug)] +pub struct TxShieldedTransferParameters { + source: AccountIndentifier, + target: AccountIndentifier, + amount: u64, + token: AccountIndentifier, +} + +impl TaskParam for TxShieldedTransferParameters { + type D = TxShieldedTransferParametersDto; + + fn parameter_from_dto(dto: Self::D, state: &Storage) -> Option { + let source = match dto.source { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + _ => AccountIndentifier::SpendingKey(data), + } + } + Value::Value { value } => { + if value.starts_with(MASP_EXT_SPENDING_KEY_HRP) { + AccountIndentifier::SpendingKey(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + let target = match dto.target { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + _ => AccountIndentifier::PaymentAddress(data), + } + } + Value::Value { value } => { + if value.starts_with(MASP_PAYMENT_ADDRESS_HRP) { + AccountIndentifier::PaymentAddress(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + let amount = match dto.amount { + Value::Ref { value, field } => { + state.get_step_item(&value, &field).parse::().ok()? + } + Value::Value { value } => value.parse::().ok()?, + Value::Fuzz { .. } => unimplemented!(), + }; + let token = match dto.token { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + "public-key" => AccountIndentifier::PublicKey(data), + "state" => AccountIndentifier::StateAddress(state.get_address(&data)), + _ => AccountIndentifier::Address(data), + } + } + Value::Value { value } => { + if value.starts_with(ADDRESS_PREFIX) { + AccountIndentifier::Address(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + + Some(Self { + source, + target, + amount, + token, + }) + } +} diff --git a/src/tasks/tx_shielding_transfer.rs b/src/tasks/tx_shielding_transfer.rs new file mode 100644 index 0000000..248c6b4 --- /dev/null +++ b/src/tasks/tx_shielding_transfer.rs @@ -0,0 +1,228 @@ +use async_trait::async_trait; +use namada_sdk::rpc::TxResponse; +use namada_sdk::tx::ProcessTxResponse; +use namada_sdk::{ + args::{ + InputAmount, TxShieldingTransfer as NamadaTxShieldingTransfer, TxShieldingTransferData, + }, + signing::default_sign, + string_encoding::MASP_PAYMENT_ADDRESS_HRP, + token::{self, DenominatedAmount}, + Namada, +}; +use serde::{Deserialize, Serialize}; + +use crate::utils::settings::TxSettings; +use crate::{ + entity::address::{AccountIndentifier, ADDRESS_PREFIX}, + scenario::StepResult, + sdk::namada::Sdk, + state::state::{StepStorage, Storage}, + utils::value::Value, +}; + +use super::{Task, TaskError, TaskParam}; + +pub enum TxShieldingTransferStorageKeys { + Source, + Target, + Amount, + Token, +} + +impl ToString for TxShieldingTransferStorageKeys { + fn to_string(&self) -> String { + match self { + TxShieldingTransferStorageKeys::Source => "source".to_string(), + TxShieldingTransferStorageKeys::Target => "target".to_string(), + TxShieldingTransferStorageKeys::Amount => "amount".to_string(), + TxShieldingTransferStorageKeys::Token => "token".to_string(), + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct TxShieldingTransfer {} + +impl TxShieldingTransfer { + pub fn new() -> Self { + Self {} + } +} + +#[async_trait(?Send)] +impl Task for TxShieldingTransfer { + type P = TxShieldingTransferParameters; + type B = NamadaTxShieldingTransfer; + + async fn execute( + &self, + sdk: &Sdk, + parameters: Self::P, + settings: TxSettings, + _state: &Storage, + ) -> Result { + let source_address = parameters.source.to_namada_address(sdk).await; + let target_address = parameters.target.to_payment_address(sdk).await; + let token_address = parameters.token.to_namada_address(sdk).await; + + let token_amount = token::Amount::from_u64(parameters.amount); + let denominated_amount = DenominatedAmount::native(token_amount); + + let tx_transfer_data = TxShieldingTransferData { + source: source_address.clone(), + token: token_address.clone(), + amount: InputAmount::Validated(denominated_amount), + }; + + let transfer_tx_builder = sdk + .namada + .new_shielding_transfer(target_address, vec![tx_transfer_data]); + + let mut transfer_tx_builder = self.add_settings(sdk, transfer_tx_builder, settings).await; + + let (mut transfer_tx, signing_data, _epoch) = transfer_tx_builder + .build(&sdk.namada) + .await + .map_err(|err| TaskError::Build(err.to_string()))?; + + sdk.namada + .sign( + &mut transfer_tx, + &transfer_tx_builder.tx, + signing_data, + default_sign, + (), + ) + .await + .map_err(|err| TaskError::Build(err.to_string()))?; + let tx = sdk + .namada + .submit(transfer_tx.clone(), &transfer_tx_builder.tx) + .await; + + let mut storage = StepStorage::default(); + self.fetch_info(sdk, &mut storage).await; + + if Self::is_tx_rejected(&transfer_tx, &tx) { + let errors = Self::get_tx_errors(&transfer_tx, &tx.unwrap()).unwrap_or_default(); + return Ok(StepResult::fail(errors)); + } + + let Ok(ProcessTxResponse::Applied(TxResponse { height, .. })) = &tx else { + unreachable!() + }; + + storage.add( + TxShieldingTransferStorageKeys::Source.to_string(), + source_address.to_string(), + ); + storage.add( + TxShieldingTransferStorageKeys::Target.to_string(), + target_address.to_string(), + ); + storage.add( + TxShieldingTransferStorageKeys::Amount.to_string(), + token_amount.raw_amount().to_string(), + ); + storage.add( + TxShieldingTransferStorageKeys::Token.to_string(), + token_address.to_string(), + ); + storage.add("stx-height".to_string(), height.to_string()); + + Ok(StepResult::success(storage)) + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct TxShieldingTransferParametersDto { + pub source: Value, + pub target: Value, + pub amount: Value, + pub token: Value, +} + +#[derive(Clone, Debug)] +pub struct TxShieldingTransferParameters { + source: AccountIndentifier, + target: AccountIndentifier, + amount: u64, + token: AccountIndentifier, +} + +impl TaskParam for TxShieldingTransferParameters { + type D = TxShieldingTransferParametersDto; + + fn parameter_from_dto(dto: Self::D, state: &Storage) -> Option { + let source = match dto.source { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + "public-key" => AccountIndentifier::PublicKey(data), + "state" => AccountIndentifier::StateAddress(state.get_address(&data)), + _ => AccountIndentifier::Address(data), + } + } + Value::Value { value } => { + if value.starts_with(ADDRESS_PREFIX) { + AccountIndentifier::Address(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + let target = match dto.target { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + _ => AccountIndentifier::PaymentAddress(data), + } + } + Value::Value { value } => { + if value.starts_with(MASP_PAYMENT_ADDRESS_HRP) { + AccountIndentifier::PaymentAddress(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + let amount = match dto.amount { + Value::Ref { value, field } => { + state.get_step_item(&value, &field).parse::().ok()? + } + Value::Value { value } => value.parse::().ok()?, + Value::Fuzz { .. } => unimplemented!(), + }; + let token = match dto.token { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + "public-key" => AccountIndentifier::PublicKey(data), + "state" => AccountIndentifier::StateAddress(state.get_address(&data)), + _ => AccountIndentifier::Address(data), + } + } + Value::Value { value } => { + if value.starts_with(ADDRESS_PREFIX) { + AccountIndentifier::Address(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + + Some(Self { + source, + target, + amount, + token, + }) + } +} diff --git a/src/tasks/tx_transparent_transfer.rs b/src/tasks/tx_transparent_transfer.rs index 23da569..81538d5 100644 --- a/src/tasks/tx_transparent_transfer.rs +++ b/src/tasks/tx_transparent_transfer.rs @@ -67,7 +67,7 @@ impl Task for TxTransparentTransfer { source: source_address.clone(), target: target_address.clone(), token: token_address.clone(), - amount: InputAmount::Unvalidated(DenominatedAmount::native(token_amount.clone())), + amount: InputAmount::Unvalidated(DenominatedAmount::native(token_amount)), }; let transfer_tx_builder = sdk.namada.new_transparent_transfer(vec![tx_transfer_data]); diff --git a/src/tasks/tx_unshielding_transfer.rs b/src/tasks/tx_unshielding_transfer.rs new file mode 100644 index 0000000..5a9ae95 --- /dev/null +++ b/src/tasks/tx_unshielding_transfer.rs @@ -0,0 +1,258 @@ +use async_trait::async_trait; +use namada_sdk::rpc::TxResponse; +use namada_sdk::tx::ProcessTxResponse; +use namada_sdk::{ + args::{ + InputAmount, TxUnshieldingTransfer as NamadaTxUnshieldingTransfer, + TxUnshieldingTransferData, + }, + args::{NamadaTypes, SdkTypes, Tx, TxBuilder, TxExpiration}, + signing::default_sign, + string_encoding::MASP_EXT_SPENDING_KEY_HRP, + token::{self, DenominatedAmount}, + Namada, +}; +use serde::{Deserialize, Serialize}; + +use crate::utils::settings::TxSettings; +use crate::{ + entity::address::{AccountIndentifier, ADDRESS_PREFIX}, + scenario::StepResult, + sdk::namada::Sdk, + state::state::{StepStorage, Storage}, + utils::value::Value, +}; + +use super::{Task, TaskError, TaskParam}; + +pub struct UnshieldingTransferBuilder(NamadaTxUnshieldingTransfer) +where + C: NamadaTypes; + +impl TxBuilder for UnshieldingTransferBuilder { + fn tx(self, func: F) -> Self + where + F: FnOnce(Tx) -> Tx, + { + Self(NamadaTxUnshieldingTransfer { + tx: func(self.0.tx), + ..self.0 + }) + } +} + +pub enum TxUnshieldingTransferStorageKeys { + Source, + Target, + Amount, + Token, +} + +impl ToString for TxUnshieldingTransferStorageKeys { + fn to_string(&self) -> String { + match self { + TxUnshieldingTransferStorageKeys::Source => "source".to_string(), + TxUnshieldingTransferStorageKeys::Target => "target".to_string(), + TxUnshieldingTransferStorageKeys::Amount => "amount".to_string(), + TxUnshieldingTransferStorageKeys::Token => "token".to_string(), + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct TxUnshieldingTransfer {} + +impl TxUnshieldingTransfer { + pub fn new() -> Self { + Self {} + } +} + +#[async_trait(?Send)] +impl Task for TxUnshieldingTransfer { + type P = TxUnshieldingTransferParameters; + type B = UnshieldingTransferBuilder; + + async fn execute( + &self, + sdk: &Sdk, + parameters: Self::P, + settings: TxSettings, + _state: &Storage, + ) -> Result { + let source_address = parameters.target.to_spending_key(sdk).await; + let target_address = parameters.source.to_namada_address(sdk).await; + let token_address = parameters.token.to_namada_address(sdk).await; + + let token_amount = token::Amount::from_u64(parameters.amount); + let denominated_amount = DenominatedAmount::native(token_amount); + + let tx_transfer_data = TxUnshieldingTransferData { + target: target_address.clone(), + token: token_address.clone(), + amount: InputAmount::Validated(denominated_amount), + }; + + let mut transfer_tx_builder = UnshieldingTransferBuilder( + sdk.namada + .new_unshielding_transfer(source_address, vec![tx_transfer_data], vec![]), + ); + + transfer_tx_builder.0.tx.signing_keys = vec![ + settings + .gas_payer + .as_ref() + .ok_or_else(|| TaskError::Build("No gas payer was present".into()))? + .to_public_key(sdk) + .await, + ]; + + transfer_tx_builder.0.tx.expiration = TxExpiration::NoExpiration; + let UnshieldingTransferBuilder(mut transfer_tx_builder) = + self.add_settings(sdk, transfer_tx_builder, settings).await; + + let (mut transfer_tx, signing_data) = transfer_tx_builder + .build(&sdk.namada) + .await + .map_err(|err| TaskError::Build(err.to_string()))?; + + sdk.namada + .sign( + &mut transfer_tx, + &transfer_tx_builder.tx, + signing_data, + default_sign, + (), + ) + .await + .map_err(|err| TaskError::Build(err.to_string()))?; + let tx = sdk + .namada + .submit(transfer_tx.clone(), &transfer_tx_builder.tx) + .await; + + let mut storage = StepStorage::default(); + self.fetch_info(sdk, &mut storage).await; + + if Self::is_tx_rejected(&transfer_tx, &tx) { + let errors = Self::get_tx_errors(&transfer_tx, &tx.unwrap()).unwrap_or_default(); + return Ok(StepResult::fail(errors)); + } + + let Ok(ProcessTxResponse::Applied(TxResponse { height, .. })) = &tx else { + unreachable!() + }; + + storage.add( + TxUnshieldingTransferStorageKeys::Source.to_string(), + source_address.to_string(), + ); + storage.add( + TxUnshieldingTransferStorageKeys::Target.to_string(), + target_address.to_string(), + ); + storage.add( + TxUnshieldingTransferStorageKeys::Amount.to_string(), + token_amount.raw_amount().to_string(), + ); + storage.add( + TxUnshieldingTransferStorageKeys::Token.to_string(), + token_address.to_string(), + ); + storage.add("stx-height".to_string(), height.to_string()); + + Ok(StepResult::success(storage)) + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct TxUnshieldingTransferParametersDto { + pub source: Value, + pub target: Value, + pub amount: Value, + pub token: Value, +} + +#[derive(Clone, Debug)] +pub struct TxUnshieldingTransferParameters { + source: AccountIndentifier, + target: AccountIndentifier, + amount: u64, + token: AccountIndentifier, +} + +impl TaskParam for TxUnshieldingTransferParameters { + type D = TxUnshieldingTransferParametersDto; + + fn parameter_from_dto(dto: Self::D, state: &Storage) -> Option { + let source = match dto.source { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + _ => AccountIndentifier::SpendingKey(data), + } + } + Value::Value { value } => { + if value.starts_with(MASP_EXT_SPENDING_KEY_HRP) { + AccountIndentifier::SpendingKey(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + let target = match dto.target { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + "public-key" => AccountIndentifier::PublicKey(data), + "state" => AccountIndentifier::StateAddress(state.get_address(&data)), + _ => AccountIndentifier::Address(data), + } + } + Value::Value { value } => { + if value.starts_with(ADDRESS_PREFIX) { + AccountIndentifier::Address(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + let amount = match dto.amount { + Value::Ref { value, field } => { + state.get_step_item(&value, &field).parse::().ok()? + } + Value::Value { value } => value.parse::().ok()?, + Value::Fuzz { .. } => unimplemented!(), + }; + let token = match dto.token { + Value::Ref { value, field } => { + let data = state.get_step_item(&value, &field); + match field.to_lowercase().as_str() { + "alias" => AccountIndentifier::Alias(data), + "public-key" => AccountIndentifier::PublicKey(data), + "state" => AccountIndentifier::StateAddress(state.get_address(&data)), + _ => AccountIndentifier::Address(data), + } + } + Value::Value { value } => { + if value.starts_with(ADDRESS_PREFIX) { + AccountIndentifier::Address(value) + } else { + AccountIndentifier::Alias(value) + } + } + Value::Fuzz { .. } => unimplemented!(), + }; + + Some(Self { + source, + target, + amount, + token, + }) + } +} diff --git a/src/tasks/update_account.rs b/src/tasks/update_account.rs index 7164faf..6c15976 100644 --- a/src/tasks/update_account.rs +++ b/src/tasks/update_account.rs @@ -11,10 +11,7 @@ use crate::{ state::state::{StepStorage, Storage}, utils::{settings::TxSettings, value::Value}, }; -use namada_sdk::{ - args::{TxBuilder, TxUpdateAccount as SdkUpdateAccountTx}, - signing::default_sign, -}; +use namada_sdk::{args::TxUpdateAccount as SdkUpdateAccountTx, signing::default_sign}; use namada_sdk::{tx::VP_USER_WASM, Namada}; use super::{Task, TaskError, TaskParam}; diff --git a/src/tasks/wallet_new_key.rs b/src/tasks/wallet_new_key.rs index 5b49104..5c29c8c 100644 --- a/src/tasks/wallet_new_key.rs +++ b/src/tasks/wallet_new_key.rs @@ -1,5 +1,7 @@ use async_trait::async_trait; use namada_sdk::args::Bond; +use namada_sdk::masp::{find_valid_diversifier, PaymentAddress}; +use namada_sdk::masp_primitives::zip32; use namada_sdk::{address::Address, key::SchemeType}; use rand::rngs::OsRng; use rand::{distributions::Alphanumeric, Rng}; @@ -20,6 +22,8 @@ pub enum WalletNewKeyStorageKeys { PrivateKey, PublicKey, Address, + PaymentAddress, + SpendingKey, } impl ToString for WalletNewKeyStorageKeys { @@ -29,6 +33,8 @@ impl ToString for WalletNewKeyStorageKeys { WalletNewKeyStorageKeys::Alias => "alias".to_string(), WalletNewKeyStorageKeys::PublicKey => "public-key".to_string(), WalletNewKeyStorageKeys::PrivateKey => "private-key".to_string(), + WalletNewKeyStorageKeys::PaymentAddress => "payment-address".to_string(), + WalletNewKeyStorageKeys::SpendingKey => "spending-key".to_string(), } } } @@ -82,6 +88,33 @@ impl Task for WalletNewKey { let address = Address::from(&sk.ref_to()).to_string(); + // this also generates and store in the wallet the viewing key (witht he same alias) + let spending_key_alias = format!("{}-masp", alias); + let spending_key = + wallet.gen_store_spending_key(spending_key_alias.clone(), None, None, true, &mut OsRng); + + let (_, spending_key) = if let Some((alias, sk)) = spending_key { + wallet.save().expect("unable to save wallet"); + (alias, sk) + } else { + return Ok(StepResult::fail( + "Failed saving wallet spending key".to_string(), + )); + }; + + let viewing_key = zip32::ExtendedFullViewingKey::from(&spending_key.into()) + .fvk + .vk; + let (div, _g_d) = find_valid_diversifier(&mut OsRng); + let masp_payment_addr: namada_sdk::masp_primitives::sapling::PaymentAddress = viewing_key + .to_payment_address(div) + .expect("a PaymentAddress"); + let payment_addr = PaymentAddress::from(masp_payment_addr); + + let payment_address_alias = format!("{}-pa", alias); + wallet.insert_payment_addr(payment_address_alias, payment_addr, true); + wallet.save().expect("unable to save wallet"); + let mut storage = StepStorage::default(); storage.add( WalletNewKeyStorageKeys::Alias.to_string(), @@ -99,6 +132,14 @@ impl Task for WalletNewKey { WalletNewKeyStorageKeys::PrivateKey.to_string(), sk.to_string(), ); + storage.add( + WalletNewKeyStorageKeys::PaymentAddress.to_string(), + payment_addr.to_string(), + ); + storage.add( + WalletNewKeyStorageKeys::SpendingKey.to_string(), + spending_key.to_string(), + ); let address = StateAddress::new_implicit(alias, address);