diff --git a/.github/codespell/words.txt b/.github/codespell/words.txt index d15ff15549..eed2287f50 100644 --- a/.github/codespell/words.txt +++ b/.github/codespell/words.txt @@ -2,3 +2,6 @@ crate shs ser numer +nam +inout +wast diff --git a/.github/workflows/cargo-doc.yaml b/.github/workflows/cargo-doc.yaml index 9682a8456f..06e19ab0ae 100644 --- a/.github/workflows/cargo-doc.yaml +++ b/.github/workflows/cargo-doc.yaml @@ -29,6 +29,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: nightly-2024-04-21 + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Build API documentation uses: actions-rs/cargo@v1 env: diff --git a/.github/workflows/guide-templates.yaml b/.github/workflows/guide-templates.yaml index 9eefc0d3fc..76152d6513 100644 --- a/.github/workflows/guide-templates.yaml +++ b/.github/workflows/guide-templates.yaml @@ -31,13 +31,13 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Check templates run: bash scripts/auto_gen_templates.sh --mode "check" - - uses: actions-rs/cargo@v1 - name: Update lockfile - with: - command: generate-lockfile - args: --manifest-path tools/check-guide/Cargo.toml - uses: actions-rs/cargo@v1 name: Check guide with: diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index 8fc11af9bd..a03774dc99 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -111,6 +111,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test @@ -149,6 +154,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test @@ -192,6 +202,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test @@ -234,6 +249,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test @@ -276,6 +296,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test @@ -317,6 +342,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test diff --git a/.github/workflows/misbehaviour.yml b/.github/workflows/misbehaviour.yml index 77016f5354..9eb41bb979 100644 --- a/.github/workflows/misbehaviour.yml +++ b/.github/workflows/misbehaviour.yml @@ -80,6 +80,11 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Build Hermes uses: actions-rs/cargo@v1 with: @@ -132,6 +137,11 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Build Hermes uses: actions-rs/cargo@v1 with: @@ -184,6 +194,11 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Build Hermes uses: actions-rs/cargo@v1 with: @@ -237,6 +252,11 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Build Hermes uses: actions-rs/cargo@v1 with: diff --git a/.github/workflows/multi-chains.yaml b/.github/workflows/multi-chains.yaml index 9e23d3a5a2..0d3c18baa3 100644 --- a/.github/workflows/multi-chains.yaml +++ b/.github/workflows/multi-chains.yaml @@ -96,6 +96,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/cargo@v1 with: command: test diff --git a/.github/workflows/namada.yaml b/.github/workflows/namada.yaml new file mode 100644 index 0000000000..8198ab2674 --- /dev/null +++ b/.github/workflows/namada.yaml @@ -0,0 +1,189 @@ +name: Namada Integration + +on: + workflow_dispatch: + pull_request: + paths: + - .github/workflows/integration.yaml + - Cargo.toml + - Cargo.lock + - flake.nix + - flake.lock + - ci/** + - e2e/** + - crates/** + - tools/** + +env: + CARGO_INCREMENTAL: 0 + CARGO_PROFILE_DEV_DEBUG: 1 + CARGO_PROFILE_RELEASE_DEBUG: 1 + RUST_BACKTRACE: short + CARGO_NET_RETRY: 10 + RUSTUP_MAX_RETRIES: 10 + +# Cancel previous runs of this workflow when a new commit is added to the PR, branch or tag +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + gaia-namada: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + chain: + - package: .#gaia15 + command: gaiad,namada + account_prefix: cosmos,'' + native_token: stake,nam + steps: + - uses: actions/checkout@v4 + - name: Clone Namada + uses: actions/checkout@v4 + with: + repository: anoma/namada + ref: yuji/for-hermes-ci + path: namada + - name: Retrieve Namada repository path + id: namada-repo-path + run: | + echo "NAMADA_REPO_PATH=$(pwd)/namada" >> "$GITHUB_ENV" + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + with: + extra-conf: | + substituters = https://cache.nixos.org + trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= + - name: Install Cachix + uses: cachix/cachix-action@v14 + with: + name: cosmos-nix + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + - name: Install libudev + run: sudo apt-get update && sudo apt-get -y install libudev-dev + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions-rs/cargo@v1 + with: + command: test + args: -p ibc-integration-test --features namada --no-fail-fast --no-run + - name: Install cargo-nextest + run: curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin + - name: Download CometBFT + run: | + curl -o cometbft.tar.gz -LO https://github.com/cometbft/cometbft/releases/download/v0.37.2/cometbft_0.37.2_linux_amd64.tar.gz + tar -xvzf cometbft.tar.gz + chmod +x cometbft + mkdir -p $HOME/local/bin + mv cometbft ~/local/bin + - name: Download Namada binaries + env: + OPERATING_SYSTEM: Linux + run: | + release_url=$(curl -s "https://api.github.com/repos/anoma/namada/releases/159144175" | grep "browser_download_url" | cut -d '"' -f 4 | grep "$OPERATING_SYSTEM") + wget "$release_url" + tar -xzvf namada*.tar.gz + cp ./namada*/namadac ~/local/bin/namadac + cp ./namada*/namadan ~/local/bin/namadan + cp ./namada*/namadaw ~/local/bin/namadaw + cp ./namada*/namada ~/local/bin/namada + - name: Update environment path + run: | + echo "${HOME}/local/bin" >> $GITHUB_PATH + - name: Download MASP parameters + run: | + echo $HOME + mkdir -p $HOME/.masp-params + curl -o $HOME/.masp-params/masp-spend.params -L https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-spend.params\?raw\=true + curl -o $HOME/.masp-params/masp-output.params -L https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-output.params?raw=true + curl -o $HOME/.masp-params/masp-convert.params -L https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-convert.params?raw=true + - env: + RUST_LOG: info + RUST_BACKTRACE: 1 + NO_COLOR_LOG: 1 + CHAIN_COMMAND_PATHS: ${{ matrix.chain.command }} + ACCOUNT_PREFIXES: ${{ matrix.chain.account_prefix }} + NATIVE_TOKENS: ${{ matrix.chain.native_token }} + run: | + nix shell ${{ matrix.chain.package }} -c \ + cargo nextest run -p ibc-integration-test --no-fail-fast --failure-output final --test-threads=1 \ + --features namada + + namada: + runs-on: ubuntu-22.04 + strategy: + fail-fast: false + steps: + - uses: actions/checkout@v4 + - name: Clone Namada + uses: actions/checkout@v4 + with: + repository: anoma/namada + ref: yuji/for-hermes-ci + path: namada + - name: Retrieve Namada repository path + id: namada-repo-path + run: | + echo "NAMADA_REPO_PATH=$(pwd)/namada" >> "$GITHUB_ENV" + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: stable + - name: Install libudev + run: sudo apt-get update && sudo apt-get -y install libudev-dev + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: actions-rs/cargo@v1 + with: + command: test + args: -p ibc-integration-test --features namada --no-fail-fast --no-run + - name: Install cargo-nextest + run: curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin + - name: Download CometBFT + run: | + curl -o cometbft.tar.gz -LO https://github.com/cometbft/cometbft/releases/download/v0.37.2/cometbft_0.37.2_linux_amd64.tar.gz + tar -xvzf cometbft.tar.gz + mkdir -p ~/local/bin + chmod +x cometbft + mv cometbft ~/local/bin + - name: Download Namada binaries + env: + OPERATING_SYSTEM: Linux + run: | + release_url=$(curl -s "https://api.github.com/repos/anoma/namada/releases/159144175" | grep "browser_download_url" | cut -d '"' -f 4 | grep "$OPERATING_SYSTEM") + wget "$release_url" + tar -xzvf namada*.tar.gz + cp ./namada*/namadac ~/local/bin/namadac + cp ./namada*/namadan ~/local/bin/namadan + cp ./namada*/namadaw ~/local/bin/namadaw + cp ./namada*/namada ~/local/bin/namada + - name: Update environment path + run: | + echo "${HOME}/local/bin" >> $GITHUB_PATH + - name: Download MASP parameters + run: | + echo $HOME + mkdir -p $HOME/.masp-params + curl -o $HOME/.masp-params/masp-spend.params -L https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-spend.params\?raw\=true + curl -o $HOME/.masp-params/masp-output.params -L https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-output.params?raw=true + curl -o $HOME/.masp-params/masp-convert.params -L https://github.com/anoma/masp-mpc/releases/download/namada-trusted-setup/masp-convert.params?raw=true + - env: + RUST_LOG: info + RUST_BACKTRACE: 1 + NO_COLOR_LOG: 1 + CHAIN_COMMAND_PATHS: namada + ACCOUNT_PREFIXES: '' + NATIVE_TOKENS: nam + run: | + cargo nextest run -p ibc-integration-test --no-fail-fast --failure-output final --test-threads=1 \ + --features namada + diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 42106466c5..34e99fd9f6 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,6 +14,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: katyo/publish-crates@v2 with: registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b1f7b3a39c..20dd2d8ab2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,11 @@ jobs: runs-on: ${{ matrix.config.os }} steps: - uses: actions/checkout@v4 + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: taiki-e/upload-rust-binary-action@v1 with: # (required) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index bc19b03142..38aa9b9ac9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -54,6 +54,11 @@ jobs: with: toolchain: stable components: clippy + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/clippy-check@v1 with: name: clippy-all-features @@ -68,6 +73,11 @@ jobs: with: toolchain: stable components: clippy + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - uses: actions-rs/clippy-check@v1 with: name: clippy-no-default-features @@ -82,6 +92,11 @@ jobs: - uses: actions-rust-lang/setup-rust-toolchain@v1 with: toolchain: stable + - name: Install Protoc + uses: heliaxdev/setup-protoc@v2 + with: + version: "25.0" + repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Install cargo-nextest run: curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin - uses: actions-rs/cargo@v1 diff --git a/Cargo.lock b/Cargo.lock index 2a401e1ae8..3718548df1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "Inflector" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "abscissa_core" version = "0.6.0" @@ -18,7 +28,7 @@ dependencies = [ "once_cell", "regex", "secrecy", - "semver", + "semver 1.0.22", "serde", "termcolor", "toml 0.5.11", @@ -56,6 +66,38 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.14", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -65,50 +107,64 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", - "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.7" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -126,6 +182,91 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" +[[package]] +name = "ark-bls12-381" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65be532f9dd1e98ad0150b037276cde464c6f371059e6dd02c0222395761f6aa" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea978406c4b1ca13c2db2373b05cc55429c3575b8b21f1b9ee859aa5b03dd42" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "num-traits 0.2.18", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "num-bigint", + "num-traits 0.2.18", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits 0.2.18", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std", + "digest 0.9.0", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits 0.2.18", + "rand 0.8.5", +] + [[package]] name = "arrayref" version = "0.3.7" @@ -138,6 +279,15 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii-canvas" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] + [[package]] name = "async-stream" version = "0.3.5" @@ -157,7 +307,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -168,7 +318,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -185,7 +335,18 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", - "tungstenite", + "tungstenite 0.21.0", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version 0.4.0", ] [[package]] @@ -199,11 +360,22 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "autocfg" -version = "1.3.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" @@ -275,6 +447,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.7" @@ -283,9 +467,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.22.1" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" [[package]] name = "base64ct" @@ -293,6 +477,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bech32" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9ff0bbfd639f15c74af777d81383cf53efb7c93613f6cab67c6c11e05bbf8b" + [[package]] name = "bech32" version = "0.9.1" @@ -305,6 +495,60 @@ version = "0.10.0-beta" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea" +[[package]] +name = "bellman" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afceed28bac7f9f5a508bca8aeeff51cdfa4770c0b967ac55c621e2ddfd6171" +dependencies = [ + "bitvec", + "blake2s_simd", + "byteorder", + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "bimap" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "230c5f1ca6a325a32553f8640d31ac9b49f2411e901e427570154868b46da4f7" +dependencies = [ + "serde", +] + +[[package]] +name = "bip0039" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568b6890865156d9043af490d4c4081c385dd68ea10acd6ca15733d511e6b51c" +dependencies = [ + "hmac 0.12.1", + "pbkdf2 0.12.2", + "rand 0.8.5", + "sha2 0.10.8", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitcoin" version = "0.31.2" @@ -351,6 +595,21 @@ name = "bitflags" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] [[package]] name = "blake2" @@ -361,6 +620,28 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "blake2b_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq 0.3.0", +] + +[[package]] +name = "blake2s_simd" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94230421e395b9920d23df13ea5d77a20e1725331f90fbbf6df6040b33f756ae" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq 0.3.0", +] + [[package]] name = "blake3" version = "1.5.1" @@ -371,7 +652,7 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq", + "constant_time_eq 0.3.0", ] [[package]] @@ -392,12 +673,103 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bls12_381" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc6d6292be3a19e6379786dac800f551e5865a5bb51ebbe3064ab80433f403" +dependencies = [ + "ff", + "group", + "pairing", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive 0.10.3", + "hashbrown 0.12.3", +] + +[[package]] +name = "borsh" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbe5b10e214954177fb1dc9fbd20a1a2608fe99e6c832033bdc7cea287a20d77" +dependencies = [ + "borsh-derive 1.5.0", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal", + "borsh-schema-derive-internal", + "proc-macro-crate 0.1.5", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a8646f94ab393e43e8b35a2558b1624bed28b97ee09c5d15456e3c9463f46d" +dependencies = [ + "once_cell", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.60", + "syn_derive", +] + +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "borsh-ext" +version = "1.2.0" +source = "git+https://github.com/heliaxdev/borsh-ext?tag=v1.2.0#a62fee3e847e512cad9ac0f1fd5a900e5db9ba37" +dependencies = [ + "borsh 1.5.0", +] + +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bs58" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ + "sha2 0.10.8", "tinyvec", ] @@ -407,6 +779,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + [[package]] name = "byte-unit" version = "4.0.19" @@ -433,16 +811,83 @@ dependencies = [ ] [[package]] -name = "canonical-path" -version = "2.0.2" +name = "bzip2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +dependencies = [ + "serde", +] + +[[package]] +name = "canonical-path" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e9e01327e6c86e92ec72b1c798d4a94810f147209bbe3ffab6a86954937a6f" + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.22", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] [[package]] name = "cc" -version = "1.0.98" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] [[package]] name = "cfg-if" @@ -450,6 +895,70 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits 0.2.18", + "wasm-bindgen", + "windows-targets 0.52.5", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "circular-queue" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d34327ead1c743a10db339de35fb58957564b99d248a67985c55638b22c59b5" +dependencies = [ + "version_check", +] + [[package]] name = "clap" version = "3.2.25" @@ -498,6 +1007,58 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "coins-bip32" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b6be4a5df2098cd811f3194f64ddb96c267606bffd9689ac7b0160097b01ad3" +dependencies = [ + "bs58", + "coins-core", + "digest 0.10.7", + "hmac 0.12.1", + "k256", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8fba409ce3dc04f7d804074039eb68b960b0829161f8e06c95fea3f122528" +dependencies = [ + "bitvec", + "coins-bip32", + "hmac 0.12.1", + "once_cell", + "pbkdf2 0.12.2", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5286a0843c21f8367f7be734f89df9b822e0321d8bcce8d6e735aadff7d74979" +dependencies = [ + "base64 0.21.7", + "bech32 0.9.1", + "bs58", + "digest 0.10.7", + "generic-array", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3", + "thiserror", +] + [[package]] name = "color-eyre" version = "0.6.3" @@ -527,9 +1088,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "console" @@ -544,12 +1105,37 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "const-hex" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8a24a26d37e1ffd45343323dc9fe6654ceea44c12f2fcb3d7ac29e610bc6" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const_panic" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "constant_time_eq" version = "0.3.0" @@ -592,12 +1178,31 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ + "crossbeam-epoch", "crossbeam-utils", ] @@ -612,9 +1217,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crunchy" @@ -629,7 +1234,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -644,6 +1249,31 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ct-codecs" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + [[package]] name = "curve25519-dalek" version = "4.1.2" @@ -656,7 +1286,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "platforms", - "rustc_version", + "rustc_version 0.4.0", "subtle", "zeroize", ] @@ -669,7 +1299,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -680,7 +1310,7 @@ checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" dependencies = [ "byteorder", "digest 0.9.0", - "rand_core", + "rand_core 0.6.4", "subtle-ng", "zeroize", ] @@ -692,7 +1322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown 0.14.5", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core", @@ -700,9 +1330,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -729,6 +1359,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -774,6 +1415,24 @@ dependencies = [ "subtle", ] +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -784,6 +1443,29 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -795,6 +1477,43 @@ dependencies = [ "winapi", ] +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "duration-str" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c1a2e028bbf7921549873b291ddc0cfe08b673d9489da81ac28898cd5a0e6e0" +dependencies = [ + "chrono", + "rust_decimal", + "serde", + "thiserror", + "time", + "winnow 0.6.8", +] + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + [[package]] name = "ecdsa" version = "0.16.9" @@ -805,6 +1524,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve", "rfc6979", + "serdect", "signature", "spki", ] @@ -828,8 +1548,10 @@ checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" dependencies = [ "curve25519-dalek-ng", "hex", - "rand_core", + "rand_core 0.6.4", + "serde", "sha2 0.9.9", + "thiserror", "zeroize", ] @@ -841,7 +1563,7 @@ checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", - "rand_core", + "rand_core 0.6.4", "serde", "sha2 0.10.8", "subtle", @@ -856,15 +1578,15 @@ checksum = "6b49a684b133c4980d7ee783936af771516011c8cd15f429dbda77245e282f03" dependencies = [ "derivation-path", "ed25519-dalek", - "hmac", + "hmac 0.12.1", "sha2 0.10.8", ] [[package]] name = "either" -version = "1.12.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" @@ -879,12 +1601,22 @@ dependencies = [ "generic-array", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", + "serdect", "subtle", "zeroize", ] +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -901,10 +1633,28 @@ dependencies = [ ] [[package]] -name = "env_filter" -version = "0.1.0" +name = "enr" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "2a3d8dc56e02f954cac8eb489772c552c473346fc34f67412bb6244fd647f7e4" +dependencies = [ + "base64 0.21.7", + "bytes", + "hex", + "k256", + "log", + "rand 0.8.5", + "rlp", + "serde", + "sha3", + "zeroize", +] + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" dependencies = [ "log", "regex", @@ -931,14 +1681,364 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac 0.12.1", + "pbkdf2 0.11.0", + "rand 0.8.5", + "scrypt", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3", + "thiserror", + "uuid 0.8.2", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak", +] + +[[package]] +name = "ethbridge-bridge-contract" +version = "0.24.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.24.0#d66708bb8a734111988b9eaf08c7473bd7020c00" +dependencies = [ + "ethbridge-bridge-events", + "ethbridge-structs", + "ethers", + "ethers-contract", +] + +[[package]] +name = "ethbridge-bridge-events" +version = "0.24.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.24.0#d66708bb8a734111988b9eaf08c7473bd7020c00" +dependencies = [ + "ethabi", + "ethbridge-structs", + "ethers", + "ethers-contract", +] + +[[package]] +name = "ethbridge-structs" +version = "0.24.0" +source = "git+https://github.com/heliaxdev/ethbridge-rs?tag=v0.24.0#d66708bb8a734111988b9eaf08c7473bd7020c00" +dependencies = [ + "ethabi", + "ethers", + "ethers-contract", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "816841ea989f0c69e459af1cf23a6b0033b19a55424a1ea3a30099becdb8dec0" +dependencies = [ + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-middleware", + "ethers-providers", + "ethers-signers", + "ethers-solc", +] + +[[package]] +name = "ethers-addressbook" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5495afd16b4faa556c3bba1f21b98b4983e53c1755022377051a975c3b021759" +dependencies = [ + "ethers-core", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "ethers-contract" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fceafa3578c836eeb874af87abacfb041f92b4da0a78a5edd042564b8ecdaaa" +dependencies = [ + "const-hex", + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04ba01fbc2331a38c429eb95d4a570166781f14290ef9fdb144278a90b5a739b" +dependencies = [ + "Inflector", + "const-hex", + "dunce", + "ethers-core", + "ethers-etherscan", + "eyre", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "reqwest", + "serde", + "serde_json", + "syn 2.0.60", + "toml 0.8.12", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87689dcabc0051cde10caaade298f9e9093d65f6125c14575db3fd8c669a168f" +dependencies = [ + "Inflector", + "const-hex", + "ethers-contract-abigen", + "ethers-core", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.60", +] + +[[package]] +name = "ethers-core" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82d80cc6ad30b14a48ab786523af33b37f28a8623fc06afd55324816ef18fb1f" +dependencies = [ + "arrayvec", + "bytes", + "cargo_metadata", + "chrono", + "const-hex", + "elliptic-curve", + "ethabi", + "generic-array", + "k256", + "num_enum", + "once_cell", + "open-fastrlp", + "rand 0.8.5", + "rlp", + "serde", + "serde_json", + "strum 0.26.2", + "syn 2.0.60", + "tempfile", + "thiserror", + "tiny-keccak", + "unicode-xid", +] + +[[package]] +name = "ethers-etherscan" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79e5973c26d4baf0ce55520bd732314328cabe53193286671b47144145b9649" +dependencies = [ + "chrono", + "ethers-core", + "reqwest", + "semver 1.0.22", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-middleware" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48f9fdf09aec667c099909d91908d5eaf9be1bd0e2500ba4172c1d28bfaa43de" +dependencies = [ + "async-trait", + "auto_impl", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-channel", + "futures-locks", + "futures-util", + "instant", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", +] + +[[package]] +name = "ethers-providers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6434c9a33891f1effc9c75472e12666db2fa5a0fec4b29af6221680a6fe83ab2" +dependencies = [ + "async-trait", + "auto_impl", + "base64 0.21.7", + "bytes", + "const-hex", + "enr", + "ethers-core", + "futures-core", + "futures-timer", + "futures-util", + "hashers", + "http 0.2.12", + "instant", + "jsonwebtoken", + "once_cell", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethers-signers" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228875491c782ad851773b652dd8ecac62cda8571d3bc32a5853644dd26766c2" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "const-hex", + "elliptic-curve", + "eth-keystore", + "ethers-core", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-solc" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66244a771d9163282646dbeffe0e6eca4dda4146b6498644e678ac6089b11edd" +dependencies = [ + "cfg-if", + "const-hex", + "dirs", + "dunce", + "ethers-core", + "glob", + "home", + "md-5", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver 1.0.22", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak", + "tokio", + "tracing", + "walkdir", + "yansi", +] + [[package]] name = "eyre" version = "0.6.12" @@ -951,9 +2051,20 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fd-lock" +version = "3.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" +dependencies = [ + "cfg-if", + "rustix", + "windows-sys 0.48.0", +] [[package]] name = "ff" @@ -961,15 +2072,16 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core", + "bitvec", + "rand_core 0.6.4", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" [[package]] name = "fixed-hash" @@ -977,9 +2089,28 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", "static_assertions", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flex-error" version = "0.4.4" @@ -1005,6 +2136,20 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fpe" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c4b37de5ae15812a764c958297cfc50f5c010438f60c6ce75d11b802abd404" +dependencies = [ + "cbc", + "cipher", + "libm", + "num-bigint", + "num-integer", + "num-traits 0.2.18", +] + [[package]] name = "fs-err" version = "2.11.0" @@ -1014,6 +2159,22 @@ dependencies = [ "autocfg", ] +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.30" @@ -1063,15 +2224,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] -name = "futures-macro" -version = "0.3.30" +name = "futures-locks" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.66", -] + "futures-channel", + "futures-task", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] [[package]] name = "futures-sink" @@ -1085,6 +2256,16 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers", + "send_wrapper 0.4.0", +] + [[package]] name = "futures-util" version = "0.3.30" @@ -1103,6 +2284,15 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1116,14 +2306,27 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -1133,6 +2336,24 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "group" version = "0.13.0" @@ -1140,7 +2361,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "memuse", + "rand_core 0.6.4", "subtle", ] @@ -1194,12 +2416,24 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hashers" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] [[package]] name = "hdpath" @@ -1239,9 +2473,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hex-conservative" -version = "0.1.2" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" +checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" [[package]] name = "hex_lit" @@ -1249,6 +2483,16 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1258,6 +2502,21 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hmac-sha512" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e806677ce663d0a199541030c816847b36e8dc095f70dae4a4f4ad63da5383" + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "http" version = "0.2.12" @@ -1352,7 +2611,7 @@ dependencies = [ "futures-util", "http 0.2.12", "hyper", - "rustls 0.21.12", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", ] @@ -1370,766 +2629,2411 @@ dependencies = [ ] [[package]] -name = "ibc-chain-registry" -version = "0.28.0" +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ - "async-trait", - "flex-error", - "futures", - "http 0.2.12", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ibc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9298a8de81eea8d496672e47f13ab1ae5145b3b554ec3951222197697e1cf82" +dependencies = [ + "ibc-apps", + "ibc-clients", + "ibc-core", + "ibc-core-host-cosmos", + "ibc-derive", + "ibc-primitives", +] + +[[package]] +name = "ibc-app-nft-transfer" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e4d7728ae132ecb49286f225d0ab6ad56b2a15af47e019da45ad23fd789d76f" +dependencies = [ + "ibc-app-nft-transfer-types", + "ibc-core", + "serde-json-wasm", +] + +[[package]] +name = "ibc-app-nft-transfer-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "333b2fcc0226d150e996fddd3fd2041460c7ed7e7594b65077026c7e38587329" +dependencies = [ + "base64 0.21.7", + "borsh 0.10.3", + "derive_more", + "displaydoc", + "http 1.1.0", + "ibc-app-transfer-types", + "ibc-core", "ibc-proto", - "ibc-relayer-types", - "itertools", - "reqwest", + "mime", + "parity-scale-codec", + "scale-info", + "schemars", "serde", - "serde_json", - "tendermint-rpc", - "tokio", - "tracing", + "serde-json-wasm", ] [[package]] -name = "ibc-integration-test" -version = "0.28.0" +name = "ibc-app-transfer" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf138e322daa7b757b66a8c9a5bcac00773136f4b939b6cfb43bb95576ba59d" dependencies = [ - "byte-unit", - "http 0.2.12", - "ibc-relayer", - "ibc-relayer-types", - "ibc-test-framework", - "prost", - "serde", - "serde_json", - "tempfile", - "tendermint", - "tendermint-rpc", - "time", - "toml 0.8.13", - "tonic", + "ibc-app-transfer-types", + "ibc-core", + "serde-json-wasm", ] [[package]] -name = "ibc-proto" -version = "0.44.0" +name = "ibc-app-transfer-types" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66080040d5a4800d52966d55b055400f86b79c34b854b935bef03c87aacda62a" +checksum = "4e8777875777e43f3c18a340ac5ea2223dc87a67b60d99e451142eac3b7b7a46" dependencies = [ - "base64 0.22.1", - "bytes", - "flex-error", - "ics23", - "informalsystems-pbjson", - "prost", + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core", + "ibc-proto", + "parity-scale-codec", + "primitive-types", + "scale-info", + "schemars", "serde", - "subtle-encoding", - "tendermint-proto", - "tonic", + "uint", ] [[package]] -name = "ibc-relayer" +name = "ibc-apps" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac849a9d4f6097cc81405b00428fd73b04ce5290d806ce7f5c8afd42fbfb9bd" +dependencies = [ + "ibc-app-nft-transfer", + "ibc-app-transfer", +] + +[[package]] +name = "ibc-chain-registry" version = "0.28.0" dependencies = [ - "anyhow", - "async-stream", - "bech32 0.9.1", - "bitcoin", - "bs58", - "byte-unit", - "bytes", - "crossbeam-channel", - "digest 0.10.7", - "dirs-next", - "ed25519", - "ed25519-dalek", - "ed25519-dalek-bip32", - "env_logger", + "async-trait", "flex-error", "futures", - "generic-array", - "hdpath", - "hex", "http 0.2.12", - "humantime", - "humantime-serde", "ibc-proto", "ibc-relayer-types", - "ibc-telemetry", - "itertools", - "moka", - "num-bigint", - "num-rational", - "once_cell", - "prost", - "regex", + "itertools 0.12.1", "reqwest", - "retry", - "ripemd", - "secp256k1", - "semver", "serde", - "serde_derive", "serde_json", - "serial_test", - "sha2 0.10.8", - "signature", - "strum", - "subtle-encoding", - "tendermint", - "tendermint-light-client", - "tendermint-light-client-detector", - "tendermint-light-client-verifier", - "tendermint-proto", "tendermint-rpc", - "tendermint-testgen", - "test-log", - "thiserror", - "tiny-bip39", - "tiny-keccak", "tokio", - "tokio-stream", - "toml 0.8.13", - "tonic", "tracing", - "tracing-subscriber", - "uuid", ] [[package]] -name = "ibc-relayer-cli" -version = "1.9.0" +name = "ibc-client-tendermint" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804dcd81f62608c453e72f669b2df986eb49d4b4381deac2a70bd33ee94cef7f" dependencies = [ - "abscissa_core", - "clap", - "clap_complete", - "color-eyre", - "console", - "crossbeam-channel", - "dialoguer", - "dirs-next", - "eyre", - "flex-error", - "futures", - "hdpath", - "http 0.2.12", - "humantime", - "ibc-chain-registry", - "ibc-relayer", - "ibc-relayer-rest", - "ibc-relayer-types", - "ibc-telemetry", - "itertools", - "once_cell", - "oneline-eyre", - "regex", + "derive_more", + "ibc-client-tendermint-types", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-primitives", "serde", - "serde_json", - "serial_test", - "signal-hook", - "subtle-encoding", "tendermint", "tendermint-light-client-verifier", - "tendermint-rpc", - "time", - "tokio", - "tracing", - "tracing-subscriber", ] [[package]] -name = "ibc-relayer-rest" -version = "0.28.0" +name = "ibc-client-tendermint-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b41444137be02cabc484079443f447d23e746fabd9ac6fd5d99faac0b30a5f" dependencies = [ - "axum", - "crossbeam-channel", - "ibc-relayer", - "ibc-relayer-types", - "reqwest", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", "serde", - "tokio", - "toml 0.8.13", - "tracing", + "tendermint", + "tendermint-light-client-verifier", + "tendermint-proto", ] [[package]] -name = "ibc-relayer-types" +name = "ibc-client-wasm-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcc05b707ee957b1272877606379647ae1e5897316a3406b6a93e1885ee99e68" +dependencies = [ + "base64 0.21.7", + "displaydoc", + "ibc-core-client", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", + "serde", +] + +[[package]] +name = "ibc-clients" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "675754a0a5f2f70f71445338fa4d8b49d3c84ce1cf4748ca6c98bf6ede9c4bfc" +dependencies = [ + "ibc-client-tendermint", + "ibc-client-wasm-types", +] + +[[package]] +name = "ibc-core" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb69c4ee05d367fa321acf67ec00d3e9f8ecfef013accdb05889db32ff2de3f" +dependencies = [ + "ibc-core-channel", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-connection", + "ibc-core-handler", + "ibc-core-host", + "ibc-core-router", + "ibc-derive", + "ibc-primitives", +] + +[[package]] +name = "ibc-core-channel" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5dcc1c14a92f01e556d72d834f842bb655043a7e122ebb8aabdb5e9df600aa8" +dependencies = [ + "ibc-core-channel-types", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-connection", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-core-router", + "ibc-primitives", +] + +[[package]] +name = "ibc-core-channel-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c2744ad32ae7360caefb80f495800f883f5e5687cfbd74ff82a444b59a47af7" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", + "sha2 0.10.8", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-core-client" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80071ac73dd4f3436bf1aef03c9b1715a4db0914f738904c281449dc05a0a9cf" +dependencies = [ + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-primitives", +] + +[[package]] +name = "ibc-core-client-context" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9f751b62cad4195be5347646151020fd27c2924f10d82d6301a675fac544dd" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-core-client-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "423e9e9a70b78fabc94c51dae76800459e126f891ae0987e88ac5e12c36e24de" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-commitment-types", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-core-commitment-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b323c91e58ea7b573e01b8e76d13f146c97c245ada0aab3070576d54288f30" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-primitives", + "ibc-proto", + "ics23", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", + "subtle-encoding", +] + +[[package]] +name = "ibc-core-connection" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31271364789ccfc12c25afa21b47274d7e07bf49b1f728fd66cfa6c29daaf4a" +dependencies = [ + "ibc-core-client", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-primitives", +] + +[[package]] +name = "ibc-core-connection-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d302a36925469589a911dab66654f390b87e98608d07515e47f5c7e51dffe7" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-core-handler" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4523b9f77d3a1a391a3d63737760be44b23bc9b09ed297883a34654383b9b0e2" +dependencies = [ + "ibc-core-channel", + "ibc-core-client", + "ibc-core-commitment-types", + "ibc-core-connection", + "ibc-core-handler-types", + "ibc-core-host", + "ibc-core-router", + "ibc-primitives", +] + +[[package]] +name = "ibc-core-handler-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b229a92aa8b06ab9ccde6e1b3dad597deb97cb40e3bb6a631799b4cd2ad124" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-channel-types", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-host-types", + "ibc-core-router-types", + "ibc-primitives", + "ibc-proto", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-core-host" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ed7421f285225b78f3d020df6126b61f94b9eb370a83e42fbd4e9c8b04162fa" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-core-channel-types", + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives", + "subtle-encoding", +] + +[[package]] +name = "ibc-core-host-cosmos" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b25b5b45cf47b1e73211a83adf3a753f1acdba887cd3bc5357d6f547d4a3e8c" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-app-transfer-types", + "ibc-client-tendermint", + "ibc-core-client-context", + "ibc-core-client-types", + "ibc-core-commitment-types", + "ibc-core-connection-types", + "ibc-core-handler-types", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", + "serde", + "sha2 0.10.8", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-core-host-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "939178939d33e5af1aca19608b019233d753f3734b828d66f40152b382f3db53" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-primitives", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", +] + +[[package]] +name = "ibc-core-router" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328e6db6d3aa7126278c46c3dff779aa961952a63d031d3ddf4c202f4a3faad4" +dependencies = [ + "derive_more", + "displaydoc", + "ibc-core-channel-types", + "ibc-core-host-types", + "ibc-core-router-types", + "ibc-primitives", + "subtle-encoding", +] + +[[package]] +name = "ibc-core-router-types" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4175b57087b28759364572683b335ec4fe63a6f938f1a5d0c383a6297a032155" +dependencies = [ + "borsh 0.10.3", + "derive_more", + "displaydoc", + "ibc-core-host-types", + "ibc-primitives", + "ibc-proto", + "parity-scale-codec", + "scale-info", + "schemars", + "serde", + "subtle-encoding", + "tendermint", +] + +[[package]] +name = "ibc-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d961d2194fd5229961835d2eb78091906ef8afbaaa55bce7ad41bf3ead8aa9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "ibc-integration-test" version = "0.28.0" dependencies = [ - "bytes", + "byte-unit", + "http 0.2.12", + "ibc-relayer", + "ibc-relayer-types", + "ibc-test-framework", + "prost", + "serde", + "serde_json", + "tempfile", + "tendermint", + "tendermint-rpc", + "time", + "toml 0.8.12", + "tonic", +] + +[[package]] +name = "ibc-primitives" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b3340c4908f1a1a36863270ac976e0295fbd1911cbc4609ab406967fd8ccc04" +dependencies = [ + "borsh 0.10.3", "derive_more", + "displaydoc", + "ibc-proto", + "parity-scale-codec", + "prost", + "scale-info", + "schemars", + "serde", + "tendermint", + "time", +] + +[[package]] +name = "ibc-proto" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66080040d5a4800d52966d55b055400f86b79c34b854b935bef03c87aacda62a" +dependencies = [ + "base64 0.22.0", + "borsh 0.10.3", + "bytes", + "flex-error", + "ics23", + "informalsystems-pbjson", + "parity-scale-codec", + "prost", + "scale-info", + "schemars", + "serde", + "subtle-encoding", + "tendermint-proto", + "tonic", +] + +[[package]] +name = "ibc-relayer" +version = "0.28.0" +dependencies = [ + "anyhow", + "async-stream", + "bech32 0.9.1", + "bitcoin", + "bs58", + "byte-unit", + "bytes", + "crossbeam-channel", + "digest 0.10.7", + "dirs-next", + "ed25519", + "ed25519-dalek", + "ed25519-dalek-bip32", "env_logger", "flex-error", + "futures", + "generic-array", + "hdpath", + "hex", + "http 0.2.12", + "humantime", + "humantime-serde", "ibc-proto", - "ics23", - "itertools", + "ibc-relayer-types", + "ibc-telemetry", + "itertools 0.12.1", + "moka", + "namada_ibc", + "namada_parameters", + "namada_sdk", + "namada_token", + "num-bigint", "num-rational", - "primitive-types", + "once_cell", "prost", "regex", + "reqwest", + "retry", + "ripemd", + "rpassword", + "secp256k1", + "semver 1.0.22", + "serde", + "serde_derive", + "serde_json", + "serial_test", + "sha2 0.10.8", + "signature", + "strum 0.25.0", + "subtle-encoding", + "tendermint", + "tendermint-light-client", + "tendermint-light-client-detector", + "tendermint-light-client-verifier", + "tendermint-proto", + "tendermint-rpc", + "tendermint-testgen", + "test-log", + "thiserror", + "tiny-bip39 1.0.0", + "tiny-keccak", + "tokio", + "tokio-stream", + "toml 0.8.12", + "tonic", + "tracing", + "tracing-subscriber", + "uuid 1.8.0", +] + +[[package]] +name = "ibc-relayer-cli" +version = "1.9.0" +dependencies = [ + "abscissa_core", + "clap", + "clap_complete", + "color-eyre", + "console", + "crossbeam-channel", + "dialoguer", + "dirs-next", + "eyre", + "flex-error", + "futures", + "hdpath", + "http 0.2.12", + "humantime", + "ibc-chain-registry", + "ibc-relayer", + "ibc-relayer-rest", + "ibc-relayer-types", + "ibc-telemetry", + "itertools 0.12.1", + "once_cell", + "oneline-eyre", + "regex", + "serde", + "serde_json", + "serial_test", + "signal-hook", + "subtle-encoding", + "tendermint", + "tendermint-light-client-verifier", + "tendermint-rpc", + "time", + "tokio", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "ibc-relayer-rest" +version = "0.28.0" +dependencies = [ + "axum", + "crossbeam-channel", + "ibc-relayer", + "ibc-relayer-types", + "reqwest", + "serde", + "serde_json", + "tokio", + "toml 0.8.12", + "tracing", +] + +[[package]] +name = "ibc-relayer-types" +version = "0.28.0" +dependencies = [ + "bytes", + "derive_more", + "env_logger", + "flex-error", + "ibc-proto", + "ics23", + "itertools 0.12.1", + "num-rational", + "primitive-types", + "prost", + "regex", + "serde", + "serde_derive", + "serde_json", + "subtle-encoding", + "tendermint", + "tendermint-light-client-verifier", + "tendermint-proto", + "tendermint-rpc", + "tendermint-testgen", + "test-log", + "time", + "tracing", + "tracing-subscriber", + "uint", +] + +[[package]] +name = "ibc-telemetry" +version = "0.28.0" +dependencies = [ + "axum", + "dashmap", + "ibc-relayer-types", + "moka", + "once_cell", + "opentelemetry", + "opentelemetry-prometheus", + "prometheus", + "serde", + "serde_json", + "tendermint", + "tokio", + "tracing", +] + +[[package]] +name = "ibc-test-framework" +version = "0.28.0" +dependencies = [ + "color-eyre", + "crossbeam-channel", + "eyre", + "flex-error", + "hdpath", + "hex", + "http 0.2.12", + "ibc-proto", + "ibc-relayer", + "ibc-relayer-cli", + "ibc-relayer-types", + "itertools 0.12.1", + "namada_ibc", + "namada_sdk", + "once_cell", + "prost", + "rand 0.8.5", + "semver 1.0.22", + "serde", + "serde_json", + "serde_yaml", + "sha2 0.10.8", + "subtle-encoding", + "tendermint", + "tendermint-rpc", + "tokio", + "toml 0.8.12", + "tonic", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "ics23" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3b8be84e7285c73b88effdc3294b552277d6b0ec728ee016c861b7b9a2c19c" +dependencies = [ + "anyhow", + "blake2", + "blake3", + "bytes", + "hex", + "informalsystems-pbjson", + "prost", + "ripemd", + "serde", + "sha2 0.10.8", + "sha3", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-num-traits" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951641f13f873bff03d4bf19ae8bec531935ac0ac2cc775f84d7edfdcfed3f17" +dependencies = [ + "integer-sqrt", + "num-traits 0.2.18", + "uint", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "incrementalmerkletree" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5ad43a3f5795945459d577f6589cf62a476e92c79b75e70cd954364e14ce17b" +dependencies = [ + "serde", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "index-set" +version = "0.8.0" +source = "git+https://github.com/heliaxdev/index-set?tag=v0.8.1#b0d928f83cf0d465ccda299d131e8df2859b5184" +dependencies = [ + "borsh 1.5.0", + "serde", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.4" +source = "git+https://github.com/heliaxdev/indexmap?tag=2.2.4-heliax-1#b5b5b547bd6ab04bbb16e060326a50ddaeb6c909" +dependencies = [ + "borsh 1.5.0", + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "informalsystems-pbjson" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa4a0980c8379295100d70854354e78df2ee1c6ca0f96ffe89afeb3140e3a3d" +dependencies = [ + "base64 0.21.7", + "serde", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "integer-sqrt" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" +dependencies = [ + "num-traits 0.2.18", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "jubjub" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8499f7a74008aafbecb2a2e608a3e13e4dd3e84df198b604451efe93f2de6e61" +dependencies = [ + "bitvec", + "bls12_381", + "ff", + "group", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "serdect", + "sha2 0.10.8", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "konst" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50a0ba6de5f7af397afff922f22c149ff605c766cd3269cf6c1cd5e466dbe3b9" +dependencies = [ + "const_panic", + "konst_kernel", + "typewit", +] + +[[package]] +name = "konst_kernel" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0a455a1719220fd6adf756088e1c69a85bf14b6a9e24537a5cc04f503edb2b" +dependencies = [ + "typewit", +] + +[[package]] +name = "lalrpop" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cb077ad656299f160924eb2912aa147d7339ea7d69e1b5517326fdcec3c1ca" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools 0.11.0", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.8.3", + "string_cache", + "term", + "tiny-keccak", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" +dependencies = [ + "regex-automata 0.4.6", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "linkme" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833222afbfe72868ac8f9770c91a33673f0d5fefc37c9dbe94aa3548b571623f" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f0dea92dbea3271557cc2e1848723967bba81f722f95026860974ec9283f08" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "masp_note_encryption" +version = "1.0.0" +source = "git+https://github.com/anoma/masp?rev=4ede1c42d76d6348af8224bc8bfac4404321fe82#4ede1c42d76d6348af8224bc8bfac4404321fe82" +dependencies = [ + "borsh 1.5.0", + "chacha20", + "chacha20poly1305", + "cipher", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "masp_primitives" +version = "1.0.0" +source = "git+https://github.com/anoma/masp?rev=4ede1c42d76d6348af8224bc8bfac4404321fe82#4ede1c42d76d6348af8224bc8bfac4404321fe82" +dependencies = [ + "aes", + "bip0039", + "bitvec", + "blake2b_simd", + "blake2s_simd", + "bls12_381", + "borsh 1.5.0", + "byteorder", + "ff", + "fpe", + "group", + "hex", + "incrementalmerkletree", + "jubjub", + "lazy_static", + "masp_note_encryption", + "memuse", + "nonempty", + "num-traits 0.2.19", + "rand 0.8.5", + "rand_core 0.6.4", + "sha2 0.10.8", + "subtle", + "zcash_encoding", +] + +[[package]] +name = "masp_proofs" +version = "1.0.0" +source = "git+https://github.com/anoma/masp?rev=4ede1c42d76d6348af8224bc8bfac4404321fe82#4ede1c42d76d6348af8224bc8bfac4404321fe82" +dependencies = [ + "bellman", + "blake2b_simd", + "bls12_381", + "directories", + "getrandom 0.2.14", + "group", + "itertools 0.11.0", + "jubjub", + "lazy_static", + "masp_primitives", + "minreq", + "rand_core 0.6.4", + "redjubjub", + "tracing", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memuse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" + +[[package]] +name = "memzero" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c0d11ac30a033511ae414355d80f70d9f29a44a49140face477117a1ee90db" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "minreq" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fdef521c74c2884a4f3570bcdb6d2a77b3c533feb6b27ac2ae72673cc221c64" +dependencies = [ + "log", + "once_cell", + "rustls 0.21.11", + "rustls-webpki 0.101.7", + "webpki-roots", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "moka" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0d88686dc561d743b40de8269b26eaf0dc58781bde087b0984646602021d08" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "once_cell", + "parking_lot", + "quanta", + "rustc_version 0.4.0", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid 1.8.0", +] + +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + +[[package]] +name = "namada_account" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "linkme", + "namada_core", + "namada_macros", + "namada_migrations", + "namada_storage", + "serde", +] + +[[package]] +name = "namada_controller" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "namada_core", + "smooth-operator", + "thiserror", +] + +[[package]] +name = "namada_core" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "bech32 0.8.1", + "borsh 1.5.0", + "borsh-ext", + "chrono", + "data-encoding", + "ed25519-consensus", + "ethabi", + "ethbridge-structs", + "eyre", + "ibc", + "ics23", + "impl-num-traits", + "index-set", + "indexmap 2.2.4", + "k256", + "linkme", + "masp_primitives", + "namada_macros", + "namada_migrations", + "num-integer", + "num-rational", + "num-traits 0.2.18", + "num256", + "num_enum", + "primitive-types", + "prost-types", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "serde_json", + "sha2 0.9.9", + "smooth-operator", + "sparse-merkle-tree", + "tendermint", + "tendermint-proto", + "thiserror", + "tiny-keccak", + "tracing", + "uint", + "zeroize", +] + +[[package]] +name = "namada_ethereum_bridge" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "ethers", + "eyre", + "itertools 0.12.1", + "konst", + "linkme", + "namada_core", + "namada_events", + "namada_macros", + "namada_migrations", + "namada_parameters", + "namada_proof_of_stake", + "namada_state", + "namada_storage", + "namada_trans_token", + "namada_tx", + "namada_vote_ext", + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "namada_events" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "linkme", + "namada_core", + "namada_macros", + "namada_migrations", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "namada_gas" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "linkme", + "namada_core", + "namada_events", + "namada_macros", + "namada_migrations", + "serde", + "thiserror", +] + +[[package]] +name = "namada_governance" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "itertools 0.12.1", + "konst", + "linkme", + "namada_core", + "namada_events", + "namada_macros", + "namada_migrations", + "namada_parameters", + "namada_storage", + "namada_trans_token", + "serde", + "serde_json", + "smooth-operator", + "thiserror", + "tracing", +] + +[[package]] +name = "namada_ibc" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "ibc", + "ibc-derive", + "ics23", + "konst", + "masp_primitives", + "namada_core", + "namada_events", + "namada_governance", + "namada_macros", + "namada_parameters", + "namada_state", + "namada_storage", + "namada_token", + "primitive-types", + "prost", "serde", - "serde_derive", "serde_json", - "subtle-encoding", - "tendermint", - "tendermint-light-client-verifier", - "tendermint-proto", - "tendermint-rpc", - "tendermint-testgen", - "test-log", - "time", + "sha2 0.9.9", + "thiserror", "tracing", - "tracing-subscriber", - "uint", ] [[package]] -name = "ibc-telemetry" -version = "0.28.0" +name = "namada_macros" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" dependencies = [ - "axum", - "dashmap", - "ibc-relayer-types", - "moka", + "data-encoding", + "proc-macro2", + "quote", + "sha2 0.9.9", + "syn 1.0.109", +] + +[[package]] +name = "namada_merkle_tree" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "eyre", + "ics23", + "namada_core", + "namada_macros", + "prost", + "sparse-merkle-tree", + "thiserror", +] + +[[package]] +name = "namada_migrations" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "lazy_static", + "linkme", + "namada_macros", +] + +[[package]] +name = "namada_parameters" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "namada_core", + "namada_macros", + "namada_storage", + "thiserror", +] + +[[package]] +name = "namada_proof_of_stake" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "konst", + "linkme", + "namada_account", + "namada_controller", + "namada_core", + "namada_events", + "namada_governance", + "namada_macros", + "namada_migrations", + "namada_parameters", + "namada_storage", + "namada_trans_token", "once_cell", - "opentelemetry", - "opentelemetry-prometheus", - "prometheus", "serde", - "serde_json", - "tendermint", - "tokio", + "smooth-operator", + "thiserror", "tracing", ] [[package]] -name = "ibc-test-framework" -version = "0.28.0" +name = "namada_replay_protection" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" dependencies = [ - "color-eyre", - "crossbeam-channel", + "namada_core", +] + +[[package]] +name = "namada_sdk" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "async-trait", + "bimap", + "borsh 1.5.0", + "borsh-ext", + "circular-queue", + "data-encoding", + "derivation-path", + "duration-str", + "ethbridge-bridge-contract", + "ethers", "eyre", - "flex-error", - "hdpath", - "hex", - "http 0.2.12", - "ibc-proto", - "ibc-relayer", - "ibc-relayer-cli", - "ibc-relayer-types", - "itertools", - "once_cell", + "fd-lock", + "futures", + "itertools 0.12.1", + "lazy_static", + "linkme", + "masp_primitives", + "masp_proofs", + "namada_account", + "namada_core", + "namada_ethereum_bridge", + "namada_events", + "namada_gas", + "namada_governance", + "namada_ibc", + "namada_macros", + "namada_migrations", + "namada_parameters", + "namada_proof_of_stake", + "namada_state", + "namada_storage", + "namada_token", + "namada_tx", + "namada_vote_ext", + "num-traits 0.2.18", + "num256", + "orion", + "owo-colors", + "paste", + "patricia_tree", "prost", - "rand", - "semver", + "rand 0.8.5", + "rand_core 0.6.4", + "regex", + "ripemd", "serde", "serde_json", - "serde_yaml", - "sha2 0.10.8", - "subtle-encoding", + "sha2 0.9.9", + "slip10_ed25519", + "smooth-operator", "tendermint-rpc", + "thiserror", + "tiny-bip39 0.8.2", + "tiny-hderive", "tokio", - "toml 0.8.13", - "tonic", + "toml 0.5.11", "tracing", - "tracing-subscriber", + "wasmtimer", + "zeroize", ] [[package]] -name = "ics23" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc3b8be84e7285c73b88effdc3294b552277d6b0ec728ee016c861b7b9a2c19c" +name = "namada_shielded_token" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" dependencies = [ - "anyhow", - "blake2", - "blake3", - "bytes", - "hex", - "informalsystems-pbjson", + "borsh 1.5.0", + "masp_primitives", + "namada_controller", + "namada_core", + "namada_parameters", + "namada_storage", + "namada_trans_token", + "serde", + "smooth-operator", + "tracing", +] + +[[package]] +name = "namada_state" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "itertools 0.12.1", + "linkme", + "namada_core", + "namada_events", + "namada_gas", + "namada_macros", + "namada_merkle_tree", + "namada_migrations", + "namada_parameters", + "namada_replay_protection", + "namada_storage", + "namada_tx", + "patricia_tree", + "smooth-operator", + "thiserror", + "tracing", +] + +[[package]] +name = "namada_storage" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "itertools 0.12.1", + "linkme", + "namada_core", + "namada_macros", + "namada_merkle_tree", + "namada_migrations", + "namada_replay_protection", + "regex", + "serde", + "smooth-operator", + "thiserror", + "tracing", +] + +[[package]] +name = "namada_token" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "namada_core", + "namada_events", + "namada_macros", + "namada_shielded_token", + "namada_storage", + "namada_trans_token", + "serde", +] + +[[package]] +name = "namada_trans_token" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "konst", + "namada_core", + "namada_events", + "namada_storage", +] + +[[package]] +name = "namada_tx" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "ark-bls12-381", + "bitflags 2.5.0", + "borsh 1.5.0", + "data-encoding", + "konst", + "linkme", + "masp_primitives", + "namada_core", + "namada_events", + "namada_gas", + "namada_macros", + "namada_migrations", + "num-derive 0.4.2", + "num-traits 0.2.18", "prost", - "ripemd", + "prost-types", "serde", - "sha2 0.10.8", - "sha3", + "serde_json", + "sha2 0.9.9", + "thiserror", + "tonic-build", ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "namada_vote_ext" +version = "0.39.0" +source = "git+https://github.com/anoma/namada#879a3268f2edfbdd0da1c98cf0e4bbdac48f5b0d" +dependencies = [ + "borsh 1.5.0", + "linkme", + "namada_core", + "namada_macros", + "namada_migrations", + "namada_tx", + "serde", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] -name = "idna" -version = "0.5.0" +name = "nonempty" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "overload", + "winapi", ] [[package]] -name = "impl-serde" -version = "0.4.0" +name = "num" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits 0.2.18", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ + "autocfg", + "num-integer", + "num-traits 0.2.18", "serde", ] [[package]] -name = "indenter" +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits 0.2.18", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "indexmap" -version = "1.9.3" +name = "num-derive" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits 0.2.18", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", - "hashbrown 0.12.3", + "num-integer", + "num-traits 0.2.18", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits 0.2.18", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "git+https://github.com/heliaxdev/num-traits?rev=3f3657caa34b8e116fdf3f8a3519c4ac29f012fe#3f3657caa34b8e116fdf3f8a3519c4ac29f012fe" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num256" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9b5179e82f0867b23e0b9b822493821f9345561f271364f409c8e4a058367d" +dependencies = [ + "lazy_static", + "num", + "num-derive 0.3.3", + "num-traits 0.2.18", + "serde", + "serde_derive", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", ] [[package]] -name = "indexmap" -version = "2.2.6" +name = "num_enum" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" dependencies = [ - "equivalent", - "hashbrown 0.14.5", + "num_enum_derive", ] [[package]] -name = "informalsystems-pbjson" -version = "0.7.0" +name = "num_enum_derive" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa4a0980c8379295100d70854354e78df2ee1c6ca0f96ffe89afeb3140e3a3d" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "base64 0.21.7", - "serde", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 2.0.60", ] [[package]] -name = "ipnet" -version = "2.9.0" +name = "object" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] [[package]] -name = "is_terminal_polyfill" -version = "1.70.0" +name = "once_cell" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] -name = "itertools" -version = "0.12.1" +name = "oneline-eyre" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "862f17a1e689c0ce8ca158ea48e776c5101c5d14fdfbed3e01c15f89604c3097" dependencies = [ - "either", + "eyre", ] [[package]] -name = "itoa" -version = "1.0.11" +name = "opaque-debug" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] -name = "js-sys" -version = "0.3.69" +name = "open-fastrlp" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" dependencies = [ - "wasm-bindgen", + "arrayvec", + "auto_impl", + "bytes", + "ethereum-types", + "open-fastrlp-derive", ] [[package]] -name = "k256" -version = "0.13.3" +name = "open-fastrlp-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "sha2 0.10.8", + "bytes", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "keccak" +name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] -name = "libc" -version = "0.2.155" +name = "opentelemetry" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "5f4b8347cc26099d3aeee044065ecc3ae11469796b4d65d065a23a584ed92a6f" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] [[package]] -name = "libredox" -version = "0.1.3" +name = "opentelemetry-prometheus" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "9a9f186f6293ebb693caddd0595e66b74a6068fa51048e26e0bf9c95478c639c" dependencies = [ - "bitflags 2.5.0", - "libc", + "opentelemetry", + "prometheus", + "protobuf", ] [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "opentelemetry_api" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "ed41783a5bf567688eb38372f2b7a8530f5a607a4b49d38dd7573236c23ca7e2" +dependencies = [ + "fnv", + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] [[package]] -name = "lock_api" -version = "0.4.12" +name = "opentelemetry_sdk" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "8b3a2a91fdbfdd4d212c0dcc2ab540de2c2bcbbd90be17de7a7daf8822d010c1" dependencies = [ - "autocfg", - "scopeguard", + "async-trait", + "crossbeam-channel", + "dashmap", + "fnv", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "percent-encoding", + "rand 0.8.5", + "thiserror", ] [[package]] -name = "log" -version = "0.4.21" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] -name = "matchers" -version = "0.1.0" +name = "orion" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "c6624905ddd92e460ff0685567539ed1ac985b2dee4c92c7edcd64fce905b00c" dependencies = [ - "regex-automata 0.1.10", + "ct-codecs", + "getrandom 0.2.14", + "subtle", + "zeroize", ] [[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.2" +name = "os_str_bytes" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] -name = "mime" -version = "0.3.17" +name = "overload" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "miniz_oxide" -version = "0.7.3" +name = "owo-colors" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" -dependencies = [ - "adler", -] +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" [[package]] -name = "mio" -version = "0.8.11" +name = "pairing" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", + "group", ] [[package]] -name = "moka" -version = "0.12.7" +name = "parity-scale-codec" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0d88686dc561d743b40de8269b26eaf0dc58781bde087b0984646602021d08" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "crossbeam-channel", - "crossbeam-epoch", - "crossbeam-utils", - "once_cell", - "parking_lot", - "quanta", - "rustc_version", - "smallvec", - "tagptr", - "thiserror", - "triomphe", - "uuid", + "arrayvec", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", ] [[package]] -name = "nu-ansi-term" -version = "0.46.0" +name = "parity-scale-codec-derive" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "overload", - "winapi", + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "num-bigint" -version = "0.4.5" +name = "parking_lot" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ - "num-integer", - "num-traits", - "serde", + "lock_api", + "parking_lot_core", ] [[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ - "num-traits", + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", ] [[package]] -name = "num-rational" +name = "password-hash" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", + "base64ct", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "num-traits" -version = "0.2.19" +name = "password-hash" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ - "autocfg", + "base64ct", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "num_cpus" -version = "1.16.0" +name = "pasta_curves" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +checksum = "d3e57598f73cc7e1b2ac63c79c517b31a0877cd7c402cdcaa311b5208de7a095" dependencies = [ - "hermit-abi 0.3.9", - "libc", + "ff", + "group", + "rand 0.8.5", + "static_assertions", + "subtle", ] [[package]] -name = "object" -version = "0.32.2" +name = "paste" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] -name = "once_cell" -version = "1.19.0" +name = "path-slash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" [[package]] -name = "oneline-eyre" -version = "0.1.0" +name = "patricia_tree" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862f17a1e689c0ce8ca158ea48e776c5101c5d14fdfbed3e01c15f89604c3097" +checksum = "31f2f4539bffe53fc4b4da301df49d114b845b077bd5727b7fe2bd9d8df2ae68" dependencies = [ - "eyre", -] - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + "bitflags 2.5.0", +] [[package]] -name = "openssl-probe" -version = "0.1.5" +name = "pbkdf2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "216eaa586a190f0a738f2f918511eecfa90f13295abec0e457cdebcceda80cbd" +dependencies = [ + "crypto-mac", +] [[package]] -name = "opentelemetry" -version = "0.19.0" +name = "pbkdf2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4b8347cc26099d3aeee044065ecc3ae11469796b4d65d065a23a584ed92a6f" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "opentelemetry_api", - "opentelemetry_sdk", + "digest 0.10.7", + "hmac 0.12.1", + "password-hash 0.4.2", + "sha2 0.10.8", ] [[package]] -name = "opentelemetry-prometheus" -version = "0.12.0" +name = "pbkdf2" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9f186f6293ebb693caddd0595e66b74a6068fa51048e26e0bf9c95478c639c" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "opentelemetry", - "prometheus", - "protobuf", + "digest 0.10.7", + "hmac 0.12.1", + "password-hash 0.5.0", ] [[package]] -name = "opentelemetry_api" -version = "0.19.0" +name = "peg" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed41783a5bf567688eb38372f2b7a8530f5a607a4b49d38dd7573236c23ca7e2" +checksum = "400bcab7d219c38abf8bd7cc2054eb9bbbd4312d66f6a5557d572a203f646f61" dependencies = [ - "fnv", - "futures-channel", - "futures-util", - "indexmap 1.9.3", - "once_cell", - "pin-project-lite", - "thiserror", - "urlencoding", + "peg-macros", + "peg-runtime", ] [[package]] -name = "opentelemetry_sdk" -version = "0.19.0" +name = "peg-macros" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b3a2a91fdbfdd4d212c0dcc2ab540de2c2bcbbd90be17de7a7daf8822d010c1" +checksum = "46e61cce859b76d19090f62da50a9fe92bab7c2a5f09e183763559a2ac392c90" dependencies = [ - "async-trait", - "crossbeam-channel", - "dashmap", - "fnv", - "futures-channel", - "futures-executor", - "futures-util", - "once_cell", - "opentelemetry_api", - "percent-encoding", - "rand", - "thiserror", + "peg-runtime", + "proc-macro2", + "quote", ] [[package]] -name = "os_str_bytes" -version = "6.6.1" +name = "peg-runtime" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" +checksum = "36bae92c60fa2398ce4678b98b2c4b5a7c61099961ca1fa305aec04a9ad28922" [[package]] -name = "overload" -version = "0.1.1" +name = "pem" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] [[package]] -name = "owo-colors" -version = "3.5.0" +name = "percent-encoding" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] -name = "parking_lot" -version = "0.12.3" +name = "pest" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" dependencies = [ - "lock_api", - "parking_lot_core", + "memchr", + "thiserror", + "ucd-trie", ] [[package]] -name = "parking_lot_core" -version = "0.9.10" +name = "petgraph" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.5", + "fixedbitset", + "indexmap 2.2.6", ] [[package]] -name = "paste" -version = "1.0.15" +name = "pharos" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version 0.4.0", +] [[package]] -name = "pbkdf2" -version = "0.11.0" +name = "phf" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "digest 0.10.7", + "phf_macros", + "phf_shared 0.11.2", ] [[package]] -name = "peg" -version = "0.8.3" +name = "phf_generator" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a625d12ad770914cbf7eff6f9314c3ef803bfe364a1b20bc36ddf56673e71e5" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ - "peg-macros", - "peg-runtime", + "phf_shared 0.11.2", + "rand 0.8.5", ] [[package]] -name = "peg-macros" -version = "0.8.3" +name = "phf_macros" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f241d42067ed3ab6a4fece1db720838e1418f36d868585a27931f95d6bc03582" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ - "peg-runtime", + "phf_generator", + "phf_shared 0.11.2", "proc-macro2", "quote", + "syn 2.0.60", ] [[package]] -name = "peg-runtime" -version = "0.8.3" +name = "phf_shared" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "phf_shared" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] [[package]] name = "pin-project" @@ -2148,7 +5052,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -2173,12 +5077,29 @@ dependencies = [ "spki", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "platforms" version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -2191,6 +5112,22 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f12335488a2f3b0a83b14edad48dca9879ce89b2edd10e80237e4e852dd645e" +dependencies = [ + "proc-macro2", + "syn 2.0.60", +] + [[package]] name = "primitive-types" version = "0.12.2" @@ -2198,10 +5135,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ "fixed-hash", + "impl-codec", + "impl-rlp", "impl-serde", + "scale-info", "uint", ] +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml 0.5.11", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -2228,9 +5186,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.84" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -2250,6 +5208,22 @@ dependencies = [ "thiserror", ] +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bitflags 2.5.0", + "lazy_static", + "num-traits 0.2.18", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax 0.8.3", + "unarray", +] + [[package]] name = "prost" version = "0.12.6" @@ -2260,6 +5234,27 @@ dependencies = [ "prost-derive", ] +[[package]] +name = "prost-build" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" +dependencies = [ + "bytes", + "heck", + "itertools 0.12.1", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 2.0.60", + "tempfile", +] + [[package]] name = "prost-derive" version = "0.12.6" @@ -2267,17 +5262,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] name = "prost-types" -version = "0.12.6" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" +checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" dependencies = [ "prost", ] @@ -2292,72 +5287,179 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" name = "quanta" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.14", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" dependencies = [ - "crossbeam-utils", - "libc", - "once_cell", - "raw-cpuid", - "wasi", - "web-sys", - "winapi", + "rand_core 0.6.4", ] [[package]] -name = "quote" -version = "1.0.36" +name = "raw-cpuid" +version = "11.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" dependencies = [ - "proc-macro2", + "bitflags 2.5.0", ] [[package]] -name = "rand" -version = "0.8.5" +name = "rayon" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ - "libc", - "rand_chacha", - "rand_core", + "either", + "rayon-core", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "rayon-core" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "ppv-lite86", - "rand_core", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "reddsa" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "78a5191930e84973293aa5f532b513404460cd2216c1cfb76d08748c15b40b02" dependencies = [ - "getrandom", + "blake2b_simd", + "byteorder", + "group", + "hex", + "jubjub", + "pasta_curves", + "rand_core 0.6.4", + "serde", + "thiserror", + "zeroize", ] [[package]] -name = "raw-cpuid" -version = "11.0.2" +name = "redjubjub" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e29830cbb1290e404f24c73af91c5d8d631ce7e128691e9477556b540cd01ecd" +checksum = "7a60db2c3bc9c6fd1e8631fee75abc008841d27144be744951d6b9b75f9b569c" dependencies = [ - "bitflags 2.5.0", + "rand_core 0.6.4", + "reddsa", + "serde", + "thiserror", + "zeroize", ] [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags 2.5.0", + "bitflags 1.3.2", ] [[package]] @@ -2366,7 +5468,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom", + "getrandom 0.2.14", "libredox", "thiserror", ] @@ -2438,7 +5540,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.12", + "rustls 0.21.11", "rustls-native-certs 0.6.3", "rustls-pemfile 1.0.4", "serde", @@ -2453,6 +5555,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] @@ -2468,10 +5571,25 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac", + "hmac 0.12.1", "subtle", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + [[package]] name = "ring" version = "0.17.8" @@ -2480,10 +5598,10 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.14", "libc", - "spin", - "untrusted", + "spin 0.9.8", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -2496,11 +5614,53 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rlp-derive", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rpassword" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc936cf8a7ea60c58f030fd36a612a48f440610214dc54bc36431f9ea0c3efb" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "rust_decimal" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +dependencies = [ + "arrayvec", + "num-traits 0.2.18", +] + [[package]] name = "rustc-demangle" -version = "0.1.24" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hash" @@ -2508,20 +5668,35 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.22", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "e3cc72858054fcff6d7dea32df2aeaee6a7c24227366d7ea429aada2f26b16ad" dependencies = [ "bitflags 2.5.0", "errno", @@ -2532,12 +5707,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.12" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", - "ring", + "ring 0.17.8", "rustls-webpki 0.101.7", "sct", ] @@ -2549,9 +5724,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", - "ring", + "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki 0.102.2", "subtle", "zeroize", ] @@ -2596,15 +5771,15 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64 0.22.1", + "base64 0.22.0", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "ecd36cc4259e3e4514335c4a138c6b43171a8d61d8f5c9348f9fc7529416f247" [[package]] name = "rustls-webpki" @@ -2612,32 +5787,41 @@ version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" dependencies = [ - "ring", + "ring 0.17.8", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "salsa20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] [[package]] name = "same-file" @@ -2648,11 +5832,35 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scale-info" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024" +dependencies = [ + "cfg-if", + "derive_more", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "scc" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ad2bbb0ae5100a07b7a6f2ed7ab5fd0045551a4c507989b7a620046ea3efdc" +checksum = "ec96560eea317a9cc4e0bb1f6a2c93c09a19b8c4fc5cb3fcc0ec1c094cd783e2" dependencies = [ "sdd", ] @@ -2666,20 +5874,56 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "schemars" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09c024468a378b7e36765cd36702b7a90cc3cba11654f6685c8f233408e89e92" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.60", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac 0.12.1", + "pbkdf2 0.11.0", + "salsa20", + "sha2 0.10.8", +] + [[package]] name = "sct" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.8", + "untrusted 0.9.0", ] [[package]] @@ -2698,6 +5942,7 @@ dependencies = [ "der", "generic-array", "pkcs8", + "serdect", "subtle", "zeroize", ] @@ -2709,7 +5954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10" dependencies = [ "bitcoin_hashes", - "rand", + "rand 0.8.5", "secp256k1-sys", "serde", ] @@ -2735,11 +5980,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.11.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ - "bitflags 2.5.0", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2748,9 +5993,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -2758,13 +6003,43 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + [[package]] name = "serde" version = "1.0.203" @@ -2774,6 +6049,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-json-wasm" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05da0d153dd4595bdffd5099dc0e9ce425b205ee648eb93437ff7302af8c9a5" +dependencies = [ + "serde", +] + [[package]] name = "serde_bytes" version = "0.11.14" @@ -2801,7 +6085,18 @@ checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", ] [[package]] @@ -2833,14 +6128,14 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -2870,6 +6165,16 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "serial_test" version = "3.1.1" @@ -2892,7 +6197,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -2981,7 +6286,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -2990,6 +6295,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8542b68b8800c3cda649d2c72d688b6907b30f1580043135d61669d4aad1c175" +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits 0.2.18", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -2999,22 +6322,81 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slip10_ed25519" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be0ff28bf14f9610a342169084e87a4f435ad798ec528dc7579a3678fa9dc9a" +dependencies = [ + "hmac-sha512", +] + [[package]] name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smooth-operator" +version = "0.7.0" +source = "git+https://github.com/heliaxdev/smooth-operator?tag=v0.7.0#0e182707f5e5bb9c6e0efa2d235dc9efd715d0a1" +dependencies = [ + "smooth-operator-impl", +] + +[[package]] +name = "smooth-operator-impl" +version = "0.7.0" +source = "git+https://github.com/heliaxdev/smooth-operator?tag=v0.7.0#0e182707f5e5bb9c6e0efa2d235dc9efd715d0a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", "windows-sys 0.52.0", ] +[[package]] +name = "solang-parser" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c425ce1c59f4b154717592f0bdf4715c3a1d55058883622d3157e1f0908a5b26" +dependencies = [ + "itertools 0.11.0", + "lalrpop", + "lalrpop-util", + "phf", + "thiserror", + "unicode-xid", +] + +[[package]] +name = "sparse-merkle-tree" +version = "0.3.1-pre" +source = "git+https://github.com/heliaxdev/sparse-merkle-tree?rev=bab8cb96872db22cc9a139b2d3dfc4e00521d097#bab8cb96872db22cc9a139b2d3dfc4e00521d097" +dependencies = [ + "borsh 1.5.0", + "cfg-if", + "ics23", + "itertools 0.12.1", + "sha2 0.9.9", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" @@ -3037,6 +6419,19 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", +] + [[package]] name = "strsim" version = "0.10.0" @@ -3045,11 +6440,20 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.25.0" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros 0.25.3", +] + +[[package]] +name = "strum" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" dependencies = [ - "strum_macros", + "strum_macros 0.26.2", ] [[package]] @@ -3062,7 +6466,20 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.66", + "syn 2.0.60", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.60", ] [[package]] @@ -3086,6 +6503,26 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" +[[package]] +name = "svm-rs" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11297baafe5fa0c99d5722458eac6a5e25c01eb1b8e5cd137f54079093daa7a4" +dependencies = [ + "dirs", + "fs2", + "hex", + "once_cell", + "reqwest", + "semver 1.0.22", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "url", + "zip", +] + [[package]] name = "syn" version = "1.0.109" @@ -3099,15 +6536,27 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.66" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -3153,6 +6602,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.10.1" @@ -3178,7 +6633,7 @@ dependencies = [ "flex-error", "futures", "k256", - "num-traits", + "num-traits 0.2.18", "once_cell", "prost", "prost-types", @@ -3206,7 +6661,7 @@ dependencies = [ "serde", "serde_json", "tendermint", - "toml 0.8.13", + "toml 0.8.12", "url", ] @@ -3298,12 +6753,12 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom", + "getrandom 0.2.14", "peg", "pin-project", - "rand", + "rand 0.8.5", "reqwest", - "semver", + "semver 1.0.22", "serde", "serde_bytes", "serde_json", @@ -3317,7 +6772,7 @@ dependencies = [ "tokio", "tracing", "url", - "uuid", + "uuid 1.8.0", "walkdir", ] @@ -3337,6 +6792,17 @@ dependencies = [ "time", ] +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -3348,9 +6814,9 @@ dependencies = [ [[package]] name = "test-log" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dffced63c2b5c7be278154d76b479f9f9920ed34e7574201407f0b14e2bbb93" +checksum = "7b319995299c65d522680decf80f2c108d85b861d81dfe340a10d16cee29d9e6" dependencies = [ "env_logger", "test-log-macros", @@ -3359,13 +6825,13 @@ dependencies = [ [[package]] name = "test-log-macros" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" +checksum = "c8f546451eaa38373f549093fe9fd05e7d2bade739e2ddf834b9968621d60107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -3391,7 +6857,7 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -3411,6 +6877,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", + "itoa", "num-conv", "powerfmt", "serde", @@ -3434,6 +6901,24 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-bip39" +version = "0.8.2" +source = "git+https://github.com/anoma/tiny-bip39.git?rev=bf0f6d8713589b83af7a917366ec31f5275c0e57#bf0f6d8713589b83af7a917366ec31f5275c0e57" +dependencies = [ + "anyhow", + "hmac 0.8.1", + "once_cell", + "pbkdf2 0.4.0", + "rand 0.7.3", + "rustc-hash", + "sha2 0.9.9", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + [[package]] name = "tiny-bip39" version = "1.0.0" @@ -3441,10 +6926,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" dependencies = [ "anyhow", - "hmac", + "hmac 0.12.1", "once_cell", - "pbkdf2", - "rand", + "pbkdf2 0.11.0", + "rand 0.8.5", "rustc-hash", "sha2 0.10.8", "thiserror", @@ -3453,6 +6938,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "tiny-hderive" +version = "0.3.0" +source = "git+https://github.com/heliaxdev/tiny-hderive.git?rev=173ae03abed0cd25d88a5a13efac00af96b75b87#173ae03abed0cd25d88a5a13efac00af96b75b87" +dependencies = [ + "base58", + "hmac 0.12.1", + "k256", + "memzero", + "sha2 0.10.8", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -3479,9 +6976,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.38.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -3508,13 +7005,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.3.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -3523,7 +7020,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.12", + "rustls 0.21.11", "tokio", ] @@ -3549,17 +7046,33 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "rustls 0.21.11", + "tokio", + "tokio-rustls 0.24.1", + "tungstenite 0.20.1", + "webpki-roots", +] + [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", + "tracing", ] [[package]] @@ -3573,36 +7086,47 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.12", ] [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.8", ] [[package]] @@ -3636,6 +7160,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "tonic-build" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 2.0.60", +] + [[package]] name = "tower" version = "0.4.13" @@ -3647,7 +7184,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand", + "rand 0.8.5", "slab", "tokio", "tokio-util", @@ -3688,7 +7225,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", ] [[package]] @@ -3711,6 +7248,16 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-log" version = "0.1.4" @@ -3766,9 +7313,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.12" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b2cb4fbb9995eeb36ac86fadf24031ccd58f99d6b4b2d7b911db70bddb80d90" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" [[package]] name = "try-lock" @@ -3776,6 +7323,26 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 0.2.12", + "httparse", + "log", + "rand 0.8.5", + "rustls 0.21.11", + "sha1", + "thiserror", + "url", + "utf-8", +] + [[package]] name = "tungstenite" version = "0.21.0" @@ -3788,7 +7355,7 @@ dependencies = [ "http 1.1.0", "httparse", "log", - "rand", + "rand 0.8.5", "rustls 0.22.4", "rustls-pki-types", "sha1", @@ -3803,6 +7370,27 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typewit" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fb9ae6a3cafaf0a5d14c2302ca525f9ae8e07a0f0e6949de88d882c37a6e24" +dependencies = [ + "typewit_proc_macros", +] + +[[package]] +name = "typewit_proc_macros" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uint" version = "0.9.5" @@ -3815,6 +7403,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -3838,9 +7432,9 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] name = "unicode-xid" @@ -3848,12 +7442,28 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "unsafe-libyaml" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -3895,13 +7505,23 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.14", + "serde", +] + [[package]] name = "uuid" version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom", + "getrandom 0.2.14", ] [[package]] @@ -3944,6 +7564,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3971,7 +7597,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -4005,7 +7631,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4016,6 +7642,20 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + [[package]] name = "web-sys" version = "0.3.69" @@ -4026,6 +7666,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "winapi" version = "0.3.9" @@ -4044,11 +7690,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ - "windows-sys 0.52.0", + "winapi", ] [[package]] @@ -4057,6 +7703,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -4198,9 +7853,18 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.6.9" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86c949fede1d13936a99f14fafd3e76fd642b556dd2ce96287fbe2e0151bfac6" +checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" dependencies = [ "memchr", ] @@ -4215,11 +7879,54 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version 0.4.0", + "send_wrapper 0.6.0", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zcash_encoding" +version = "0.2.0" +source = "git+https://github.com/zcash/librustzcash?rev=bd7f9d7#bd7f9d7c3ce5cfd14af169ffe0e1c5c903162f46" +dependencies = [ + "byteorder", + "nonempty", +] + [[package]] name = "zeroize" -version = "1.8.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -4232,5 +7939,54 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.66", + "syn 2.0.60", +] + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq 0.1.5", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac 0.12.1", + "pbkdf2 0.11.0", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", ] diff --git a/Cargo.toml b/Cargo.toml index 6f8bbf44b3..271768cad9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,13 +30,19 @@ ibc-test-framework = { version = "0.28.0", path = "tools/test-framework" } ibc-integration-test = { version = "0.28.0", path = "tools/integration-test" } # Tendermint dependencies -tendermint = { version = "0.36.0", default-features = false } -tendermint-light-client = { version = "0.36.0", default-features = false } -tendermint-light-client-detector = { version = "0.36.0", default-features = false } -tendermint-light-client-verifier = { version = "0.36.0", default-features = false } -tendermint-proto = { version = "0.36.0" } -tendermint-rpc = { version = "0.36.0" } -tendermint-testgen = { version = "0.36.0" } +tendermint = { version = "=0.36.0", default-features = false } +tendermint-light-client = { version = "=0.36.0", default-features = false } +tendermint-light-client-detector = { version = "=0.36.0", default-features = false } +tendermint-light-client-verifier = { version = "=0.36.0", default-features = false } +tendermint-proto = { version = "=0.36.0" } +tendermint-rpc = { version = "=0.36.0" } +tendermint-testgen = { version = "=0.36.0" } + +# Namada dependencies +namada_ibc = { git = "https://github.com/anoma/namada", version = "0.39.0" } +namada_parameters = { git = "https://github.com/anoma/namada", version = "0.39.0" } +namada_sdk = { git = "https://github.com/anoma/namada", version = "0.39.0" } +namada_token = { git = "https://github.com/anoma/namada", version = "0.39.0" } # Other dependencies abscissa_core = "=0.6.0" @@ -72,7 +78,7 @@ hex = "0.4.3" http = "0.2.9" humantime = "2.1.0" humantime-serde = "1.1.1" -ibc-proto = "0.44.0" +ibc-proto = "=0.44.0" ics23 = "0.11.1" itertools = "0.12.1" moka = "0.12.5" @@ -90,6 +96,7 @@ regex = "1.10.4" reqwest = { version = "0.11.27", default-features = false } retry = { version = "2.0.0", default-features = false } ripemd = "0.1.3" +rpassword = "5.0.1" secp256k1 = "0.28.2" semver = "1.0.21" serde = "1.0.203" diff --git a/config.toml b/config.toml index 897814008d..58bb877764 100644 --- a/config.toml +++ b/config.toml @@ -154,7 +154,7 @@ port = 5555 # Specify the chain ID. Required id = 'ibc-0' -# Specify the chain type, currently only `CosmosSdk` is supported. +# Specify the chain type, currently `CosmosSdk` and `Namada` are supported. # Default: CosmosSdk type = "CosmosSdk" diff --git a/crates/relayer-cli/src/commands/keys/add.rs b/crates/relayer-cli/src/commands/keys/add.rs index b24514d00a..61ff01f416 100644 --- a/crates/relayer-cli/src/commands/keys/add.rs +++ b/crates/relayer-cli/src/commands/keys/add.rs @@ -10,9 +10,11 @@ use abscissa_core::{Command, Runnable}; use eyre::eyre; use hdpath::StandardHDPath; use ibc_relayer::{ + chain::namada::wallet::CliWalletUtils, config::{ChainConfig, Config}, keyring::{ - AnySigningKeyPair, KeyRing, Secp256k1KeyPair, SigningKeyPair, SigningKeyPairSized, Store, + AnySigningKeyPair, KeyRing, NamadaKeyPair, Secp256k1KeyPair, SigningKeyPair, + SigningKeyPairSized, Store, }, }; use ibc_relayer_types::core::ics24_host::identifier::ChainId; @@ -220,6 +222,36 @@ pub fn add_key( keyring.add_key(key_name, key_pair.clone())?; key_pair.into() } + ChainConfig::Namada(config) => { + let mut keyring = + KeyRing::new_namada(Store::Test, &config.id, &config.key_store_folder)?; + + check_key_exists(&keyring, key_name, overwrite); + + let path = if file.is_file() { + file.parent().ok_or(eyre!("invalid Namada wallet path"))? + } else { + file + }; + let mut wallet = CliWalletUtils::new(path.to_path_buf()); + wallet + .load() + .map_err(|_| eyre!("error loading Namada wallet"))?; + + let secret_key = wallet + .find_secret_key(key_name, None) + .map_err(|_| eyre!("error loading the key from Namada wallet"))?; + let address = wallet + .find_address(key_name) + .ok_or_else(|| eyre!("error loading the address from Namada wallet"))?; + let namada_key = NamadaKeyPair { + alias: key_name.to_string(), + address: address.into_owned(), + secret_key: secret_key.clone(), + }; + keyring.add_key(key_name, namada_key.clone())?; + namada_key.into() + } }; Ok(key_pair) @@ -256,6 +288,11 @@ pub fn restore_key( keyring.add_key(key_name, key_pair.clone())?; key_pair.into() } + ChainConfig::Namada(_) => { + return Err(eyre!( + "Namada key can't be restored here. Use Namada wallet." + )); + } }; Ok(key_pair) diff --git a/crates/relayer-cli/src/commands/keys/balance.rs b/crates/relayer-cli/src/commands/keys/balance.rs index b3c1edd90d..b3c9851bb9 100644 --- a/crates/relayer-cli/src/commands/keys/balance.rs +++ b/crates/relayer-cli/src/commands/keys/balance.rs @@ -77,7 +77,9 @@ fn get_balance(chain: impl ChainHandle, key_name: Option, denom: Option< let key_name = key_name.unwrap_or_else(|| { let chain_config = chain.config().unwrap_or_else(exit_with_unrecoverable_error); match chain_config { - ChainConfig::CosmosSdk(chain_config) => chain_config.key_name, + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.key_name + } } }); @@ -99,7 +101,9 @@ fn get_balances(chain: impl ChainHandle, key_name: Option) { let key_name = key_name.unwrap_or_else(|| { let chain_config = chain.config().unwrap_or_else(exit_with_unrecoverable_error); match chain_config { - ChainConfig::CosmosSdk(chain_config) => chain_config.key_name, + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.key_name + } } }); diff --git a/crates/relayer-cli/src/commands/keys/delete.rs b/crates/relayer-cli/src/commands/keys/delete.rs index fe25e8a056..aef00748d0 100644 --- a/crates/relayer-cli/src/commands/keys/delete.rs +++ b/crates/relayer-cli/src/commands/keys/delete.rs @@ -123,6 +123,11 @@ pub fn delete_key(config: &ChainConfig, key_name: &str) -> eyre::Result<()> { )?; keyring.remove_key(key_name)?; } + ChainConfig::Namada(config) => { + let mut keyring = + KeyRing::new_namada(Store::Test, &config.id, &config.key_store_folder)?; + keyring.remove_key(key_name)?; + } } Ok(()) } @@ -141,6 +146,14 @@ pub fn delete_all_keys(config: &ChainConfig) -> eyre::Result<()> { keyring.remove_key(&key_name)?; } } + ChainConfig::Namada(config) => { + let mut keyring = + KeyRing::new_namada(Store::Test, &config.id, &config.key_store_folder)?; + let keys = keyring.keys()?; + for (key_name, _) in keys { + keyring.remove_key(&key_name)?; + } + } } Ok(()) } diff --git a/crates/relayer-cli/src/commands/listen.rs b/crates/relayer-cli/src/commands/listen.rs index 101a9ab9da..d70a15a11b 100644 --- a/crates/relayer-cli/src/commands/listen.rs +++ b/crates/relayer-cli/src/commands/listen.rs @@ -148,7 +148,7 @@ fn subscribe( // Q: Should this be restricted only to backends that support it, // or are all backends expected to support subscriptions? match chain_config { - ChainConfig::CosmosSdk(config) => { + ChainConfig::CosmosSdk(config) | ChainConfig::Namada(config) => { let (event_source, monitor_tx) = match &config.event_source { EventSourceMode::Push { url, batch_delay } => EventSource::websocket( chain_config.id().clone(), @@ -189,12 +189,12 @@ fn detect_compatibility_mode( ) -> eyre::Result { // TODO(erwan): move this to the cosmos sdk endpoint implementation let rpc_addr = match config { - ChainConfig::CosmosSdk(config) => config.rpc_addr.clone(), + ChainConfig::CosmosSdk(config) | ChainConfig::Namada(config) => config.rpc_addr.clone(), }; let client = HttpClient::new(rpc_addr)?; let status = rt.block_on(client.status())?; let compat_mode = match config { - ChainConfig::CosmosSdk(config) => { + ChainConfig::CosmosSdk(config) | ChainConfig::Namada(config) => { compat_mode_from_version(&config.compat_mode, status.node_info.version)?.into() } }; diff --git a/crates/relayer-cli/src/commands/tx/client.rs b/crates/relayer-cli/src/commands/tx/client.rs index 827d1c5cc1..9e67d277eb 100644 --- a/crates/relayer-cli/src/commands/tx/client.rs +++ b/crates/relayer-cli/src/commands/tx/client.rs @@ -206,7 +206,7 @@ impl Runnable for TxUpdateClientCmd { if let Some(restart_params) = self.genesis_restart_params() { match config.find_chain_mut(&reference_chain_id) { Some(chain_config) => match chain_config { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.genesis_restart = Some(restart_params) } }, diff --git a/crates/relayer-rest/Cargo.toml b/crates/relayer-rest/Cargo.toml index d831f4bda8..6a968f4bc2 100644 --- a/crates/relayer-rest/Cargo.toml +++ b/crates/relayer-rest/Cargo.toml @@ -24,5 +24,6 @@ tokio = { workspace = true } tracing = { workspace = true } [dev-dependencies] -reqwest = { workspace = true, features = ["json"] } -toml = { workspace = true } +reqwest = { workspace = true, features = ["json"] } +serde_json = { workspace = true } +toml = { workspace = true } diff --git a/crates/relayer-rest/tests/mock.rs b/crates/relayer-rest/tests/mock.rs index 4029db0bc7..2a7f879866 100644 --- a/crates/relayer-rest/tests/mock.rs +++ b/crates/relayer-rest/tests/mock.rs @@ -46,9 +46,12 @@ where let response = reqwest::get(&format!("http://127.0.0.1:{port}{path}")) .await .unwrap() - .json::() + .json() .await .unwrap(); + // Workaround for serde_json deserialization failure + // from_str/from_slice() failed for ChainConfig + let response = serde_json::from_value::(response).unwrap(); assert_eq!(response, expected); diff --git a/crates/relayer-types/src/events.rs b/crates/relayer-types/src/events.rs index 7ceb45d5c2..1d27cc337a 100644 --- a/crates/relayer-types/src/events.rs +++ b/crates/relayer-types/src/events.rs @@ -282,7 +282,7 @@ impl FromStr for IbcEventType { } /// Events created by the IBC component of a chain, destined for a relayer. -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, PartialEq)] pub enum IbcEvent { NewBlock(NewBlock), diff --git a/crates/relayer/Cargo.toml b/crates/relayer/Cargo.toml index 7691ca00ea..8057a02298 100644 --- a/crates/relayer/Cargo.toml +++ b/crates/relayer/Cargo.toml @@ -46,6 +46,10 @@ humantime = { workspace = true } humantime-serde = { workspace = true } itertools = { workspace = true } moka = { workspace = true, features = ["sync"] } +namada_ibc = { workspace = true } +namada_parameters = { workspace = true } +namada_sdk = { workspace = true } +namada_token = { workspace = true } num-bigint = { workspace = true, features = ["serde"] } num-rational = { workspace = true, features = ["num-bigint", "serde"] } once_cell = { workspace = true } @@ -54,6 +58,7 @@ regex = { workspace = true } reqwest = { workspace = true, features = ["rustls-tls-native-roots", "json"] } retry = { workspace = true } ripemd = { workspace = true } +rpassword = { workspace = true } secp256k1 = { workspace = true, features = ["rand-std"] } semver = { workspace = true } serde = { workspace = true } diff --git a/crates/relayer/src/chain.rs b/crates/relayer/src/chain.rs index bcca34e85f..5e37f13926 100644 --- a/crates/relayer/src/chain.rs +++ b/crates/relayer/src/chain.rs @@ -3,6 +3,7 @@ pub mod cosmos; pub mod counterparty; pub mod endpoint; pub mod handle; +pub mod namada; pub mod requests; pub mod runtime; pub mod tracking; diff --git a/crates/relayer/src/chain/client.rs b/crates/relayer/src/chain/client.rs index 6f00ec8df9..54341c525d 100644 --- a/crates/relayer/src/chain/client.rs +++ b/crates/relayer/src/chain/client.rs @@ -27,9 +27,12 @@ impl ClientSettings { // // TODO: extract Tendermint-related configs into a separate substructure // that can be used both by CosmosSdkConfig and configs for nonSDK chains. - use ChainConfig::CosmosSdk as Csdk; + use ChainConfig::{CosmosSdk as Csdk, Namada}; match (src_chain_config, dst_chain_config) { - (Csdk(src_chain_config), Csdk(dst_chain_config)) => { + (Csdk(src_chain_config), Csdk(dst_chain_config)) + | (Namada(src_chain_config), Namada(dst_chain_config)) + | (Csdk(src_chain_config), Namada(dst_chain_config)) + | (Namada(src_chain_config), Csdk(dst_chain_config)) => { ClientSettings::Tendermint(cosmos::client::Settings::for_create_command( options, src_chain_config, diff --git a/crates/relayer/src/chain/cosmos/batch.rs b/crates/relayer/src/chain/cosmos/batch.rs index 3e52f52aec..bf55a4ec27 100644 --- a/crates/relayer/src/chain/cosmos/batch.rs +++ b/crates/relayer/src/chain/cosmos/batch.rs @@ -209,7 +209,7 @@ async fn sequential_send_messages_as_batches( Ok(tx_sync_results) } -fn response_to_tx_sync_result( +pub fn response_to_tx_sync_result( chain_id: &ChainId, message_count: usize, response: Response, diff --git a/crates/relayer/src/chain/cosmos/config.rs b/crates/relayer/src/chain/cosmos/config.rs index 5e85f2a11d..5ce9f4b707 100644 --- a/crates/relayer/src/chain/cosmos/config.rs +++ b/crates/relayer/src/chain/cosmos/config.rs @@ -165,7 +165,7 @@ impl CosmosSdkConfig { /// a) non-zero /// b) greater or equal to 1/3 /// c) strictly less than 1 -fn validate_trust_threshold( +pub fn validate_trust_threshold( id: &ChainId, trust_threshold: TrustThreshold, ) -> Result<(), Diagnostic> { diff --git a/crates/relayer/src/chain/cosmos/wait.rs b/crates/relayer/src/chain/cosmos/wait.rs index 9ff26b2cce..06d2b3f3b6 100644 --- a/crates/relayer/src/chain/cosmos/wait.rs +++ b/crates/relayer/src/chain/cosmos/wait.rs @@ -117,7 +117,7 @@ async fn update_tx_sync_result( Ok(()) } -fn all_tx_results_found(tx_sync_results: &[TxSyncResult]) -> bool { +pub fn all_tx_results_found(tx_sync_results: &[TxSyncResult]) -> bool { tx_sync_results .iter() .all(|r| matches!(r.status, TxStatus::ReceivedResponse)) diff --git a/crates/relayer/src/chain/namada.rs b/crates/relayer/src/chain/namada.rs new file mode 100644 index 0000000000..85153c2386 --- /dev/null +++ b/crates/relayer/src/chain/namada.rs @@ -0,0 +1,1289 @@ +use alloc::sync::Arc; +use core::str::FromStr; +use std::thread; + +use core::time::Duration; + +use ibc_proto::ibc::applications::fee::v1::{ + QueryIncentivizedPacketRequest, QueryIncentivizedPacketResponse, +}; +use ibc_proto::ibc::core::channel::v1::{QueryUpgradeErrorRequest, QueryUpgradeRequest}; +use ibc_proto::Protobuf; +use ibc_relayer_types::applications::ics31_icq::response::CrossChainQueryResponse; +use ibc_relayer_types::clients::ics07_tendermint::client_state::{ + AllowUpdate, ClientState as TmClientState, +}; +use ibc_relayer_types::clients::ics07_tendermint::consensus_state::ConsensusState as TmConsensusState; +use ibc_relayer_types::clients::ics07_tendermint::header::Header as TmHeader; +use ibc_relayer_types::core::ics02_client::events::UpdateClient; +use ibc_relayer_types::core::ics03_connection::connection::{ + ConnectionEnd, IdentifiedConnectionEnd, +}; +use ibc_relayer_types::core::ics04_channel::channel::{ChannelEnd, IdentifiedChannelEnd}; +use ibc_relayer_types::core::ics04_channel::packet::Sequence; +use ibc_relayer_types::core::ics04_channel::upgrade::{ErrorReceipt, Upgrade}; +use ibc_relayer_types::core::ics23_commitment::commitment::CommitmentPrefix; +use ibc_relayer_types::core::ics23_commitment::merkle::MerkleProof; +use ibc_relayer_types::core::ics24_host::identifier::{ + ChainId, ChannelId, ClientId, ConnectionId, PortId, +}; +use ibc_relayer_types::core::ics24_host::path::{ + AcksPath, ChannelEndsPath, ChannelUpgradeErrorPath, ChannelUpgradePath, + ClientConsensusStatePath, ClientStatePath, CommitmentsPath, ConnectionsPath, ReceiptsPath, + SeqRecvsPath, +}; +use ibc_relayer_types::signer::Signer; +use ibc_relayer_types::Height as ICSHeight; +use namada_ibc::storage; +use namada_parameters::{storage as param_storage, EpochDuration}; +use namada_sdk::address::{Address, InternalAddress}; +use namada_sdk::borsh::BorshDeserialize; +use namada_sdk::io::NullIo; +use namada_sdk::masp::fs::FsShieldedUtils; +use namada_sdk::masp::DefaultLogger; +use namada_sdk::proof_of_stake::storage_key as pos_storage_key; +use namada_sdk::proof_of_stake::OwnedPosParams; +use namada_sdk::queries::Client as SdkClient; +use namada_sdk::state::ics23_specs::ibc_proof_specs; +use namada_sdk::state::Sha256Hasher; +use namada_sdk::storage::{Key, KeySeg, PrefixValue}; +use namada_sdk::wallet::Store; +use namada_sdk::wallet::Wallet; +use namada_sdk::{rpc, Namada, NamadaImpl}; +use namada_token::storage_key::{balance_key, denom_key, is_any_token_balance_key}; +use namada_token::{Amount, DenominatedAmount, Denomination}; +use tendermint::block::Height as TmHeight; +use tendermint::{node, Time}; +use tendermint_light_client::types::LightBlock as TMLightBlock; +use tendermint_rpc::client::CompatMode; +use tendermint_rpc::endpoint::broadcast::tx_sync::Response; +use tendermint_rpc::{Client, HttpClient}; +use tokio::runtime::Runtime as TokioRuntime; + +use crate::account::Balance; +use crate::chain::client::ClientSettings; +use crate::chain::cosmos::batch::response_to_tx_sync_result; +use crate::chain::cosmos::config::CosmosSdkConfig; +use crate::chain::cosmos::version::Specs; +use crate::chain::endpoint::{ChainEndpoint, ChainStatus, HealthCheck}; +use crate::chain::handle::Subscription; +use crate::chain::requests::*; +use crate::chain::tracking::TrackedMsgs; +use crate::client_state::{AnyClientState, IdentifiedAnyClientState}; +use crate::config::error::Error as ConfigError; +use crate::config::ChainConfig; +use crate::consensus_state::AnyConsensusState; +use crate::denom::DenomTrace; +use crate::error::Error; +use crate::event::source::{EventSource, TxEventSourceCmd}; +use crate::event::IbcEventWithHeight; +use crate::keyring::{KeyRing, NamadaKeyPair, SigningKeyPair}; +use crate::light_client::tendermint::LightClient as TmLightClient; +use crate::light_client::{LightClient, Verified}; +use crate::misbehaviour::MisbehaviourEvidence; + +use self::error::Error as NamadaError; + +pub mod error; +pub mod key; +mod query; +mod tx; +pub mod wallet; + +pub struct NamadaChain { + /// Reuse CosmosSdkConfig for tendermint's light clients + config: CosmosSdkConfig, + /// Namada context + ctx: NamadaImpl, + light_client: TmLightClient, + rt: Arc, + keybase: KeyRing, + tx_monitor_cmd: Option, +} + +impl NamadaChain { + fn config(&self) -> &CosmosSdkConfig { + &self.config + } + + fn init_event_source(&mut self) -> Result { + crate::time!( + "init_event_source", + { + "src_chain": self.config().id.to_string(), + } + ); + + let node_info = self + .rt + .block_on(fetch_node_info(self.ctx.client(), &self.config))?; + let compat_mode = CompatMode::from_version(node_info.version).unwrap_or(CompatMode::V0_37); + + use crate::config::EventSourceMode as Mode; + let (event_source, monitor_tx) = match &self.config.event_source { + Mode::Push { url, batch_delay } => EventSource::websocket( + self.config.id.clone(), + url.clone(), + compat_mode, + *batch_delay, + self.rt.clone(), + ), + Mode::Pull { + interval, + max_retries, + } => EventSource::rpc( + self.config.id.clone(), + self.ctx.client().clone(), + *interval, + *max_retries, + self.rt.clone(), + ), + } + .map_err(Error::event_source)?; + + thread::spawn(move || event_source.run()); + + Ok(monitor_tx) + } + + fn get_unbonding_time(&self) -> Result { + let key = pos_storage_key::params_key(); + let (value, _) = self.query(key, QueryHeight::Latest, IncludeProof::No)?; + let pos_params = + OwnedPosParams::try_from_slice(&value[..]).map_err(NamadaError::borsh_decode)?; + + let key = param_storage::get_epoch_duration_storage_key(); + let (value, _) = self.query(key, QueryHeight::Latest, IncludeProof::No)?; + let epoch_duration = + EpochDuration::try_from_slice(&value[..]).map_err(NamadaError::borsh_decode)?; + let unbonding_period = pos_params.pipeline_len * epoch_duration.min_duration.0; + Ok(Duration::from_secs(unbonding_period)) + } + + fn get_latest_block_time(&self) -> Result { + let status = self + .rt + .block_on(SdkClient::status(self.ctx.client())) + .map_err(|e| Error::rpc(self.config.rpc_addr.clone(), e))?; + Ok(status + .sync_info + .latest_block_time + .to_string() + .parse() + .unwrap()) + } + + async fn shielded_sync(&self) -> Result<(), Error> { + let mut shielded = self.ctx.shielded_mut().await; + let _ = shielded.load().await; + shielded + .fetch( + self.ctx.client(), + &DefaultLogger::new(self.ctx.io()), + None, + None, + 1, + &[], + &[], + ) + .await + .map_err(NamadaError::namada)?; + shielded.save().await.map_err(Error::io) + } +} + +impl ChainEndpoint for NamadaChain { + type LightBlock = TMLightBlock; + type Header = TmHeader; + type ConsensusState = TmConsensusState; + type ClientState = TmClientState; + type Time = Time; + type SigningKeyPair = NamadaKeyPair; + + fn id(&self) -> &ChainId { + &self.config.id + } + + fn config(&self) -> ChainConfig { + ChainConfig::Namada(self.config.clone()) + } + + fn bootstrap(config: ChainConfig, rt: Arc) -> Result { + #[allow(irrefutable_let_patterns)] + let ChainConfig::Namada(config) = config + else { + return Err(Error::config(ConfigError::wrong_type())); + }; + + let mut rpc_client = HttpClient::new(config.rpc_addr.clone()) + .map_err(|e| Error::rpc(config.rpc_addr.clone(), e))?; + rpc_client.set_compat_mode(CompatMode::V0_37); + + let node_info = rt.block_on(fetch_node_info(&rpc_client, &config))?; + let light_client = TmLightClient::from_cosmos_sdk_config(&config, node_info.id)?; + + let keybase = + KeyRing::new_namada(config.key_store_type, &config.id, &config.key_store_folder) + .map_err(Error::key_base)?; + + let shielded_dir = dirs_next::home_dir() + .expect("No home directory") + .join(".hermes/shielded") + .join(config.id.to_string()); + std::fs::create_dir_all(&shielded_dir).map_err(Error::io)?; + let shielded_ctx = FsShieldedUtils::new(shielded_dir); + + let mut store = Store::default(); + let key = keybase + .get_key(&config.key_name) + .map_err(|e| Error::key_not_found(config.key_name.clone(), e))?; + store.insert_keypair::( + config.key_name.clone().into(), + key.secret_key, + None, + Some(key.address), + None, + true, + ); + let wallet = Wallet::new(wallet::NullWalletUtils, store); + + let native_token = rt + .block_on(rpc::query_native_token(&rpc_client)) + .map_err(NamadaError::namada)?; + + // overwrite the proof spec + let config = CosmosSdkConfig { + proof_specs: Some(ibc_proof_specs::().into()), + ..config + }; + + let ctx = NamadaImpl::native_new(rpc_client, wallet, shielded_ctx, NullIo, native_token); + + Ok(Self { + config, + ctx, + light_client, + rt, + keybase, + tx_monitor_cmd: None, + }) + } + + fn shutdown(self) -> Result<(), Error> { + Ok(()) + } + + fn health_check(&mut self) -> Result { + self.rt + .block_on(SdkClient::health(self.ctx.client())) + .map_err(|e| { + Error::health_check_json_rpc( + self.config.id.clone(), + self.config.rpc_addr.to_string(), + "/health".to_string(), + e, + ) + })?; + + Ok(HealthCheck::Healthy) + } + + fn subscribe(&mut self) -> Result { + let tx_monitor_cmd = match &self.tx_monitor_cmd { + Some(tx_monitor_cmd) => tx_monitor_cmd, + None => { + let tx_monitor_cmd = self.init_event_source()?; + self.tx_monitor_cmd = Some(tx_monitor_cmd); + self.tx_monitor_cmd.as_ref().unwrap() + } + }; + + let subscription = tx_monitor_cmd.subscribe().map_err(Error::event_source)?; + Ok(subscription) + } + + fn keybase(&self) -> &KeyRing { + &self.keybase + } + + fn keybase_mut(&mut self) -> &mut KeyRing { + &mut self.keybase + } + + fn get_key(&self) -> Result { + self.keybase + .get_key(&self.config.key_name) + .map_err(|e| Error::key_not_found(self.config.key_name.clone(), e)) + } + + fn get_signer(&self) -> Result { + let key = self + .keybase + .get_key(&self.config.key_name) + .map_err(|e| Error::key_not_found(self.config.key_name.clone(), e))?; + Ok(Signer::from_str(&key.account()).expect("The key name shouldn't be empty")) + } + + fn version_specs(&self) -> Result { + unimplemented!() + } + + fn send_messages_and_wait_commit( + &mut self, + tracked_msgs: TrackedMsgs, + ) -> Result, Error> { + crate::time!("send_messages_and_wait_commit"); + + let proto_msgs = tracked_msgs.messages(); + if proto_msgs.is_empty() { + return Ok(vec![]); + } + let max_msg_num = if self.config().sequential_batch_tx { + 1 + } else { + self.config().max_msg_num.to_usize() + }; + let msg_chunks = proto_msgs.chunks(max_msg_num); + let mut tx_sync_results = vec![]; + for msg_chunk in msg_chunks { + let response = self.batch_txs(msg_chunk)?; + tx_sync_results.push(response_to_tx_sync_result( + &self.config().id, + msg_chunk.len(), + response, + )); + } + + self.wait_for_block_commits(&mut tx_sync_results)?; + + let events: Vec = tx_sync_results + .into_iter() + .flat_map(|el| el.events) + .collect(); + let mut dedup_events = vec![]; + for event in events { + if !dedup_events.contains(&event) { + dedup_events.push(event); + } + } + + Ok(dedup_events) + } + + fn send_messages_and_wait_check_tx( + &mut self, + tracked_msgs: TrackedMsgs, + ) -> Result, Error> { + crate::time!("send_messages_and_wait_check_tx"); + + let proto_msgs = tracked_msgs.messages(); + if proto_msgs.is_empty() { + return Ok(vec![]); + } + + let max_msg_num = if self.config().sequential_batch_tx { + 1 + } else { + self.config().max_msg_num.to_usize() + }; + let msg_chunks = proto_msgs.chunks(max_msg_num); + let mut responses = vec![]; + for msg_chunk in msg_chunks { + responses.push(self.batch_txs(msg_chunk)?); + } + + Ok(responses) + } + + fn verify_header( + &mut self, + trusted: ICSHeight, + target: ICSHeight, + client_state: &AnyClientState, + ) -> Result { + crate::time!( + "verify_header", + { + "src_chain": self.config().id.to_string(), + } + ); + + let now = self.get_latest_block_time()?; + self.light_client + .verify(trusted, target, client_state, now) + .map(|v| v.target) + } + + fn check_misbehaviour( + &mut self, + update: &UpdateClient, + client_state: &AnyClientState, + ) -> Result, Error> { + crate::time!( + "check_misbehaviour", + { + "src_chain": self.config().id.to_string(), + } + ); + + let now = self.get_latest_block_time()?; + self.light_client + .detect_misbehaviour(update, client_state, now) + } + + fn query_balance(&self, key_name: Option<&str>, denom: Option<&str>) -> Result { + // Given key_name and denom should be raw Namada addresses + let default_owner = self.get_signer()?; + let owner = key_name.unwrap_or(default_owner.as_ref()); + let owner = + Address::decode(owner).map_err(|_| NamadaError::address_decode(owner.to_string()))?; + + let default_token = self.ctx.native_token().to_string(); + let denom = denom.unwrap_or(&default_token); + let token = + Address::decode(denom).map_err(|_| NamadaError::address_decode(denom.to_string()))?; + + let balance_key = balance_key(&token, &owner); + let (value, _) = self.query(balance_key, QueryHeight::Latest, IncludeProof::No)?; + if value.is_empty() { + return Ok(Balance { + amount: "0".to_string(), + denom: denom.to_string(), + }); + } + let amount = Amount::try_from_slice(&value[..]).map_err(NamadaError::borsh_decode)?; + let denom_key = denom_key(&token); + let (value, _) = self.query(denom_key, QueryHeight::Latest, IncludeProof::No)?; + let denominated_amount = if value.is_empty() { + DenominatedAmount::new(amount, 0.into()) + } else { + let token_denom = + Denomination::try_from_slice(&value[..]).map_err(NamadaError::borsh_decode)?; + DenominatedAmount::new(amount, token_denom) + }; + + Ok(Balance { + amount: denominated_amount.to_string(), + denom: denom.to_string(), + }) + } + + fn query_all_balances(&self, key_name: Option<&str>) -> Result, Error> { + let default_owner = self.get_signer()?; + let owner = key_name.unwrap_or(default_owner.as_ref()); + let owner = + Address::decode(owner).map_err(|_| NamadaError::address_decode(owner.to_string()))?; + + let mut balances = vec![]; + let prefix = Key::from(Address::Internal(InternalAddress::Multitoken).to_db_key()); + for PrefixValue { key, value } in self.query_prefix(prefix)? { + if let Some([token, bal_owner]) = is_any_token_balance_key(&key) { + if owner == *bal_owner { + let amount = + Amount::try_from_slice(&value[..]).map_err(NamadaError::borsh_decode)?; + let denom_key = denom_key(token); + let (value, _) = + self.query(denom_key, QueryHeight::Latest, IncludeProof::No)?; + let denominated_amount = if value.is_empty() { + DenominatedAmount::new(amount, 0.into()) + } else { + let namada_denom = Denomination::try_from_slice(&value[..]) + .map_err(NamadaError::borsh_decode)?; + DenominatedAmount::new(amount, namada_denom) + }; + let balance = Balance { + amount: denominated_amount.to_string(), + denom: token.to_string(), + }; + balances.push(balance); + } + } + } + Ok(balances) + } + + // Query the denom trace with "{IbcToken}" address which has a hashed denom. + fn query_denom_trace(&self, hash: String) -> Result { + let denom = self.query_denom(hash)?; + match denom.rsplit_once('/') { + Some((path, base_denom)) => Ok(DenomTrace { + path: path.to_string(), + base_denom: base_denom.to_string(), + }), + None => Err(Error::query(format!( + "The denom is not a PrefixedDenom: denom {}", + denom + ))), + } + } + + fn query_commitment_prefix(&self) -> Result { + crate::time!( + "query_commitment_prefix", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_commitment_prefix"); + + CommitmentPrefix::try_from(b"ibc".to_vec()).map_err(Error::ics23) + } + + fn query_application_status(&self) -> Result { + crate::time!( + "query_application_status", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_application_status"); + + let status = self + .rt + .block_on(SdkClient::status(self.ctx.client())) + .map_err(|e| Error::rpc(self.config.rpc_addr.clone(), e))?; + + if status.sync_info.catching_up { + return Err(Error::chain_not_caught_up( + self.config.rpc_addr.to_string(), + self.config().id.clone(), + )); + } + + let time = self.get_latest_block_time()?; + let height = ICSHeight::new( + ChainId::chain_version(status.node_info.network.as_str()), + u64::from(status.sync_info.latest_block_height), + ) + .map_err(Error::ics02)?; + + Ok(ChainStatus { + height, + timestamp: time.into(), + }) + } + + fn query_clients( + &self, + _request: QueryClientStatesRequest, + ) -> Result, Error> { + crate::time!( + "query_clients", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_clients"); + + let prefix = storage::ibc_key("clients").expect("the path should be parsable"); + let mut states = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value } = prefix_value; + if key.to_string().ends_with("clientState") { + let client_id = + storage::client_id(&key).map_err(|e| Error::query(e.to_string()))?; + let client_id = ClientId::from_str(&client_id.to_string()).unwrap(); + let client_state = AnyClientState::decode_vec(&value).map_err(Error::decode)?; + states.push(IdentifiedAnyClientState::new(client_id, client_state)); + } + } + + Ok(states) + } + + fn query_client_state( + &self, + request: QueryClientStateRequest, + include_proof: IncludeProof, + ) -> Result<(AnyClientState, Option), Error> { + crate::time!( + "query_client_state", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_client_state"); + + let path = ClientStatePath(request.client_id); + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, request.height, include_proof)?; + let client_state = AnyClientState::decode_vec(&value).map_err(Error::decode)?; + + Ok((client_state, proof)) + } + + fn query_consensus_state( + &self, + request: QueryConsensusStateRequest, + include_proof: IncludeProof, + ) -> Result<(AnyConsensusState, Option), Error> { + crate::time!( + "query_consensus_state", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_consensus_state"); + + let path = ClientConsensusStatePath { + client_id: request.client_id, + epoch: request.consensus_height.revision_number(), + height: request.consensus_height.revision_height(), + }; + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, request.query_height, include_proof)?; + let consensus_state = AnyConsensusState::decode_vec(&value).map_err(Error::decode)?; + Ok((consensus_state, proof)) + } + + fn query_consensus_state_heights( + &self, + request: QueryConsensusStateHeightsRequest, + ) -> Result, Error> { + let prefix = storage::ibc_key(format!("clients/{}", request.client_id)) + .expect("the path should be parsable"); + let mut heights = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value: _ } = prefix_value; + match storage::consensus_height(&key) { + Ok(h) => { + let height = ICSHeight::new(h.revision_number(), h.revision_height()).unwrap(); + heights.push(height); + } + // the key is not for a consensus state + Err(_) => continue, + } + } + Ok(heights) + } + + fn query_upgraded_client_state( + &self, + _request: QueryUpgradedClientStateRequest, + ) -> Result<(AnyClientState, MerkleProof), Error> { + crate::time!( + "query_upgraded_client_state", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_upgraded_client_state"); + + unimplemented!() + } + + fn query_upgraded_consensus_state( + &self, + _request: QueryUpgradedConsensusStateRequest, + ) -> Result<(AnyConsensusState, MerkleProof), Error> { + crate::time!( + "query_upgraded_consensus_state", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_upgraded_consensus_state"); + + unimplemented!() + } + + fn query_connections( + &self, + _request: QueryConnectionsRequest, + ) -> Result, Error> { + crate::time!( + "query_connections", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_connections"); + + let prefix = storage::ibc_key("connections").expect("the path should be parsable"); + let mut connections = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value } = prefix_value; + // "connections/counter" should be skipped + if key == storage::connection_counter_key() { + continue; + } + let conn_id = storage::connection_id(&key).map_err(|e| Error::query(e.to_string()))?; + let connection_id = conn_id + .as_str() + .parse() + .expect("The connection ID should be parsable"); + let connection = ConnectionEnd::decode_vec(&value).map_err(Error::decode)?; + connections.push(IdentifiedConnectionEnd::new(connection_id, connection)); + } + + Ok(connections) + } + + fn query_client_connections( + &self, + request: QueryClientConnectionsRequest, + ) -> Result, Error> { + crate::time!( + "query_client_connections", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_client_connections"); + + let query_request = QueryConnectionsRequest { pagination: None }; + let connections = self.query_connections(query_request)?; + let ids = connections + .iter() + .filter(|c| *c.connection_end.client_id() == request.client_id) + .map(|c| c.connection_id.clone()) + .collect(); + Ok(ids) + } + + fn query_connection( + &self, + request: QueryConnectionRequest, + include_proof: IncludeProof, + ) -> Result<(ConnectionEnd, Option), Error> { + crate::time!( + "query_connection", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_connection"); + + let path = ConnectionsPath(request.connection_id); + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, request.height, include_proof)?; + let connection_end = ConnectionEnd::decode_vec(&value).map_err(Error::decode)?; + Ok((connection_end, proof)) + } + + fn query_connection_channels( + &self, + request: QueryConnectionChannelsRequest, + ) -> Result, Error> { + crate::time!( + "query_connection_channels", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_connection_channels"); + + let hops = vec![request.connection_id]; + let query_request = QueryChannelsRequest { pagination: None }; + let channels = self + .query_channels(query_request)? + .into_iter() + .filter(|c| c.channel_end.connection_hops_matches(&hops)) + .collect(); + + Ok(channels) + } + + fn query_channels( + &self, + _request: QueryChannelsRequest, + ) -> Result, Error> { + crate::time!( + "query_channels", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_channels"); + + let prefix = storage::ibc_key("channelEnds").expect("the path should be parsable"); + let mut channels = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value } = prefix_value; + // "channelEnds/counter" should be skipped + if key == storage::channel_counter_key() { + continue; + } + let (port_id, channel_id) = + storage::port_channel_id(&key).map_err(|e| Error::query(e.to_string()))?; + let port_id = port_id.as_ref().parse().unwrap(); + let channel_id = channel_id.as_ref().parse().unwrap(); + let channel = ChannelEnd::decode_vec(&value).map_err(Error::decode)?; + channels.push(IdentifiedChannelEnd::new(port_id, channel_id, channel)) + } + + Ok(channels) + } + + fn query_channel( + &self, + request: QueryChannelRequest, + include_proof: IncludeProof, + ) -> Result<(ChannelEnd, Option), Error> { + crate::time!( + "query_channel", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_channel"); + + let path = ChannelEndsPath(request.port_id, request.channel_id); + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, request.height, include_proof)?; + let channel_end = ChannelEnd::decode_vec(&value).map_err(Error::decode)?; + Ok((channel_end, proof)) + } + + fn query_channel_client_state( + &self, + request: QueryChannelClientStateRequest, + ) -> Result, Error> { + crate::time!( + "query_channel_client_state", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_channel_client_state"); + + let request = QueryChannelRequest { + port_id: request.port_id, + channel_id: request.channel_id, + height: QueryHeight::Latest, + }; + let (channel_end, _) = self.query_channel(request, IncludeProof::No)?; + let connection_id = channel_end + .connection_hops() + .first() + .ok_or_else(|| Error::query("no connection ID in the channel end".to_string()))? + .clone(); + let request = QueryConnectionRequest { + connection_id, + height: QueryHeight::Latest, + }; + let (connection_end, _) = self.query_connection(request, IncludeProof::No)?; + let client_id = connection_end.client_id().clone(); + let request = QueryClientStateRequest { + client_id: client_id.clone(), + height: QueryHeight::Latest, + }; + let (client_state, _) = self.query_client_state(request, IncludeProof::No)?; + + Ok(Some(IdentifiedAnyClientState { + client_id, + client_state, + })) + } + + fn query_packet_commitment( + &self, + request: QueryPacketCommitmentRequest, + include_proof: IncludeProof, + ) -> Result<(Vec, Option), Error> { + let path = CommitmentsPath { + port_id: request.port_id, + channel_id: request.channel_id, + sequence: request.sequence, + }; + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + self.query(key, request.height, include_proof) + } + + fn query_packet_commitments( + &self, + request: QueryPacketCommitmentsRequest, + ) -> Result<(Vec, ICSHeight), Error> { + crate::time!( + "query_packet_commitments", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_packet_commitments"); + + let path = format!( + "commitments/ports/{}/channels/{}/sequences", + request.port_id, request.channel_id + ); + let prefix = storage::ibc_key(path).expect("the path should be parsable"); + let mut sequences = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value: _ } = prefix_value; + let (_, _, sequence) = + storage::port_channel_sequence_id(&key).map_err(|e| Error::query(e.to_string()))?; + let sequence = u64::from(sequence).into(); + sequences.push(sequence); + } + + // NOTE the height might be mismatched with the previous query + let status = self.query_application_status()?; + + Ok((sequences, status.height)) + } + + fn query_packet_receipt( + &self, + request: QueryPacketReceiptRequest, + include_proof: IncludeProof, + ) -> Result<(Vec, Option), Error> { + let path = ReceiptsPath { + port_id: request.port_id, + channel_id: request.channel_id, + sequence: request.sequence, + }; + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + self.query(key, request.height, include_proof) + } + + fn query_unreceived_packets( + &self, + request: QueryUnreceivedPacketsRequest, + ) -> Result, Error> { + crate::time!( + "query_unreceived_packets", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_unreceived_packets"); + + let path = format!( + "receipts/ports/{}/channels/{}/sequences", + request.port_id, request.channel_id + ); + let prefix = storage::ibc_key(path).expect("the path should be parsable"); + let mut received_seqs = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let (_, _, sequence) = storage::port_channel_sequence_id(&prefix_value.key) + .map_err(|e| Error::query(e.to_string()))?; + let sequence = u64::from(sequence).into(); + received_seqs.push(sequence) + } + + let unreceived_seqs = request + .packet_commitment_sequences + .into_iter() + .filter(|seq| !received_seqs.contains(seq)) + .collect(); + + Ok(unreceived_seqs) + } + + fn query_packet_acknowledgement( + &self, + request: QueryPacketAcknowledgementRequest, + include_proof: IncludeProof, + ) -> Result<(Vec, Option), Error> { + let path = AcksPath { + port_id: request.port_id, + channel_id: request.channel_id, + sequence: request.sequence, + }; + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + self.query(key, request.height, include_proof) + } + + fn query_packet_acknowledgements( + &self, + request: QueryPacketAcknowledgementsRequest, + ) -> Result<(Vec, ICSHeight), Error> { + crate::time!( + "query_packet_acknowledgements", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_packet_acknowledgements"); + + let path = format!( + "acks/ports/{}/channels/{}/sequences", + request.port_id, request.channel_id + ); + let prefix = storage::ibc_key(path).expect("the path should be parsable"); + let mut sequences = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value: _ } = prefix_value; + let (_, _, sequence) = + storage::port_channel_sequence_id(&key).map_err(|e| Error::query(e.to_string()))?; + let sequence = u64::from(sequence).into(); + if request.packet_commitment_sequences.contains(&sequence) { + sequences.push(sequence); + } + } + + // NOTE the height might be mismatched with the previous query + let status = self.query_application_status()?; + Ok((sequences, status.height)) + } + + fn query_unreceived_acknowledgements( + &self, + request: QueryUnreceivedAcksRequest, + ) -> Result, Error> { + crate::time!( + "query_unreceived_acknowledgements", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_unreceived_acknowledgements"); + + let path = format!( + "commitments/ports/{}/channels/{}/sequences", + request.port_id, request.channel_id + ); + let prefix = storage::ibc_key(path).expect("the path should be parsable"); + let mut unreceived_seqs = vec![]; + for prefix_value in self.query_prefix(prefix)? { + let PrefixValue { key, value: _ } = prefix_value; + let (_, _, sequence) = + storage::port_channel_sequence_id(&key).map_err(|e| Error::query(e.to_string()))?; + let sequence = u64::from(sequence).into(); + if request.packet_ack_sequences.contains(&sequence) { + unreceived_seqs.push(sequence); + } + } + Ok(unreceived_seqs) + } + + fn query_next_sequence_receive( + &self, + request: QueryNextSequenceReceiveRequest, + include_proof: IncludeProof, + ) -> Result<(Sequence, Option), Error> { + crate::time!( + "query_next_sequence_receive", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_next_sequence_receive"); + + let path = SeqRecvsPath(request.port_id, request.channel_id); + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, request.height, include_proof)?; + + // As ibc-go, the sequence index is encoded with big-endian + let index: [u8; 8] = value + .try_into() + .map_err(|_| Error::query("Encoding u64 failed".to_owned()))?; + let sequence = u64::from_be_bytes(index).into(); + + Ok((sequence, proof)) + } + + fn query_txs(&self, request: QueryTxRequest) -> Result, Error> { + crate::time!("query_txs", + { + "src_chain": self.config().id.to_string(), + }); + crate::telemetry!(query, self.id(), "query_txs"); + + match request { + QueryTxRequest::Client(request) => { + crate::time!("query_txs: single client update event"); + match self.query_update_event(&request)? { + Some(event) => Ok(vec![event]), + None => Ok(vec![]), + } + } + QueryTxRequest::Transaction(tx) => self.query_tx_events(&tx.0), + } + } + + fn query_packet_events( + &self, + request: QueryPacketEventDataRequest, + ) -> Result, Error> { + crate::time!( + "query_packet_events", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_packet_events"); + self.query_packet_events_from_block(&request) + } + + fn query_host_consensus_state( + &self, + request: QueryHostConsensusStateRequest, + ) -> Result { + let height = match request.height { + QueryHeight::Latest => TmHeight::from(0u32), + QueryHeight::Specific(ibc_height) => { + TmHeight::try_from(ibc_height.revision_height()).map_err(Error::invalid_height)? + } + }; + + let rpc_call = match height.value() { + 0 => SdkClient::latest_block(self.ctx.client()), + _ => SdkClient::block(self.ctx.client(), height), + }; + let response = self + .rt + .block_on(rpc_call) + .map_err(|e| Error::rpc(self.config.rpc_addr.clone(), e))?; + Ok(Self::ConsensusState::from(response.block.header)) + } + + fn build_client_state( + &self, + height: ICSHeight, + settings: ClientSettings, + ) -> Result { + let ClientSettings::Tendermint(settings) = settings; + let unbonding_period = self.get_unbonding_time()?; + let trusting_period = settings.trusting_period.unwrap_or_else(|| { + self.config + .trusting_period + .unwrap_or(2 * unbonding_period / 3) + }); + TmClientState::new( + self.id().clone(), + settings.trust_threshold, + trusting_period, + unbonding_period, + settings.max_clock_drift, + height, + self.config.proof_specs.clone().unwrap(), + vec![], + AllowUpdate { + after_expiry: true, + after_misbehaviour: true, + }, + ) + .map_err(Error::ics07) + } + + fn build_consensus_state( + &self, + light_block: Self::LightBlock, + ) -> Result { + crate::time!( + "build_consensus_state", + { + "src_chain": self.config().id.to_string(), + } + ); + + Ok(TmConsensusState::from(light_block.signed_header.header)) + } + + fn build_header( + &mut self, + trusted_height: ICSHeight, + target_height: ICSHeight, + client_state: &AnyClientState, + ) -> Result<(Self::Header, Vec), Error> { + crate::time!( + "build_header", + { + "src_chain": self.config().id.to_string(), + } + ); + + let now = self.get_latest_block_time()?; + // Get the light block at target_height from chain. + let Verified { target, supporting } = self.light_client.header_and_minimal_set( + trusted_height, + target_height, + client_state, + now, + )?; + + Ok((target, supporting)) + } + + fn maybe_register_counterparty_payee( + &mut self, + _channel_id: &ChannelId, + _port_id: &PortId, + _counterparty_payee: &Signer, + ) -> Result<(), Error> { + // not supported + unimplemented!() + } + + fn cross_chain_query( + &self, + _requests: Vec, + ) -> Result, Error> { + // not supported + unimplemented!() + } + + fn query_incentivized_packet( + &self, + _request: QueryIncentivizedPacketRequest, + ) -> Result { + // not supported + unimplemented!() + } + + fn query_consumer_chains(&self) -> Result, Error> { + // not supported + unimplemented!() + } + + fn query_upgrade( + &self, + request: QueryUpgradeRequest, + height: ICSHeight, + include_proof: IncludeProof, + ) -> Result<(Upgrade, Option), Error> { + let port_id = PortId::from_str(&request.port_id) + .map_err(|_| Error::invalid_port_string(request.port_id))?; + let channel_id = ChannelId::from_str(&request.channel_id) + .map_err(|_| Error::invalid_channel_string(request.channel_id))?; + let path = ChannelUpgradePath { + port_id, + channel_id, + }; + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, QueryHeight::Specific(height), include_proof)?; + + let upgrade = Upgrade::decode_vec(&value).map_err(Error::decode)?; + + Ok((upgrade, proof)) + } + + fn query_upgrade_error( + &self, + request: QueryUpgradeErrorRequest, + height: ICSHeight, + include_proof: IncludeProof, + ) -> Result<(ErrorReceipt, Option), Error> { + let port_id = PortId::from_str(&request.port_id) + .map_err(|_| Error::invalid_port_string(request.port_id))?; + let channel_id = ChannelId::from_str(&request.channel_id) + .map_err(|_| Error::invalid_channel_string(request.channel_id))?; + let path = ChannelUpgradeErrorPath { + port_id, + channel_id, + }; + let key = storage::ibc_key(path.to_string()).expect("the path should be parsable"); + let (value, proof) = self.query(key, QueryHeight::Specific(height), include_proof)?; + + let error_receipt = ErrorReceipt::decode_vec(&value).map_err(Error::decode)?; + + Ok((error_receipt, proof)) + } +} + +/// Fetch the node info +async fn fetch_node_info( + rpc_client: &HttpClient, + config: &CosmosSdkConfig, +) -> Result { + crate::time!("fetch_node_info", + { + "src_chain": config.id.to_string(), + }); + + Client::status(rpc_client) + .await + .map(|s| s.node_info) + .map_err(|e| Error::rpc(config.rpc_addr.clone(), e)) +} diff --git a/crates/relayer/src/chain/namada/error.rs b/crates/relayer/src/chain/namada/error.rs new file mode 100644 index 0000000000..85f5d46527 --- /dev/null +++ b/crates/relayer/src/chain/namada/error.rs @@ -0,0 +1,31 @@ +use flex_error::{define_error, TraceError}; + +define_error! { + Error { + AddressDecode + { raw: String } + |e| { format!("Namada address decoding failed for {}", e.raw) }, + + DenomNotFound + { denom: String } + |e| { format!("No denom for {}", e.denom) }, + + Namada + [ TraceError ] + |_| { "Namada error" }, + + Query + [ TraceError ] + |_| { "Query error" }, + + BorshDecode + [ TraceError ] + |_| { "borsh decoding failed" }, + } +} + +impl From for crate::error::Error { + fn from(error: Error) -> Self { + Self::namada(error) + } +} diff --git a/crates/relayer/src/chain/namada/key.rs b/crates/relayer/src/chain/namada/key.rs new file mode 100644 index 0000000000..9f8486dc52 --- /dev/null +++ b/crates/relayer/src/chain/namada/key.rs @@ -0,0 +1,47 @@ +use core::any::Any; + +use namada_sdk::address::Address; +use namada_sdk::key::common::SecretKey; + +use crate::config::AddressType; +use crate::keyring::errors::Error; +use crate::keyring::{KeyFile, KeyType, SigningKeyPair}; +use hdpath::StandardHDPath; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NamadaKeyPair { + pub alias: String, + pub address: Address, + pub secret_key: SecretKey, +} + +impl SigningKeyPair for NamadaKeyPair { + const KEY_TYPE: KeyType = KeyType::Secp256k1; + type KeyFile = KeyFile; + + fn from_key_file(_key_file: Self::KeyFile, _hd_path: &StandardHDPath) -> Result { + unimplemented!("Namada key can't be restored from a KeyFile") + } + + fn from_mnemonic( + _mnemonic: &str, + _hd_path: &StandardHDPath, + _address_type: &AddressType, + _account_prefix: &str, + ) -> Result { + unimplemented!("Namada key can't be restored from a KeyFile") + } + + fn account(&self) -> String { + self.address.to_string() + } + + fn sign(&self, _message: &[u8]) -> Result, Error> { + unimplemented!("don't use this to sign a Namada transaction") + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/crates/relayer/src/chain/namada/query.rs b/crates/relayer/src/chain/namada/query.rs new file mode 100644 index 0000000000..e7dfc865bf --- /dev/null +++ b/crates/relayer/src/chain/namada/query.rs @@ -0,0 +1,303 @@ +use ibc_relayer_types::core::ics04_channel::packet::Sequence; +use ibc_relayer_types::core::ics23_commitment::merkle::convert_tm_to_ics_merkle_proof; +use ibc_relayer_types::core::ics23_commitment::merkle::MerkleProof; +use ibc_relayer_types::events::IbcEvent; +use ibc_relayer_types::Height as ICSHeight; +use namada_ibc::storage::{ibc_trace_key_prefix, is_ibc_trace_key}; +use namada_sdk::address::{Address, InternalAddress}; +use namada_sdk::borsh::BorshDeserialize; +use namada_sdk::events::extend::Height as HeightAttr; +use namada_sdk::events::Event as NamadaEvent; +use namada_sdk::queries::{Client as SdkClient, RPC}; +use namada_sdk::rpc; +use namada_sdk::storage::{BlockHeight, Epoch, Key, PrefixValue}; +use namada_sdk::tx::event::Batch as BatchAttr; +use namada_sdk::Namada; +use tendermint::block::Height as TmHeight; +use tendermint::Hash as TmHash; + +use crate::chain::endpoint::ChainEndpoint; +use crate::chain::requests::{ + IncludeProof, QueryClientEventRequest, QueryHeight, QueryPacketEventDataRequest, +}; +use crate::error::Error; +use crate::event::{ibc_event_try_from_abci_event, IbcEventWithHeight}; + +use super::error::Error as NamadaError; +use super::NamadaChain; + +impl NamadaChain { + pub fn query( + &self, + key: Key, + height: QueryHeight, + include_proof: IncludeProof, + ) -> Result<(Vec, Option), Error> { + let height = match height { + QueryHeight::Latest => None, + QueryHeight::Specific(h) => Some(BlockHeight(h.revision_height())), + }; + let is_proven = matches!(include_proof, IncludeProof::Yes); + let (value, proof) = self + .rt + .block_on(rpc::query_storage_value_bytes( + self.ctx.client(), + &key, + height, + is_proven, + )) + .map_err(NamadaError::namada)?; + + let proof = if is_proven { + let proof_ops = proof.ok_or_else(Error::empty_response_proof)?; + let proof = convert_tm_to_ics_merkle_proof(&proof_ops).map_err(Error::ics23)?; + Some(proof) + } else { + None + }; + // return an empty data for non-existence proof + Ok((value.unwrap_or_default(), proof)) + } + + pub fn query_prefix(&self, prefix: Key) -> Result, Error> { + let response = self + .rt + .block_on( + // We can't use rpc::query_storage_prefix` because we need byte data + RPC.shell() + .storage_prefix(self.ctx.client(), None, None, false, &prefix), + ) + .map_err(NamadaError::query)?; + Ok(response.data) + } + + pub fn query_epoch(&self) -> Result { + self.rt + .block_on(rpc::query_epoch(self.ctx.client())) + .map_err(|e| Error::namada(NamadaError::namada(e))) + } + + pub fn query_update_event( + &self, + request: &QueryClientEventRequest, + ) -> Result, Error> { + let height = BlockHeight(request.consensus_height.revision_height()); + let event = self + .rt + .block_on(RPC.shell().ibc_client_update( + self.ctx.client(), + &request.client_id.as_str().parse().unwrap(), + &height, + )) + .map_err(NamadaError::query)?; + match event { + Some(event) => { + let h = event + .read_attribute::() + .map_err(|_| Error::invalid_height_no_source())?; + let height = ICSHeight::new(self.config.id.version(), h.0) + .map_err(|_| Error::invalid_height_no_source())?; + let pb_abci_event = tendermint_proto::v0_37::abci::Event::from(event); + let abci_event = pb_abci_event.try_into().map_err(|_| { + Error::query("Conversion from proto AbciEvent to AbciEvent failed".to_string()) + })?; + match ibc_event_try_from_abci_event(&abci_event) { + Ok(event) => Ok(Some(IbcEventWithHeight { event, height })), + // non IBC event + Err(_) => Ok(None), + } + } + None => Ok(None), + } + } + + /// Get all IBC events when the tx has been applied + pub fn query_tx_events(&self, tx_hash: &TmHash) -> Result, Error> { + match self.query_applied_event(tx_hash)? { + Some(applied) => { + let h = applied + .read_attribute::() + .map_err(|_| Error::invalid_height_no_source())?; + let height = ICSHeight::new(self.config.id.version(), h.0) + .map_err(|_| Error::invalid_height_no_source())?; + // Check if the tx is valid + let tx_result = applied + .read_attribute::>() + .expect("The batch attribute should exist"); + let events = tx_result.batch_results.0.into_iter().filter_map(|(_, r)| { + r.map(|batched_tx_result| { + // Get IBC events when the transaction was accepted + if batched_tx_result.is_accepted() { + batched_tx_result.events.into_iter().filter_map(|event| { + ibc_event_try_from_abci_event(&event.into()).ok() + }).map(|ibc_event| IbcEventWithHeight::new(ibc_event, height)).collect() + } else { + vec![IbcEventWithHeight::new( + IbcEvent::ChainError(format!( + "The transaction was invalid: BatchedTxResult {batched_tx_result}", + )), + height, + )] + } + }).ok() + }).flatten().collect(); + Ok(events) + } + None => Ok(vec![]), + } + } + + fn query_applied_event(&self, tx_hash: &TmHash) -> Result, Error> { + self.rt + .block_on(RPC.shell().applied( + self.ctx.client(), + &tx_hash.as_ref().try_into().expect("Invalid tx hash"), + )) + .map_err(|e| Error::namada(NamadaError::query(e))) + } + + /// Get IBC packet events + pub fn query_packet_events_from_block( + &self, + request: &QueryPacketEventDataRequest, + ) -> Result, Error> { + let mut block_events = vec![]; + for seq in &request.sequences { + if let Some(response_height) = self.query_packet_height(request, *seq)? { + if let QueryHeight::Specific(query_height) = request.height.get() { + if response_height > query_height { + continue; + } + } + let events = self.query_events(response_height)?; + let mut packet_events = events + .into_iter() + .filter(|e| { + let packet = match &e.event { + IbcEvent::SendPacket(send_event) => &send_event.packet, + IbcEvent::WriteAcknowledgement(write_ack_event) => { + &write_ack_event.packet + } + _ => return false, + }; + !block_events.contains(e) + && packet.source_port == request.source_port_id + && packet.source_channel == request.source_channel_id + && packet.destination_port == request.destination_port_id + && packet.destination_channel == request.destination_channel_id + && packet.sequence == *seq + }) + .collect(); + block_events.append(&mut packet_events); + } + } + Ok(block_events) + } + + /// Get the height at which the packet event has been emitted + fn query_packet_height( + &self, + request: &QueryPacketEventDataRequest, + sequence: Sequence, + ) -> Result, Error> { + match self + .rt + .block_on( + RPC.shell().ibc_packet( + self.ctx.client(), + &request + .event_id + .as_str() + .parse() + .expect("invalid event type"), + &request + .source_port_id + .as_str() + .parse() + .expect("PortId should be parsable"), + &request + .source_channel_id + .as_str() + .parse() + .expect("ChannelId should be parsable"), + &request + .destination_port_id + .as_str() + .parse() + .expect("PortId should be parsable"), + &request + .destination_channel_id + .as_str() + .parse() + .expect("ChannelId should be parsable"), + &u64::from(sequence).into(), + ), + ) + .map_err(NamadaError::query)? + { + Some(event) => { + let h = event + .read_attribute::() + .map_err(|_| Error::invalid_height_no_source())?; + let height = ICSHeight::new(self.config.id.version(), h.0) + .map_err(|_| Error::invalid_height_no_source())?; + Ok(Some(height)) + } + None => Ok(None), + } + } + + /// Get IBC events at the given height + fn query_events(&self, height: ICSHeight) -> Result, Error> { + crate::time!( + "query_blocks: query block packet events", + { + "src_chain": self.config().id.to_string(), + } + ); + crate::telemetry!(query, self.id(), "query_block"); + + let tm_height = TmHeight::try_from(height.revision_height()) + .map_err(|_| Error::invalid_height_no_source())?; + let response = self + .rt + .block_on(SdkClient::block_results(self.ctx.client(), tm_height)) + .map_err(|e| Error::rpc(self.config.rpc_addr.clone(), e))?; + + let events = response + .end_block_events + .ok_or_else(|| Error::query("No transaction result was found".to_string()))?; + let mut ibc_events = vec![]; + for event in &events { + if let Ok(ibc_event) = ibc_event_try_from_abci_event(event) { + ibc_events.push(IbcEventWithHeight::new(ibc_event, height)) + } + } + Ok(ibc_events) + } + + /// Get IBC denom + pub fn query_denom(&self, raw_addr: String) -> Result { + let token = Address::decode(&raw_addr) + .map_err(|_| NamadaError::address_decode(raw_addr.to_string()))?; + let hash = match &token { + Address::Internal(InternalAddress::IbcToken(hash)) => hash.to_string(), + _ => return Err(NamadaError::denom_not_found(raw_addr).into()), + }; + + let prefix = ibc_trace_key_prefix(None); + let pairs = self.query_prefix(prefix)?; + let pair = pairs + .iter() + .find(|PrefixValue { key, value: _ }| { + if let Some((_, token_hash)) = is_ibc_trace_key(key) { + token_hash == *hash + } else { + false + } + }) + .ok_or(NamadaError::denom_not_found(raw_addr))?; + + String::try_from_slice(&pair.value).map_err(|e| Error::namada(NamadaError::borsh_decode(e))) + } +} diff --git a/crates/relayer/src/chain/namada/tx.rs b/crates/relayer/src/chain/namada/tx.rs new file mode 100644 index 0000000000..c1be1ac799 --- /dev/null +++ b/crates/relayer/src/chain/namada/tx.rs @@ -0,0 +1,383 @@ +use core::str::FromStr; +use core::time::Duration; +use std::path::PathBuf; +use std::thread; +use std::time::Instant; + +use ibc_proto::google::protobuf::Any; +use itertools::Itertools; +use namada_ibc::{MsgAcknowledgement, MsgRecvPacket, MsgTimeout}; +use namada_sdk::address::{Address, ImplicitAddress}; +use namada_sdk::args::{self, TxBuilder}; +use namada_sdk::args::{InputAmount, Tx as TxArgs, TxCustom}; +use namada_sdk::borsh::BorshSerializeExt; +use namada_sdk::chain::ChainId; +use namada_sdk::ibc::apps::nft_transfer::types::packet::PacketData as NftPacketData; +use namada_sdk::ibc::apps::transfer::types::packet::PacketData; +use namada_sdk::ibc::core::channel::types::acknowledgement::AcknowledgementStatus; +use namada_sdk::ibc::core::channel::types::msgs::{ + MsgAcknowledgement as IbcMsgAcknowledgement, MsgRecvPacket as IbcMsgRecvPacket, + MsgTimeout as IbcMsgTimeout, ACKNOWLEDGEMENT_TYPE_URL, RECV_PACKET_TYPE_URL, TIMEOUT_TYPE_URL, +}; +use namada_sdk::ibc::core::host::types::identifiers::{ChannelId, PortId}; +use namada_sdk::masp::{PaymentAddress, TransferTarget}; +use namada_sdk::masp_primitives::transaction::Transaction as MaspTransaction; +use namada_sdk::{signing, tx, Namada}; +use namada_token::ShieldingTransfer; +use tendermint_proto::Protobuf; +use tendermint_rpc::endpoint::broadcast::tx_sync::Response; +use tracing::{debug, debug_span, trace}; + +use crate::chain::cosmos::types::tx::{TxStatus, TxSyncResult}; +use crate::chain::cosmos::wait::all_tx_results_found; +use crate::chain::endpoint::ChainEndpoint; +use crate::error::Error; + +use super::error::Error as NamadaError; +use super::NamadaChain; + +const WAIT_BACKOFF: Duration = Duration::from_millis(300); + +impl NamadaChain { + pub fn batch_txs(&mut self, msgs: &[Any]) -> Result { + if msgs.is_empty() { + return Err(Error::send_tx("No message to be batched".to_string())); + } + + let tx_args = self.make_tx_args()?; + + let relayer_addr = self.get_key()?.address; + let rt = self.rt.clone(); + rt.block_on(self.submit_reveal_aux(&tx_args, &relayer_addr))?; + + let args = TxCustom { + tx: tx_args.clone(), + code_path: Some(PathBuf::from(tx::TX_IBC_WASM)), + data_path: None, + serialized_tx: None, + owner: relayer_addr.clone(), + }; + + let mut txs = Vec::new(); + for msg in msgs { + let (mut tx, signing_data) = rt + .block_on(args.build(&self.ctx)) + .map_err(NamadaError::namada)?; + self.set_tx_data(&mut tx, msg)?; + txs.push((tx, signing_data)); + } + let (mut tx, signing_data) = tx::build_batch(txs).map_err(NamadaError::namada)?; + rt.block_on(self.ctx.sign( + &mut tx, + &args.tx, + signing_data.first().unwrap().clone(), + signing::default_sign, + (), + )) + .map_err(NamadaError::namada)?; + let tx_header_hash = tx.header_hash().to_string(); + let response = rt + .block_on(self.ctx.submit(tx, &args.tx)) + .map_err(NamadaError::namada)?; + + match response { + tx::ProcessTxResponse::Broadcast(mut response) => { + // overwrite the tx decrypted hash for the tx query + response.hash = tx_header_hash.parse().expect("invalid hash"); + Ok(response) + } + _ => unreachable!("The response type was unexpected"), + } + } + + fn make_tx_args(&mut self) -> Result { + let chain_id = ChainId::from_str(self.config.id.as_str()).expect("invalid chain ID"); + + let namada_key = self.get_key()?; + let relayer_public_key = namada_key.secret_key.to_public(); + + let tx_args = self.ctx.tx_builder(); + let tx_args = tx_args.chain_id(chain_id); + let tx_args = tx_args.signing_keys(vec![relayer_public_key]); + // Confirm the transaction later + let mut tx_args = tx_args.broadcast_only(true); + + let memo = if !self.config().memo_prefix.as_str().is_empty() { + Some( + self.config() + .memo_prefix + .as_str() + .to_string() + .as_bytes() + .to_vec(), + ) + } else { + None + }; + tx_args.memo = memo; + + Ok(tx_args) + } + + fn set_tx_data(&self, tx: &mut tx::Tx, proto_msg: &Any) -> Result<(), Error> { + // Make a new message with Namada shielded transfer + // if receiving or refunding to a shielded address + let data = match proto_msg.type_url.as_ref() { + RECV_PACKET_TYPE_URL => { + let message: IbcMsgRecvPacket = + Protobuf::decode_vec(&proto_msg.value).map_err(Error::decode)?; + self.get_shielded_transfer( + &message.packet.port_id_on_b, + &message.packet.chan_id_on_b, + &message.packet.data, + false, + )? + .map(|(transfer, masp_tx)| { + ( + MsgRecvPacket { + message, + transfer: Some(transfer), + } + .serialize_to_vec(), + masp_tx, + ) + }) + } + ACKNOWLEDGEMENT_TYPE_URL => { + let message: IbcMsgAcknowledgement = + Protobuf::decode_vec(&proto_msg.value).map_err(Error::decode)?; + let acknowledgement: AcknowledgementStatus = + serde_json::from_slice(message.acknowledgement.as_ref()).map_err(|e| { + Error::send_tx(format!("Decoding acknowledment failed: {e}")) + })?; + if acknowledgement.is_successful() { + None + } else { + // Need to refund + self.get_shielded_transfer( + &message.packet.port_id_on_b, + &message.packet.chan_id_on_a, + &message.packet.data, + true, + )? + .map(|(transfer, masp_tx)| { + ( + MsgAcknowledgement { + message, + transfer: Some(transfer), + } + .serialize_to_vec(), + masp_tx, + ) + }) + } + } + TIMEOUT_TYPE_URL => { + let message: IbcMsgTimeout = + Protobuf::decode_vec(&proto_msg.value).map_err(Error::decode)?; + self.get_shielded_transfer( + &message.packet.port_id_on_b, + &message.packet.chan_id_on_a, + &message.packet.data, + true, + )? + .map(|(transfer, masp_tx)| { + ( + MsgTimeout { + message, + transfer: Some(transfer), + } + .serialize_to_vec(), + masp_tx, + ) + }) + } + _ => None, + }; + + if let Some((tx_data, masp_tx)) = data { + tx.add_serialized_data(tx_data); + tx.add_masp_tx_section(masp_tx); + } else { + let mut tx_data = vec![]; + prost::Message::encode(proto_msg, &mut tx_data).map_err(|e| { + Error::protobuf_encode(String::from("Encoding the message failed"), e) + })?; + tx.add_serialized_data(tx_data); + } + Ok(()) + } + + fn get_shielded_transfer( + &self, + port_id: &PortId, + channel_id: &ChannelId, + packet_data: &[u8], + is_refund: bool, + ) -> Result, Error> { + let transfer = serde_json::from_slice::(packet_data) + .ok() + .and_then(|data| { + let target = if is_refund { + data.sender.as_ref() + } else { + data.receiver.as_ref() + }; + PaymentAddress::from_str(target) + .map(|payment_addr| { + ( + payment_addr, + data.token.denom.to_string(), + data.token.amount.to_string(), + ) + }) + .ok() + }) + .or(serde_json::from_slice::(packet_data) + .ok() + .and_then(|data| { + let target = if is_refund { + data.sender.as_ref() + } else { + data.receiver.as_ref() + }; + PaymentAddress::from_str(target) + .map(|payment_addr| { + let ibc_token = format!( + "{}/{}", + data.class_id, + data.token_ids + .0 + .first() + .expect("at least 1 token ID should exist") + ); + (payment_addr, ibc_token, "1".to_string()) + }) + .ok() + })); + + if let Some((receiver, token, amount)) = transfer { + self.rt.block_on(self.shielded_sync())?; + let amount = InputAmount::Unvalidated( + amount + .parse() + .map_err(|e| Error::send_tx(format!("invalid amount: {e}")))?, + ); + let args = args::GenIbcShieldedTransfer { + query: args::Query { + ledger_address: self.config().rpc_addr.clone(), + }, + output_folder: None, + target: TransferTarget::PaymentAddress(receiver), + token: token.clone(), + amount, + port_id: port_id.clone(), + channel_id: channel_id.clone(), + refund: is_refund, + }; + Ok(self + .rt + .block_on(tx::gen_ibc_shielding_transfer(&self.ctx, args)) + .map_err(NamadaError::namada)?) + } else { + Ok(None) + } + } + + pub fn wait_for_block_commits( + &self, + tx_sync_results: &mut [TxSyncResult], + ) -> Result<(), Error> { + if all_tx_results_found(tx_sync_results) { + return Ok(()); + } + + let chain_id = &self.config().id; + crate::time!( + "wait_for_block_commits", + { + "src_chain": chain_id, + } + ); + let _span = debug_span!("wait_for_block_commits", id = %chain_id).entered(); + + let start_time = Instant::now(); + + let hashes = tx_sync_results + .iter() + .map(|res| res.response.hash.to_string()) + .join(", "); + + debug!("waiting for commit of tx hashes(s) {}", hashes); + + loop { + let elapsed = start_time.elapsed(); + + if all_tx_results_found(tx_sync_results) { + trace!( + "retrieved {} tx results after {} ms", + tx_sync_results.len(), + elapsed.as_millis(), + ); + + return Ok(()); + } else if elapsed > self.config().rpc_timeout { + debug!("timed out after {} ms", elapsed.as_millis()); + return Err(Error::tx_no_confirmation()); + } else { + thread::sleep(WAIT_BACKOFF); + + for tx_sync_result in tx_sync_results.iter_mut() { + if let Err(e) = self.update_tx_sync_result(tx_sync_result) { + debug!("update_tx_sync_result failed. It will be retried: {e}"); + } + } + } + } + } + + fn update_tx_sync_result(&self, tx_sync_result: &mut TxSyncResult) -> Result<(), Error> { + if let TxStatus::Pending { .. } = tx_sync_result.status { + // If the transaction failed, query_txs returns the IbcEvent::ChainError, + // so that we don't attempt to resolve the transaction later on. + let events = self.query_tx_events(&tx_sync_result.response.hash)?; + // If we get events back, progress was made, so we replace the events + // with the new ones. in both cases we will check in the next iteration + // whether or not the transaction was fully committed. + if !events.is_empty() { + tx_sync_result.events = events; + tx_sync_result.status = TxStatus::ReceivedResponse; + } + } + Ok(()) + } + + async fn submit_reveal_aux(&mut self, args: &TxArgs, address: &Address) -> Result<(), Error> { + if let Address::Implicit(ImplicitAddress(pkh)) = address { + let public_key = self + .ctx + .wallet() + .await + .find_public_key(pkh.to_string()) + .map_err(|e| NamadaError::namada(namada_sdk::error::Error::Other(e.to_string())))?; + + if tx::is_reveal_pk_needed(self.ctx.client(), address) + .await + .map_err(NamadaError::namada)? + { + let (mut tx, signing_data) = tx::build_reveal_pk(&self.ctx, args, &public_key) + .await + .map_err(NamadaError::namada)?; + self.ctx + .sign(&mut tx, args, signing_data, signing::default_sign, ()) + .await + .map_err(NamadaError::namada)?; + self.ctx + .submit(tx, args) + .await + .map_err(NamadaError::namada)?; + } + } + Ok(()) + } +} diff --git a/crates/relayer/src/chain/namada/wallet.rs b/crates/relayer/src/chain/namada/wallet.rs new file mode 100644 index 0000000000..00f59b4e45 --- /dev/null +++ b/crates/relayer/src/chain/namada/wallet.rs @@ -0,0 +1,65 @@ +use std::path::PathBuf; +use std::{env, fs}; + +use namada_sdk::wallet::fs::FsWalletStorage; +use namada_sdk::wallet::{LoadStoreError, Store, Wallet, WalletIo, WalletStorage}; +use namada_sdk::zeroize::Zeroizing; +use signature::rand_core::OsRng; + +/// Wallet utils for Namada context +#[derive(Clone)] +pub(super) struct NullWalletUtils; + +impl WalletIo for NullWalletUtils { + type Rng = OsRng; +} + +// Namada wallet never accesses the storage. It reads the keys added in the bootstrap from the store. +impl WalletStorage for NullWalletUtils { + fn save(&self, _wallet: &Wallet) -> Result<(), LoadStoreError> { + Ok(()) + } + + fn load(&self, _wallet: &mut Wallet) -> Result<(), LoadStoreError> { + Ok(()) + } +} + +/// For Namada wallet for adding a key with a password +#[derive(Clone)] +pub struct CliWalletUtils { + store_dir: PathBuf, +} + +impl CliWalletUtils { + pub fn new(store_dir: PathBuf) -> Wallet { + Wallet::new(Self { store_dir }, Store::default()) + } +} + +impl FsWalletStorage for CliWalletUtils { + fn store_dir(&self) -> &PathBuf { + &self.store_dir + } +} + +impl WalletIo for CliWalletUtils { + type Rng = OsRng; + + fn read_password(_confirm: bool) -> Zeroizing { + match env::var("NAMADA_WALLET_PASSWORD_FILE") { + Ok(path) => Zeroizing::new( + fs::read_to_string(path).expect("Something went wrong reading the file"), + ), + Err(_) => match env::var("NAMADA_WALLET_PASSWORD") { + Ok(password) => Zeroizing::new(password), + Err(_) => { + let prompt = "Enter your decryption password: "; + rpassword::read_password_from_tty(Some(prompt)) + .map(Zeroizing::new) + .expect("Failed reading password from tty.") + } + }, + } + } +} diff --git a/crates/relayer/src/config.rs b/crates/relayer/src/config.rs index 973a0d400a..ee23cf6e1a 100644 --- a/crates/relayer/src/config.rs +++ b/crates/relayer/src/config.rs @@ -314,7 +314,7 @@ impl Config { } match chain_config { - ChainConfig::CosmosSdk(cosmos_config) => { + ChainConfig::CosmosSdk(cosmos_config) | ChainConfig::Namada(cosmos_config) => { cosmos_config .validate() .map_err(Into::>::into)?; @@ -644,36 +644,43 @@ pub enum EventSourceMode { #[serde(tag = "type")] pub enum ChainConfig { CosmosSdk(CosmosSdkConfig), + // Reuse CosmosSdkConfig for tendermint light clients + Namada(CosmosSdkConfig), } impl ChainConfig { pub fn id(&self) -> &ChainId { match self { Self::CosmosSdk(config) => &config.id, + Self::Namada(config) => &config.id, } } pub fn packet_filter(&self) -> &PacketFilter { match self { Self::CosmosSdk(config) => &config.packet_filter, + Self::Namada(config) => &config.packet_filter, } } pub fn max_block_time(&self) -> Duration { match self { Self::CosmosSdk(config) => config.max_block_time, + Self::Namada(config) => config.max_block_time, } } pub fn key_name(&self) -> &String { match self { Self::CosmosSdk(config) => &config.key_name, + Self::Namada(config) => &config.key_name, } } pub fn set_key_name(&mut self, key_name: String) { match self { Self::CosmosSdk(config) => config.key_name = key_name, + Self::Namada(config) => config.key_name = key_name, } } @@ -692,6 +699,15 @@ impl ChainConfig { .map(|(key_name, keys)| (key_name, keys.into())) .collect() } + ChainConfig::Namada(config) => { + let keyring = + KeyRing::new_namada(Store::Test, &config.id, &config.key_store_folder)?; + keyring + .keys()? + .into_iter() + .map(|(key_name, keys)| (key_name, keys.into())) + .collect() + } }; Ok(keys) @@ -699,25 +715,27 @@ impl ChainConfig { pub fn clear_interval(&self) -> Option { match self { - Self::CosmosSdk(config) => config.clear_interval, + Self::CosmosSdk(config) | Self::Namada(config) => config.clear_interval, } } pub fn query_packets_chunk_size(&self) -> usize { match self { - Self::CosmosSdk(config) => config.query_packets_chunk_size, + Self::CosmosSdk(config) | Self::Namada(config) => config.query_packets_chunk_size, } } pub fn set_query_packets_chunk_size(&mut self, query_packets_chunk_size: usize) { match self { - Self::CosmosSdk(config) => config.query_packets_chunk_size = query_packets_chunk_size, + Self::CosmosSdk(config) | Self::Namada(config) => { + config.query_packets_chunk_size = query_packets_chunk_size + } } } pub fn excluded_sequences(&self, channel_id: &ChannelId) -> Cow<'_, [Sequence]> { match self { - Self::CosmosSdk(config) => config + Self::CosmosSdk(config) | Self::Namada(config) => config .excluded_sequences .get(channel_id) .map(|seqs| Cow::Borrowed(seqs.as_slice())) @@ -750,7 +768,9 @@ impl<'de> Deserialize<'de> for ChainConfig { "CosmosSdk" => CosmosSdkConfig::deserialize(value) .map(Self::CosmosSdk) .map_err(|e| serde::de::Error::custom(format!("invalid CosmosSdk config: {e}"))), - + "Namada" => CosmosSdkConfig::deserialize(value) + .map(Self::Namada) + .map_err(|e| serde::de::Error::custom(format!("invalid Namada config: {e}"))), // // <-- Add new chain types here --> // @@ -909,6 +929,9 @@ mod tests { super::ChainConfig::CosmosSdk(_) => { // all good } + super::ChainConfig::Namada(_) => { + panic!("Default chain is expected to be CosmosSDK not Namada") + } } } diff --git a/crates/relayer/src/error.rs b/crates/relayer/src/error.rs index 537470552c..3048945956 100644 --- a/crates/relayer/src/error.rs +++ b/crates/relayer/src/error.rs @@ -35,6 +35,7 @@ use ibc_relayer_types::proofs::ProofError; use crate::chain::cosmos::version; use crate::chain::cosmos::BLOCK_MAX_BYTES_MAX_FRACTION; +use crate::chain::namada::error::Error as NamadaError; use crate::config::Error as ConfigError; use crate::event::source; use crate::keyring::{errors::Error as KeyringError, KeyType}; @@ -630,6 +631,10 @@ define_error! { InvalidChannelString { channel: String } |e| { format!("invalid channel string {}", e.channel) }, + + Namada + [ NamadaError ] + |_| { "Namada error" }, } } diff --git a/crates/relayer/src/event.rs b/crates/relayer/src/event.rs index f5219f4750..0b59747dba 100644 --- a/crates/relayer/src/event.rs +++ b/crates/relayer/src/event.rs @@ -39,7 +39,7 @@ pub mod bus; pub mod error; pub mod source; -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Serialize, PartialEq)] pub struct IbcEventWithHeight { pub event: IbcEvent, pub height: Height, diff --git a/crates/relayer/src/event/source/websocket/extract.rs b/crates/relayer/src/event/source/websocket/extract.rs index ddc692054d..e0c8886179 100644 --- a/crates/relayer/src/event/source/websocket/extract.rs +++ b/crates/relayer/src/event/source/websocket/extract.rs @@ -330,6 +330,11 @@ fn extract_block_events( extract_events(height, block_events, "send_packet", "packet_data_hex"), height, ); + append_events::( + &mut events, + extract_events(height, block_events, "write_acknowledgement", "packet_ack"), + height, + ); append_events::( &mut events, extract_events(height, block_events, "channel_close_init", "channel_id"), diff --git a/crates/relayer/src/foreign_client.rs b/crates/relayer/src/foreign_client.rs index 2a3cf41d01..afba29772a 100644 --- a/crates/relayer/src/foreign_client.rs +++ b/crates/relayer/src/foreign_client.rs @@ -905,7 +905,9 @@ impl ForeignClient config.client_refresh_rate, + ChainConfig::CosmosSdk(config) | ChainConfig::Namada(config) => { + config.client_refresh_rate + } }; let refresh_period = client_state @@ -1750,7 +1752,9 @@ impl ForeignClient config.ccv_consumer_chain, + ChainConfig::CosmosSdk(config) | ChainConfig::Namada(config) => { + config.ccv_consumer_chain + } }; let mut msgs = vec![]; diff --git a/crates/relayer/src/keyring.rs b/crates/relayer/src/keyring.rs index 1260de235e..446ba7b039 100644 --- a/crates/relayer/src/keyring.rs +++ b/crates/relayer/src/keyring.rs @@ -5,6 +5,8 @@ pub use key_type::KeyType; pub use secp256k1_key_pair::Secp256k1KeyPair; pub use signing_key_pair::{SigningKeyPair, SigningKeyPairSized}; +pub use crate::chain::namada::key::NamadaKeyPair; + mod any_signing_key_pair; mod ed25519_key_pair; mod key_type; @@ -286,7 +288,15 @@ impl KeyRing { } } -// Why is this not a method on `ChainConfig`? +impl KeyRing { + pub fn new_namada( + store: Store, + chain_id: &ChainId, + ks_folder: &Option, + ) -> Result { + Self::new(store, "", chain_id, ks_folder) + } +} fn disk_store_path(folder_name: &str, keystore_folder: &Option) -> Result { let ks_folder = match keystore_folder { diff --git a/crates/relayer/src/keyring/any_signing_key_pair.rs b/crates/relayer/src/keyring/any_signing_key_pair.rs index f6aa27bd0b..3bd57177a2 100644 --- a/crates/relayer/src/keyring/any_signing_key_pair.rs +++ b/crates/relayer/src/keyring/any_signing_key_pair.rs @@ -1,12 +1,13 @@ use serde::Serialize; -use super::{Ed25519KeyPair, KeyType, Secp256k1KeyPair, SigningKeyPair}; +use super::{Ed25519KeyPair, KeyType, NamadaKeyPair, Secp256k1KeyPair, SigningKeyPair}; #[derive(Clone, Debug, Serialize)] #[serde(untagged)] pub enum AnySigningKeyPair { Secp256k1(Secp256k1KeyPair), Ed25519(Ed25519KeyPair), + Namada(NamadaKeyPair), } impl AnySigningKeyPair { @@ -14,6 +15,7 @@ impl AnySigningKeyPair { match self { Self::Secp256k1(key_pair) => key_pair.account(), Self::Ed25519(key_pair) => key_pair.account(), + Self::Namada(key_pair) => key_pair.account(), } } @@ -21,6 +23,7 @@ impl AnySigningKeyPair { match self { Self::Secp256k1(_) => Secp256k1KeyPair::KEY_TYPE, Self::Ed25519(_) => Ed25519KeyPair::KEY_TYPE, + Self::Namada(_) => NamadaKeyPair::KEY_TYPE, } } @@ -28,6 +31,7 @@ impl AnySigningKeyPair { match self { Self::Secp256k1(key_pair) => key_pair.as_any(), Self::Ed25519(key_pair) => key_pair.as_any(), + Self::Namada(key_pair) => key_pair.as_any(), } .downcast_ref::() .cloned() @@ -45,3 +49,9 @@ impl From for AnySigningKeyPair { Self::Ed25519(key_pair) } } + +impl From for AnySigningKeyPair { + fn from(key_pair: NamadaKeyPair) -> Self { + Self::Namada(key_pair) + } +} diff --git a/crates/relayer/src/light_client/tendermint.rs b/crates/relayer/src/light_client/tendermint.rs index bb48d8dbc4..9fbc13224e 100644 --- a/crates/relayer/src/light_client/tendermint.rs +++ b/crates/relayer/src/light_client/tendermint.rs @@ -141,12 +141,12 @@ impl super::LightClient for LightClient { )) })?; - let update_header: &TmHeader = match any_header { - AnyHeader::Tendermint(header) => Ok(header), + let update_header = match any_header { + AnyHeader::Tendermint(header) => Ok::<_, Error>(header), }?; let client_state = match client_state { - AnyClientState::Tendermint(client_state) => Ok(client_state), + AnyClientState::Tendermint(client_state) => Ok::<_, Error>(client_state), }?; let next_validators = self @@ -307,7 +307,7 @@ impl LightClient { let scheduler = components::scheduler::basic_bisecting_schedule; let client_state = match client_state { - AnyClientState::Tendermint(client_state) => Ok(client_state), + AnyClientState::Tendermint(client_state) => Ok::<_, Error>(client_state), }?; Ok(TmLightClient::new( diff --git a/crates/relayer/src/spawn.rs b/crates/relayer/src/spawn.rs index 113ac1f6a7..f791fddabc 100644 --- a/crates/relayer/src/spawn.rs +++ b/crates/relayer/src/spawn.rs @@ -6,7 +6,9 @@ use tokio::runtime::Runtime as TokioRuntime; use ibc_relayer_types::core::ics24_host::identifier::ChainId; use crate::{ - chain::{cosmos::CosmosSdkChain, handle::ChainHandle, runtime::ChainRuntime}, + chain::{ + cosmos::CosmosSdkChain, handle::ChainHandle, namada::NamadaChain, runtime::ChainRuntime, + }, config::{ChainConfig, Config}, error::Error as RelayerError, }; @@ -82,6 +84,7 @@ pub fn spawn_chain_runtime_with_config( ) -> Result { let handle = match config { ChainConfig::CosmosSdk(_) => ChainRuntime::::spawn(config, rt), + ChainConfig::Namada(_) => ChainRuntime::::spawn(config, rt), } .map_err(SpawnError::relayer)?; diff --git a/e2e/namada-gaia-simple-transfers b/e2e/namada-gaia-simple-transfers new file mode 100755 index 0000000000..65ec968279 --- /dev/null +++ b/e2e/namada-gaia-simple-transfers @@ -0,0 +1,356 @@ +#!/bin/bash + +# This script sets up Namada and Gaia locally +# `make build` and `make build-wasm-scripts` on Namada directory in advance +# Run with `namada-gaia-simple-transfers ${namada_dir}` + +set -e + +NAMADA_DIR=$1 +if [ -z "${NAMADA_DIR}" ] +then + echo "ERROR: Namada directory should be given" + exit 1 +fi +cd $(dirname $0) +HERMES_DIR=${PWD%/e2e*} + +# edit for your environment +NAMADAC="${NAMADA_DIR}/target/debug/namadac" +NAMADAN="${NAMADA_DIR}/target/debug/namadan" +NAMADAW="${NAMADA_DIR}/target/debug/namadaw" +DATA_DIR="${HERMES_DIR}/data" +IBC_TOKEN="transfer/channel-0/samoleans" + +SHIELDED_ALIAS_A="shielded_a" +SHIELDED_ALIAS_B="shielded_b" +PAYMENT_ALIAS_A="payment_a" +PAYMENT_ALIAS_B="payment_b" +NAMADA_LEDGER_ADDR="http://127.0.0.1:27657" + +GAIA_CHAIN_CONFIG=" +[[chains]] +id = 'gaia-0' +type = 'CosmosSdk' +rpc_addr = 'http://127.0.0.1:26657' +grpc_addr = 'http://127.0.0.1:9090' +event_source = { mode = 'push', url = 'ws://127.0.0.1:26657/websocket', batch_delay = '500ms' } +account_prefix = 'cosmos' +key_name = 'testkey' +store_prefix = 'ibc' +gas_price = { price = 0.001, denom = 'stake' } +" + +#### main #### +mkdir -p ${DATA_DIR} + +# Gaia +rm -rf ${DATA_DIR}/gaia-0 + +${HERMES_DIR}/scripts/one-chain gaiad gaia-0 ${DATA_DIR} \ + 26657 26656 6060 9090 10000 + +# Namada +${HERMES_DIR}/scripts/setup-namada-single-node ${NAMADA_DIR} +base_dir=${DATA_DIR}/namada + +cd ${HERMES_DIR} +chain_id=$(grep id config_for_namada.toml | sed -e s/\'//g | awk '{print $3}') + +# Add Gaia chain config +echo "${GAIA_CHAIN_CONFIG}" >> config_for_namada.toml + +# add Gaia key +cargo run -q --bin hermes -- --config config_for_namada.toml \ + keys add --chain gaia-0 --key-file ${DATA_DIR}/gaia-0/user_seed.json --overwrite + +# setup Namada shielded keys +${NAMADAW} --base-dir ${base_dir} gen --shielded --alias ${SHIELDED_ALIAS_A} --unsafe-dont-encrypt +${NAMADAW} --base-dir ${base_dir} gen-payment-addr --alias ${PAYMENT_ALIAS_A} --key ${SHIELDED_ALIAS_A} +payment_addr_a=$(${NAMADAW} --base-dir ${base_dir} find --alias ${PAYMENT_ALIAS_A} | awk -v paymentAlias="${PAYMENT_ALIAS_A}" '{if($1 ~ paymentAlias) {print $2}}') + +${NAMADAW} --base-dir ${base_dir} gen --shielded --alias ${SHIELDED_ALIAS_B} --unsafe-dont-encrypt +${NAMADAW} --base-dir ${base_dir} gen-payment-addr --alias ${PAYMENT_ALIAS_B} --key ${SHIELDED_ALIAS_B} +payment_addr_b=$(${NAMADAW} --base-dir ${base_dir} find --alias ${PAYMENT_ALIAS_B} | awk -v paymentAlias="${PAYMENT_ALIAS_B}" '{if($1 ~ paymentAlias) {print $2}}') + +# Initialize Relayer's balance on Namada +${NAMADAC} --base-dir ${base_dir} \ + transparent-transfer \ + --source albert \ + --target relayer \ + --token nam \ + --amount 10000 \ + --node ${NAMADA_LEDGER_ADDR} + +${NAMADAC} --base-dir ${base_dir} \ + transparent-transfer \ + --source albert \ + --target relayer \ + --token apfel \ + --amount 1000 \ + --node ${NAMADA_LEDGER_ADDR} + +# create a channel +cargo run --bin hermes -- --config config_for_namada.toml \ + create channel --a-chain ${chain_id} \ + --b-chain gaia-0 \ + --a-port transfer \ + --b-port transfer \ + --new-client-connection --yes + +echo "~~ Transfer 100 samoleans from Gaia to Namada ~~" +namada_receiver=$(${NAMADAW} --base-dir ${base_dir} find --alias relayer | awk '/"relayer":/{print $3}') +cargo run --bin hermes -- --config config_for_namada.toml \ + tx ft-transfer \ + --dst-chain ${chain_id} \ + --src-chain gaia-0 \ + --src-port transfer \ + --src-channel channel-0 \ + --amount 100 \ + --receiver ${namada_receiver} \ + --denom samoleans \ + --timeout-height-offset 1000 + +# packet-recv +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-recv \ + --dst-chain ${chain_id} \ + --src-chain gaia-0 \ + --src-port transfer \ + --src-channel channel-0 + +# packet-ack +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-ack \ + --dst-chain gaia-0 \ + --src-chain ${chain_id} \ + --src-port transfer \ + --src-channel channel-0 + +echo "==== Balances on Namada ====" +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner relayer \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [ "${balance}" != "${IBC_TOKEN}: 100" ]; then + echo "The balance on Namada is wrong" + exit 1 +fi + +echo "==== Balances on Gaia ====" +gaia_user=$(gaiad --home ${DATA_DIR}/gaia-0 \ + keys --keyring-backend="test" show user -a) +balance=$(gaiad query bank balances ${gaia_user}) +echo "${balance}" +balance=$(echo "${balance}" | grep samoleans -B 1 | tr -d '\n') +if [ "${balance}" != "- amount: \"9900\" denom: samoleans" ]; then + echo "The balance on Gaia is wrong" + exit 1 +fi + +echo "~~ Transfer back 50 samoleans from Namada to Gaia ~~" +${NAMADAC} --base-dir ${base_dir} ibc-transfer \ + --source relayer \ + --receiver ${gaia_user} \ + --token ${IBC_TOKEN} \ + --amount 50 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${NAMADA_LEDGER_ADDR} + +# packet-recv +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-recv \ + --dst-chain gaia-0 \ + --src-chain ${chain_id} \ + --src-port transfer \ + --src-channel channel-0 + +# packet-ack +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-ack \ + --dst-chain ${chain_id} \ + --src-chain gaia-0 \ + --src-port transfer \ + --src-channel channel-0 + +echo "==== Balances on Namada ====" +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner relayer \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [ "${balance}" != "${IBC_TOKEN}: 50" ]; then + echo "The balance on Namada is wrong" + exit 1 +fi + +echo "==== Balances on Gaia ====" +balance=$(gaiad query bank balances ${gaia_user}) +echo "${balance}" +balance=$(echo "${balance}" | grep samoleans -B 1 | tr -d '\n') +if [ "${balance}" != "- amount: \"9950\" denom: samoleans" ]; then + echo "The balance on Gaia is wrong" + exit 1 +fi + +echo "==== Start Hermes ====" +cargo run --bin hermes -- --config config_for_namada.toml \ + start > ${HERMES_DIR}/e2e/hermes.log 2>&1 & + +echo "~~ Transfer 200 apfel from Namada to Gaia ~~" +${NAMADAC} --base-dir ${base_dir} ibc-transfer \ + --source relayer \ + --receiver ${gaia_user} \ + --token apfel \ + --amount 200 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${NAMADA_LEDGER_ADDR} + +# wait for relaying +sleep 15 + +echo "==== Balances on Namada ====" +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token apfel \ + --owner relayer \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [ "${balance}" != "apfel: 800" ]; then + echo "The balance on Namada is wrong" + exit 1 +fi + +echo "==== Balances on Gaia ====" +balance=$(gaiad query bank balances ${gaia_user}) +echo "${balance}" +balance=$(echo "${balance}" | grep ibc -B 1 | tr -d '\n') +if [[ "${balance}" != *"- amount: \"200\" denom: ibc/"* ]]; then + echo "The balance on Gaia is wrong" + exit 1 +fi + +echo "~~ Shielding transfer 10 samoleans from Gaia to Namada ~~" +cargo run --bin hermes -- --config config_for_namada.toml \ + tx ft-transfer \ + --dst-chain ${chain_id} \ + --src-chain gaia-0 \ + --src-port transfer \ + --src-channel channel-0 \ + --amount 10 \ + --receiver ${payment_addr_a} \ + --denom samoleans \ + --timeout-height-offset 1000 \ + +# wait for relaying +sleep 40 + +echo "==== Balance of shielded_a on Namada ====" +${NAMADAC} --base-dir ${base_dir} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_A} \ + --node ${NAMADA_LEDGER_ADDR} +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_A} \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 10" ]]; then + echo "The balance of shielded_a on Namada is wrong" + exit 1 +fi + +echo "==== Balances on Gaia ====" +balance=$(gaiad query bank balances ${gaia_user}) +echo "${balance}" +balance=$(echo "${balance}" | grep samoleans -B 1 | tr -d '\n') +if [ "${balance}" != "- amount: \"9940\" denom: samoleans" ]; then + echo "The balance on Gaia is wrong" + exit 1 +fi + +echo "~~ Shielded transfer 5 apfel from shielded_a to shielded_b ~~" +${NAMADAC} --base-dir ${base_dir} transfer \ + --source ${SHIELDED_ALIAS_A} \ + --target ${payment_addr_b} \ + --token ${IBC_TOKEN} \ + --amount 5 \ + --signing-keys relayer \ + --node ${NAMADA_LEDGER_ADDR} + +echo "==== Balance of shielded_a on Namada ====" +${NAMADAC} --base-dir ${base_dir} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_A} ${SHIELDED_ALIAS_B} \ + --node ${NAMADA_LEDGER_ADDR} +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_A} \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 5" ]]; then + echo "The balance of shielded_a on Namada is wrong" + exit 1 +fi + +echo "==== Balance of shielded_b on Namada ====" +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B} \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 5"* ]]; then + echo "The balance of shielded_b on Namada is wrong" + exit 1 +fi + +echo "~~ Transfer back 5 samoleans from Namada to Gaia ~~" +${NAMADAC} --base-dir ${base_dir} ibc-transfer \ + --source ${SHIELDED_ALIAS_B} \ + --receiver ${gaia_user} \ + --token ${IBC_TOKEN} \ + --amount 5 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${NAMADA_LEDGER_ADDR} + +# wait for relaying +sleep 40 + +echo "==== Balances of shielded_a on Namada ====" +${NAMADAC} --base-dir ${base_dir} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_A} ${SHIELDED_ALIAS_B} \ + --node ${NAMADA_LEDGER_ADDR} +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_A} \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 5"* ]]; then + echo "The balance of shielded_a on Namada is wrong" + exit 1 +fi + +echo "==== Balances of shielded_b on Namada ====" +balance=$(${NAMADAC} --base-dir ${base_dir} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B} \ + --node ${NAMADA_LEDGER_ADDR}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 0"* ]]; then + echo "The balance of shielded_b on Namada is wrong" + exit 1 +fi + +echo "==== Balances on Gaia ====" +balance=$(gaiad query bank balances ${gaia_user}) +echo "${balance}" +balance=$(echo "${balance}" | grep samoleans -B 1 | tr -d '\n') +if [ "${balance}" != "- amount: \"9945\" denom: samoleans" ]; then + echo "The balance on Gaia is wrong" + exit 1 +fi + +killall hermes +killall gaiad +killall namadan diff --git a/e2e/namada-simple-transfers b/e2e/namada-simple-transfers new file mode 100755 index 0000000000..abba5f10da --- /dev/null +++ b/e2e/namada-simple-transfers @@ -0,0 +1,416 @@ +#!/bin/bash + +# This script executes simple transfers between Namada instances locally +# `make build` and `make build-wasm-scripts` on Namada directory in advance +# Run with `namada-simple-transfers ${namada_dir}` + +set -ex + +NAMADA_DIR=$1 +if [ -z "${NAMADA_DIR}" ] +then + echo "ERROR: Namada directory should be given" + exit 1 +fi +cd $(dirname $0) +HERMES_DIR=${PWD%/e2e*} + +NAMADAC="${NAMADA_DIR}/target/debug/namadac" +NAMADAW="${NAMADA_DIR}/target/debug/namadaw" +DATA_DIR="${HERMES_DIR}/data" +IBC_TOKEN="transfer/channel-0/apfel" + +SHIELDED_ALIAS_A="shielded_a" +SHIELDED_ALIAS_B="shielded_b" +SHIELDED_ALIAS_B_2="shielded_b_2" +PAYMENT_ALIAS_A="payment_a" +PAYMENT_ALIAS_B="payment_b" +PAYMENT_ALIAS_B_2="payment_b_2" +LEDGER_ADDR_A="http://127.0.0.1:27657" +LEDGER_ADDR_B="http://127.0.0.1:28657" +INITIAL_BALANCE=5000 + +function init_relayer_balance() { + local suffix=$1 + local ledger_addr=$2 + + local base_dir=${DATA_DIR}/namada-${suffix} + + ${NAMADAC} --base-dir ${base_dir} \ + transparent-transfer \ + --source albert \ + --target relayer \ + --token nam \ + --amount ${INITIAL_BALANCE} \ + --node ${ledger_addr} +} + +# ==== main ==== + +# Run 2 Namada chains +${HERMES_DIR}/scripts/setup-namada ${NAMADA_DIR} + +cd ${HERMES_DIR} +ids=$(grep "id" config_for_namada.toml | awk -F"'" '/^id/ {print $2}') +chain_a=$(echo ${ids} | awk '{print $1}') +chain_b=$(echo ${ids} | awk '{print $2}') + +# Initialize the balances +init_relayer_balance "a" ${LEDGER_ADDR_A} +sleep 5 +init_relayer_balance "b" ${LEDGER_ADDR_B} + +# Create a channel +cargo run --bin hermes -- --config config_for_namada.toml \ + create channel \ + --a-chain ${chain_a} \ + --b-chain ${chain_b} \ + --a-port transfer \ + --b-port transfer \ + --new-client-connection --yes + +base_dir_a=${DATA_DIR}/namada-a +base_dir_b=${DATA_DIR}/namada-b + +# Setup shielded keys +${NAMADAW} --base-dir ${base_dir_a} gen --shielded --alias ${SHIELDED_ALIAS_A} --unsafe-dont-encrypt +${NAMADAW} --base-dir ${base_dir_a} gen-payment-addr --alias ${PAYMENT_ALIAS_A} --key ${SHIELDED_ALIAS_A} +payment_addr_a=$(${NAMADAW} --base-dir ${base_dir_a} find --alias ${PAYMENT_ALIAS_A} | awk -v paymentAlias="${PAYMENT_ALIAS_A}" '{if($1 ~ paymentAlias) {print $2}}') + +${NAMADAW} --base-dir ${base_dir_b} gen --shielded --alias ${SHIELDED_ALIAS_B} --unsafe-dont-encrypt +${NAMADAW} --base-dir ${base_dir_b} gen-payment-addr --alias ${PAYMENT_ALIAS_B} --key ${SHIELDED_ALIAS_B} +payment_addr_b=$(${NAMADAW} --base-dir ${base_dir_b} find --alias ${PAYMENT_ALIAS_B} | awk -v paymentAlias="${PAYMENT_ALIAS_B}" '{if($1 ~ paymentAlias) {print $2}}') + +${NAMADAW} --base-dir ${base_dir_b} gen --shielded --alias ${SHIELDED_ALIAS_B_2} --unsafe-dont-encrypt +${NAMADAW} --base-dir ${base_dir_b} gen-payment-addr --alias ${PAYMENT_ALIAS_B_2} --key ${SHIELDED_ALIAS_B_2} +payment_addr_b_2=$(${NAMADAW} --base-dir ${base_dir_b} find --alias ${PAYMENT_ALIAS_B_2} | awk -v paymentAlias="${PAYMENT_ALIAS_B_2}" '{if($1 ~ paymentAlias) {print $2}}') + +# Faucet apfel on chain A and chain B +${NAMADAC} --base-dir ${base_dir_a} transparent-transfer \ + --source albert \ + --target relayer \ + --token apfel \ + --amount 1000 \ + --signing-keys albert-key \ + --node ${LEDGER_ADDR_A} + +${NAMADAC} --base-dir ${base_dir_b} transparent-transfer \ + --source albert \ + --target relayer \ + --token apfel \ + --amount 1000 \ + --signing-keys albert-key \ + --node ${LEDGER_ADDR_B} + +# Faucet apfel for shielded_a +${NAMADAC} --base-dir ${base_dir_a} shield \ + --source albert \ + --target ${payment_addr_a} \ + --token apfel \ + --amount 1000 \ + --signing-keys albert-key \ + --node ${LEDGER_ADDR_A} +${NAMADAC} --base-dir ${base_dir_a} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_A} \ + --node ${LEDGER_ADDR_A} + +# Get the receiver addresses +receiver_a=$(${NAMADAW} --base-dir ${base_dir_a} find --alias relayer | awk '/"relayer":/{print $3}') +receiver_b=$(${NAMADAW} --base-dir ${base_dir_b} find --alias relayer | awk '/"relayer":/{print $3}') + +echo "~~ Transfer 100 apfel from chain A to chain B ~~" +${NAMADAC} --base-dir ${base_dir_a} ibc-transfer \ + --source relayer \ + --receiver ${receiver_b} \ + --token apfel \ + --amount 100 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${LEDGER_ADDR_A} + +# packet-recv +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-recv \ + --dst-chain ${chain_b} \ + --src-chain ${chain_a} \ + --src-port transfer \ + --src-channel channel-0 + +# packet-ack +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-ack \ + --dst-chain ${chain_a} \ + --src-chain ${chain_b} \ + --src-port transfer \ + --src-channel channel-0 + +echo "==== Balances on chain A ====" +balance=$(${NAMADAC} --base-dir ${base_dir_a} balance \ + --token apfel \ + --owner relayer \ + --node ${LEDGER_ADDR_A}) +echo ${balance} +if [ "${balance}" != "apfel: 900" ]; then + echo "The balance on chain A is wrong" + exit 1 +fi + +echo "==== Balances on chain B ====" +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner relayer \ + --node ${LEDGER_ADDR_B}) +echo ${balance} +if [ "${balance}" != "${IBC_TOKEN}: 100" ]; then + echo "The balance on chain B is wrong" + exit 1 +fi + +echo "~~ Transfer back 50 apfel from chain B to chain A ~~" +${NAMADAC} --base-dir ${base_dir_b} ibc-transfer \ + --source relayer \ + --receiver ${receiver_a} \ + --token ${IBC_TOKEN} \ + --amount 50 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${LEDGER_ADDR_B} + +# packet-recv +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-recv \ + --dst-chain ${chain_a} \ + --src-chain ${chain_b} \ + --src-port transfer \ + --src-channel channel-0 + +# packet-ack +cargo run --bin hermes -- --config config_for_namada.toml \ + tx packet-ack \ + --dst-chain ${chain_b} \ + --src-chain ${chain_a} \ + --src-port transfer \ + --src-channel channel-0 + +echo "==== Balances on chain A ====" +balance=$(${NAMADAC} --base-dir ${base_dir_a} balance \ + --token apfel \ + --owner relayer \ + --node ${LEDGER_ADDR_A}) +echo ${balance} +if [ "${balance}" != "apfel: 950" ]; then + echo "The balance on chain A is wrong" + exit 1 +fi + +echo "==== Balances on chain B ====" +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner relayer \ + --node ${LEDGER_ADDR_B}) +echo ${balance} +if [ "${balance}" != "${IBC_TOKEN}: 50" ]; then + echo "The balance on chain B is wrong" + exit 1 +fi + +echo "==== Start Hermes ====" +cargo run --bin hermes -- --config config_for_namada.toml \ + start > ${HERMES_DIR}/e2e/hermes.log 2>&1 & + +echo "~~ Transfer 200 apfel from chain A to chain B ~~" +${NAMADAC} --base-dir ${base_dir_a} ibc-transfer \ + --source relayer \ + --receiver ${receiver_b} \ + --token apfel \ + --amount 200 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${LEDGER_ADDR_A} + +echo "~~ Transfer 300 apfel from chain B to chain A ~~" +${NAMADAC} --base-dir ${base_dir_b} ibc-transfer \ + --source relayer \ + --receiver ${receiver_a} \ + --token apfel \ + --amount 300 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${LEDGER_ADDR_B} + +# wait for relaying +sleep 15 + +echo "==== Balances on chain A ====" +balance=$(${NAMADAC} --base-dir ${base_dir_a} balance \ + --token apfel \ + --owner relayer \ + --node ${LEDGER_ADDR_A}) +echo ${balance} +if [ "${balance}" != "apfel: 750" ]; then + echo "The balance on chain A is wrong" + exit 1 +fi + +balance=$(${NAMADAC} --base-dir ${base_dir_a} balance \ + --token ${IBC_TOKEN} \ + --owner relayer \ + --node ${LEDGER_ADDR_A}) +echo ${balance} +if [ "${balance}" != "${IBC_TOKEN}: 300" ]; then + echo "The balance on chain A is wrong" + exit 1 +fi + +echo "==== Balances on chain B ====" +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token apfel \ + --owner relayer \ + --node ${LEDGER_ADDR_B}) +echo ${balance} +if [ "${balance}" != "apfel: 700" ]; then + echo "The balance on chain B is wrong" + exit 1 +fi + +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner relayer \ + --node ${LEDGER_ADDR_B}) +echo ${balance} +if [ "${balance}" != "${IBC_TOKEN}: 250" ]; then + echo "The balance on chain B is wrong" + exit 1 +fi + +echo "==== Shielded transfer tests ====" + +echo "~~ Shielded transfer 100 apfel from chain A to chain B ~~" +${NAMADAC} --base-dir ${base_dir_a} ibc-transfer \ + --source ${SHIELDED_ALIAS_A} \ + --receiver ${payment_addr_b} \ + --token apfel \ + --amount 100 \ + --channel-id channel-0 \ + --gas-payer relayer \ + --node ${LEDGER_ADDR_A} + +# wait for relaying +sleep 40 + +echo "==== Balance of shielded_a on chain A ====" +${NAMADAC} --base-dir ${base_dir_a} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_A} \ + --node ${LEDGER_ADDR_A} +balance=$(${NAMADAC} --base-dir ${base_dir_a} balance \ + --token apfel \ + --owner ${SHIELDED_ALIAS_A} \ + --node ${LEDGER_ADDR_A}) +echo "${balance}" +if [[ "${balance}" != *"apfel: 900" ]]; then + echo "The balance of shielded_a on chain A is wrong" + exit 1 +fi + +echo "==== Balance of shielded_b on chain B ====" +${NAMADAC} --base-dir ${base_dir_b} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_B} \ + --node ${LEDGER_ADDR_B} +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B} \ + --node ${LEDGER_ADDR_B}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 100" ]]; then + echo "The balance of shielded_b on chain B is wrong" + exit 1 +fi + +echo "~~ Shielded transfer 50 apfel from shielded_b to shielded_b_2 ~~" +${NAMADAC} --base-dir ${base_dir_b} transfer \ + --source ${SHIELDED_ALIAS_B} \ + --target ${payment_addr_b_2} \ + --token ${IBC_TOKEN} \ + --amount 50 \ + --signing-keys relayer \ + --node ${LEDGER_ADDR_B} + +echo "==== Balance of shielded_b on chain B ====" +${NAMADAC} --base-dir ${base_dir_b} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_B} \ + --node ${LEDGER_ADDR_B} +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B} \ + --node ${LEDGER_ADDR_B}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 50" ]]; then + echo "The balance of shielded_b on chain B is wrong" + exit 1 +fi + +echo "==== Balance of shielded_b_2 on chain B ====" +${NAMADAC} --base-dir ${base_dir_b} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_B_2} \ + --node ${LEDGER_ADDR_B} +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B_2} \ + --node ${LEDGER_ADDR_B}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 50" ]]; then + echo "The balance of shielded_b_2 on chain B is wrong" + exit 1 +fi + +echo "~~ Transfer back 50 apfel from shielded_b_2 on chain B to chain A ~~" +${NAMADAC} --base-dir ${base_dir_b} ibc-transfer \ + --source ${SHIELDED_ALIAS_B_2} \ + --receiver ${payment_addr_a} \ + --token ${IBC_TOKEN} \ + --amount 50 \ + --signing-keys relayer \ + --channel-id channel-0 \ + --node ${LEDGER_ADDR_B} + +# wait for relaying +sleep 40 + +echo "==== Balances of shielded_a on chain A ====" +${NAMADAC} --base-dir ${base_dir_a} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS_A} \ + --node ${LEDGER_ADDR_A} +balance=$(${NAMADAC} --base-dir ${base_dir_a} balance \ + --token apfel \ + --owner ${SHIELDED_ALIAS_A} \ + --node ${LEDGER_ADDR_A}) +echo "${balance}" +if [[ "${balance}" != *"apfel: 950" ]]; then + echo "The balance of shielded_a on chain A is wrong" + exit 1 +fi + +echo "==== Balances of shielded_b on chain B ====" +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B} \ + --node ${LEDGER_ADDR_B}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 50" ]]; then + echo "The balance of shielded_b on chain B is wrong" + exit 1 +fi + +echo "==== Balance of shielded_b_2 on chain B ====" +balance=$(${NAMADAC} --base-dir ${base_dir_b} balance \ + --token ${IBC_TOKEN} \ + --owner ${SHIELDED_ALIAS_B_2} \ + --node ${LEDGER_ADDR_B}) +echo "${balance}" +if [[ "${balance}" != *"${IBC_TOKEN}: 0" ]]; then + echo "The balance of shielded_b_2 on chain B is wrong" + exit 1 +fi + +killall hermes +killall namadan diff --git a/e2e/namada-stargaze-transfer b/e2e/namada-stargaze-transfer new file mode 100755 index 0000000000..ce96af7b3d --- /dev/null +++ b/e2e/namada-stargaze-transfer @@ -0,0 +1,253 @@ +#!/bin/bash + +# This script tests NFT transfers between a local Namada and Stargaze testnet +# Need to create an account and an NFT on Stargaze testnet. +# `make build` and `make build-wasm-scripts` on Namada directory, +# set up a local Namada with `scripts/setup-namada-single-node`, +# edit `config_namada_stargaze.toml` +# Then Run with `namada-stargaze-transfers ${namada_dir}` +# +# Set a key as "relayer" +# starsd keys add relayer --recover +# +# Add Stargaze key as a relayer +#cargo run -q --bin hermes -- --config config_namada_stargaze.toml \ +# keys add --chain ${STARGAZE_CHAIN_ID} --mnemonic-file /dev/stdin + +set -ex + + +NAMADA_DIR=$1 +if [ -z "${NAMADA_DIR}" ] +then + echo "ERROR: Namada directory should be given" + exit 1 +fi + +cd $(dirname $0) +HERMES_DIR=${PWD%/e2e*} + +# edit for your environment +NAMADA_CHAIN_ID="namada-test.eb0199f3257a844df8" +NAMADAC="${NAMADA_DIR}/target/debug/namadac" +NAMADAN="${NAMADA_DIR}/target/debug/namadan" +NAMADAW="${NAMADA_DIR}/target/debug/namadaw" +DATA_DIR="${HERMES_DIR}/data" +NAMADA_LEDGER_ADDR="http://127.0.0.1:27657" + +TOKEN_ID="5" + +CONFIG_FILE="${HERMES_DIR}/config_namada_stargaze.toml" + +STARGAZE_CHAIN_ID="elgafar-1" +ICS721_CONTRACT="stars1ve46fjrhcrum94c7d8yc2wsdz8cpuw73503e8qn9r44spr6dw0lsvmvtqh" +SG721_CONTRACT="stars1exh83tyv29g374yhs6cktwsd2sen50gjpuq2jhfn6p7e6nqsejfq2p0v7z" +STARGAZE_NODE="https://rpc.elgafar-1.stargaze-apis.com:443" +STARGAZE_PORT="wasm.${ICS721_CONTRACT}" + +TX_ARGS="--from relayer --node ${STARGAZE_NODE} --chain-id ${STARGAZE_CHAIN_ID} --gas auto --gas-prices 0.01ustars --gas-adjustment 1.1 -y" + +NAMADA_BASE="${DATA_DIR}/namada" +SHIELDED_ALIAS="shielded-1" +PAYMENT_ALIAS="payment-1" + +SHIELDED_ALIAS_2="shielded-2" +PAYMENT_ALIAS_2="payment-2" + +#### main #### +echo "==== Check the minted NFT on Stargaze ====" +starsd query wasm contract-state smart ${SG721_CONTRACT} \ + "{\"owner_of\": {\"token_id\": \"${TOKEN_ID}\"}}" \ + --node ${STARGAZE_NODE} + +# Create a channel +resp=$(cargo run --bin hermes -- --config ${CONFIG_FILE} \ + create channel \ + --a-chain ${NAMADA_CHAIN_ID} \ + --b-chain ${STARGAZE_CHAIN_ID} \ + --a-port nft-transfer \ + --b-port ${STARGAZE_PORT} \ + --channel-version ics721-1 \ + --new-client-connection --yes) + +namada_channel=$(echo "$resp" | grep "a_side" -A 19 | grep "channel-" | sed 's/"//g' | awk -F',' '{print $1}' | sed 's/ //g') +stargaze_channel=$(echo "$resp" | grep "b_side" -A 19 | grep "channel-" | sed 's/"//g' | awk -F',' '{print $1}' | sed 's/ //g') + +echo "==== Send the NFT from Stargaze to Namada ====" +current_height=$(starsd status --node ${STARGAZE_NODE} | jq .SyncInfo.latest_block_height | sed 's/"//g') +timeout_height=$((${current_height} + 100)) +namada_receiver=$(${NAMADAW} --base-dir ${NAMADA_BASE} find --alias relayer | awk '/"relayer":/{print $3}') +msg="{\"receiver\": \"${namada_receiver}\", \"channel_id\": \"${stargaze_channel}\", \"timeout\": {\"block\": { \"revision\": 0, \"height\": ${timeout_height}}}}" +encoded_msg=$(echo ${msg} | base64) +starsd tx wasm execute ${SG721_CONTRACT} \ + "{\"send_nft\": {\"contract\":\"${ICS721_CONTRACT}\", \"token_id\": \"${TOKEN_ID}\", \"msg\": \"${encoded_msg}\"}}" \ + ${TX_ARGS} + +sleep 5 + +echo "==== Packet relaying ====" +cargo run --bin hermes -- --config ${CONFIG_FILE} clear packets \ + --chain ${STARGAZE_CHAIN_ID} \ + --port wasm.${ICS721_CONTRACT} \ + --channel ${stargaze_channel} + +echo "==== Check the escrowed NFT on Stargaze ====" +starsd query wasm contract-state smart ${SG721_CONTRACT} \ + "{\"owner_of\": {\"token_id\": \"${TOKEN_ID}\"}}" \ + --node ${STARGAZE_NODE} + +echo "==== Check the NFT on Namada ====" +token="nft-transfer/${namada_channel}/${SG721_CONTRACT}/${TOKEN_ID}" +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner relayer \ + --node ${NAMADA_LEDGER_ADDR} + +echo "==== Send back the NFT from Namada to Stargaze ====" +stargaze_receiver=$(starsd keys show relayer -a) +${NAMADAC} --base-dir ${NAMADA_BASE} ibc-transfer \ + --source relayer \ + --receiver ${stargaze_receiver} \ + --token ${token}\ + --amount 1 \ + --signing-keys relayer \ + --channel-id ${namada_channel} \ + --port-id nft-transfer \ + --node ${NAMADA_LEDGER_ADDR} + +sleep 5 + +echo "==== Packet relaying ====" +cargo run --bin hermes -- --config ${CONFIG_FILE} clear packets \ + --chain ${STARGAZE_CHAIN_ID} \ + --port wasm.${ICS721_CONTRACT} \ + --channel ${stargaze_channel} + +echo "==== Check the NFT on Stargaze ====" +starsd query wasm contract-state smart ${SG721_CONTRACT} \ + "{\"owner_of\": {\"token_id\": \"${TOKEN_ID}\"}}" \ + --node ${STARGAZE_NODE} + +echo "==== Check the NFT on Namada ====" +token="nft-transfer/${namada_channel}/${SG721_CONTRACT}/${TOKEN_ID}" +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner relayer \ + --node ${NAMADA_LEDGER_ADDR} + + +echo "======== Try shielded transfer ========" + +# setup shielded keys for Namada +${NAMADAW} --base-dir ${NAMADA_BASE} gen --shielded --alias ${SHIELDED_ALIAS} \ + --unsafe-dont-encrypt --alias-force +${NAMADAW} --base-dir ${NAMADA_BASE} gen-payment-addr --alias ${PAYMENT_ALIAS} \ + --key ${SHIELDED_ALIAS} +payment_addr=$(${NAMADAW} --base-dir ${NAMADA_BASE} find --alias ${PAYMENT_ALIAS} \ + | awk -v paymentAlias="${PAYMENT_ALIAS}" '{if($1 ~ paymentAlias) {print $2}}') + +# another one +${NAMADAW} --base-dir ${NAMADA_BASE} gen --shielded --alias ${SHIELDED_ALIAS_2} \ + --unsafe-dont-encrypt --alias-force +${NAMADAW} --base-dir ${NAMADA_BASE} gen-payment-addr --alias ${PAYMENT_ALIAS_2} \ + --key ${SHIELDED_ALIAS_2} +payment_addr_2=$(${NAMADAW} --base-dir ${NAMADA_BASE} find --alias ${PAYMENT_ALIAS_2} \ + | awk -v paymentAlias="${PAYMENT_ALIAS_2}" '{if($1 ~ paymentAlias) {print $2}}') + +echo "==== Shielding transfer from Stargaze to Namada ====" +current_height=$(starsd status --node ${STARGAZE_NODE} | jq .SyncInfo.latest_block_height | sed 's/"//g') +timeout_height=$((${current_height} + 100)) +msg="{\"receiver\": \"${payment_addr}\", \"channel_id\": \"${stargaze_channel}\", \"timeout\": {\"block\": { \"revision\": 0, \"height\": ${timeout_height}}}}" +encoded_msg=$(echo ${msg} | base64) +starsd tx wasm execute ${SG721_CONTRACT} \ + "{\"send_nft\": {\"contract\":\"${ICS721_CONTRACT}\", \"token_id\": \"${TOKEN_ID}\", \"msg\": \"${encoded_msg}\"}}" \ + ${TX_ARGS} + +sleep 5 + +echo "==== Packet relaying ====" +cargo run --bin hermes -- --config ${CONFIG_FILE} clear packets \ + --chain ${STARGAZE_CHAIN_ID} \ + --port wasm.${ICS721_CONTRACT} \ + --channel ${stargaze_channel} + +echo "==== Check the escrowed NFT on Stargaze ====" +starsd query wasm contract-state smart ${SG721_CONTRACT} \ + "{\"owner_of\": {\"token_id\": \"${TOKEN_ID}\"}}" \ + --node ${STARGAZE_NODE} + +echo "==== Check the NFT on Namada ====" +${NAMADAC} --base-dir ${NAMADA_BASE} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS} \ + --node ${NAMADA_LEDGER_ADDR} +token="nft-transfer/${namada_channel}/${SG721_CONTRACT}/${TOKEN_ID}" +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner ${SHIELDED_ALIAS} \ + --node ${NAMADA_LEDGER_ADDR} + +echo "==== Shielded transfer in Namada ====" +${NAMADAC} --base-dir ${NAMADA_BASE} transfer \ + --source ${SHIELDED_ALIAS} \ + --target ${PAYMENT_ALIAS_2} \ + --token ${token}\ + --amount 1 \ + --signing-keys relayer \ + --node ${NAMADA_LEDGER_ADDR} + +echo "==== Check the shielded NFT on Namada ====" +echo "== shielded-1 balance ==" +${NAMADAC} --base-dir ${NAMADA_BASE} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS} ${SHIELDED_ALIAS_2}\ + --node ${NAMADA_LEDGER_ADDR} +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner ${SHIELDED_ALIAS} \ + --node ${NAMADA_LEDGER_ADDR} + +echo "== shielded-2 balance ==" +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner ${SHIELDED_ALIAS_2} \ + --node ${NAMADA_LEDGER_ADDR} + +echo "==== Unshielding transfer from Namada to Stargaze ====" +${NAMADAC} --base-dir ${NAMADA_BASE} ibc-transfer \ + --source ${SHIELDED_ALIAS_2} \ + --receiver ${stargaze_receiver} \ + --token ${token}\ + --amount 1 \ + --signing-keys relayer \ + --channel-id ${namada_channel} \ + --port-id nft-transfer \ + --node ${NAMADA_LEDGER_ADDR} + +sleep 5 + +echo "==== Packet relaying ====" +cargo run --bin hermes -- --config ${CONFIG_FILE} clear packets \ + --chain ${STARGAZE_CHAIN_ID} \ + --port wasm.${ICS721_CONTRACT} \ + --channel ${stargaze_channel} + +echo "==== Check the shielded NFT on Stargaze ====" +starsd query wasm contract-state smart ${SG721_CONTRACT} \ + "{\"owner_of\": {\"token_id\": \"${TOKEN_ID}\"}}" \ + --node ${STARGAZE_NODE} + +echo "==== Check the NFT on Namada ====" +${NAMADAC} --base-dir ${NAMADA_BASE} shielded-sync \ + --viewing-keys ${SHIELDED_ALIAS} \ + --node ${NAMADA_LEDGER_ADDR} +token="nft-transfer/${namada_channel}/${SG721_CONTRACT}/${TOKEN_ID}" +echo "== shielded-1 balance ==" +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner ${SHIELDED_ALIAS} \ + --node ${NAMADA_LEDGER_ADDR} + +echo "== shielded-2 balance ==" +${NAMADAC} --base-dir ${NAMADA_BASE} balance \ + --token ${token} \ + --owner ${SHIELDED_ALIAS_2} \ + --node ${NAMADA_LEDGER_ADDR} diff --git a/flake.lock b/flake.lock index fbf9d60412..506208c59c 100644 --- a/flake.lock +++ b/flake.lock @@ -1338,11 +1338,11 @@ }, "nixpkgs_6": { "locked": { - "lastModified": 1716977081, - "narHash": "sha256-pFe5jLeIPlKEln5n2h998d7cpzXFdbrBMRe3suz4K1o=", + "lastModified": 1717459389, + "narHash": "sha256-I8/plBsua4/NZ5bKgj+z7/ThiWuud1YFwLsn1QQ5PgE=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ac82a513e55582291805d6f09d35b6d8b60637a1", + "rev": "3b01abcc24846ae49957b30f4345bab4b3f1d14b", "type": "github" }, "original": { diff --git a/scripts/setup-namada b/scripts/setup-namada new file mode 100755 index 0000000000..313a568c72 --- /dev/null +++ b/scripts/setup-namada @@ -0,0 +1,242 @@ +#!/bin/bash + +# This script sets up 2 Namada chains locally +# `make build` and `make build-wasm-scripts` on Namada directory in advance +# Run with `setup-namada ${namada_dir}` + +set -e + + +# Get absolute path to Namada directory +SCRIPT_DIR=$(cd $(dirname $0) && pwd) +NAMADA_DIR=$(cd $1 && pwd) +cd $SCRIPT_DIR +if [ -z "${NAMADA_DIR}" ] +then + echo "ERROR: Namada directory should be given" + exit 1 +fi + +HERMES_DIR=${PWD%/scripts*} + +# edit for your environment +NAMADAC="${NAMADA_DIR}/target/debug/namadac" +NAMADAN="${NAMADA_DIR}/target/debug/namadan" +NAMADAW="${NAMADA_DIR}/target/debug/namadaw" +BASE_GENESIS_DIR="${NAMADA_DIR}/genesis/localnet" +CHECKSUM_PATH="${NAMADA_DIR}/wasm/checksums.json" +DATA_DIR="${HERMES_DIR}/data" + +LEDGER_ADDR_A="http://127.0.0.1:27657" +LEDGER_ADDR_B="http://127.0.0.1:28657" + +HERMES_CONFIG_TEMPLATE=" +[global] +log_level = 'info' + +[mode] + +[mode.clients] +enabled = true +refresh = true +misbehaviour = true + +[mode.connections] +enabled = false + +[mode.channels] +enabled = false + +[mode.packets] +enabled = true +clear_interval = 10 +clear_on_start = false +tx_confirmation = true + +[telemetry] +enabled = false +host = '127.0.0.1' +port = 3001 + +[[chains]] +id = '_CHAIN_ID_A_' +type = 'Namada' +rpc_addr = 'http://127.0.0.1:27657' +grpc_addr = 'http://127.0.0.1:9090' +event_source = { mode = 'push', url = 'ws://127.0.0.1:27657/websocket', batch_delay = '500ms' } +account_prefix = '' +key_name = 'relayer' +store_prefix = 'ibc' +gas_price = { price = 0.001, denom = '_FEE_TOKEN_A_' } + +[[chains]] +id = '_CHAIN_ID_B_' +type = 'Namada' +rpc_addr = 'http://127.0.0.1:28657' +grpc_addr = 'http://127.0.0.1:9090' +event_source = { mode = 'push', url = 'ws://127.0.0.1:28657/websocket', batch_delay = '500ms' } +account_prefix = '' +key_name = 'relayer' +store_prefix = 'ibc' +gas_price = { price = 0.001, denom = '_FEE_TOKEN_B_' } +" + +function make_genesis() { + local suffix=$1 + local base_dir=${DATA_DIR}/namada-${suffix} + + mkdir -p ${base_dir}/templates + cp ${BASE_GENESIS_DIR}/*.toml ${base_dir}/templates + sed -i .bak "s/epochs_per_year = .*/epochs_per_year = 31536/g" ${base_dir}/templates/parameters.toml + sed -i .bak "s/default_mint_limit = .*/default_mint_limit = \"1000000000\"/g" ${base_dir}/templates/parameters.toml + sed -i .bak "s/default_per_epoch_throughput_limit = .*/default_per_epoch_throughput_limit = \"1000000000\"/g" ${base_dir}/templates/parameters.toml + + mkdir ${base_dir}/pre-genesis + cp -r ${BASE_GENESIS_DIR}/src/pre-genesis/* ${base_dir}/pre-genesis +} + +function init_network() { + local suffix=$1 + local base_dir=${DATA_DIR}/namada-${suffix} + local validator_base_dir=${base_dir}/setup/validator-0 + + mkdir -p ${base_dir}/genesis + local chain_id=$(NAMADA_BASE_DIR=${base_dir} \ + ${NAMADAC} utils init-network \ + --chain-prefix namada-${suffix} \ + --genesis-time "2023-01-01T00:00:00Z" \ + --templates-path ${base_dir}/templates \ + --wasm-checksums-path ${CHECKSUM_PATH} \ + --archive-dir ${base_dir}/genesis \ + | awk '$1 == "Derived" {print $4}') + + NAMADA_NETWORK_CONFIGS_DIR=${base_dir}/genesis \ + ${NAMADAC} --base-dir ${validator_base_dir} \ + utils join-network \ + --chain-id ${chain_id} \ + --genesis-validator validator-0 \ + --pre-genesis-path \ + ${base_dir}/pre-genesis/validator-0 \ + --dont-prefetch-wasm + + rm -rf ${base_dir}/${chain_id} + # for non-validator + NAMADA_NETWORK_CONFIGS_DIR=${base_dir}/genesis \ + ${NAMADAC} --base-dir ${base_dir} \ + utils join-network \ + --chain-id ${chain_id} \ + --dont-prefetch-wasm +} + +function copy_wasm() { + local suffix=$1 + local chain_id=$2 + + local base_dir=${DATA_DIR}/namada-${suffix} + + cp ${NAMADA_DIR}/wasm/*.wasm ${base_dir}/setup/validator-0/${chain_id}/wasm/ +} + +function init_relayer_acc() { + local suffix=$1 + local chain_id=$2 + + local base_dir=${DATA_DIR}/namada-${suffix} + + ${NAMADAW} --base-dir ${base_dir} \ + gen --alias relayer --unsafe-dont-encrypt +} + +function add_relayer_key() { + local suffix=$1 + local chain_id=$2 + + local base_dir=${DATA_DIR}/namada-${suffix} + + cargo run --bin hermes -- --config ${HERMES_DIR}/config_for_namada.toml \ + keys add \ + --chain ${chain_id} \ + --key-file ${base_dir}/${chain_id}/wallet.toml \ + --overwrite +} + +# ==== main ==== + +mkdir -p ${DATA_DIR} + +# for chain A +make_genesis "a" +result=$(init_network "a") +chain_id_a=$(echo "${result}" | awk '$5 == "ID" {id = $6} END {print id}') + +copy_wasm "a" ${chain_id_a} + +${NAMADAN} --base-dir ${DATA_DIR}/namada-a/setup/validator-0 \ + ledger run > ${DATA_DIR}/namada-a/namada.log 2>&1 & +sleep 5 + +# shutdown temporarily to bootstrap chain-b +killall namadan + +# for chain B +make_genesis "b" +result=$(init_network "b") +chain_id_b=$(echo "${result}" | awk '$5 == "ID" {id = $6} END {print id}') + +copy_wasm "b" ${chain_id_b} + +${NAMADAN} --base-dir ${DATA_DIR}/namada-b/setup/validator-0 \ + ledger run > ${DATA_DIR}/namada-b/namada.log 2>&1 & +sleep 5 + +# shutdown temporarily to bootstrap chain-b +killall namadan + +# Edit chain-b addresses +sed -i .bak \ + -e "s/:27656/:28656/" \ + -e "s/:27657/:28657/" \ + -e "s/:27658/:28658/" \ + ${DATA_DIR}/namada-b/setup/validator-0/${chain_id_b}/config.toml +sed -i .bak \ + -e "s/:27656/:28656/" \ + -e "s/:27657/:28657/" \ + -e "s/:27658/:28658/" \ + ${DATA_DIR}/namada-b/setup/validator-0/${chain_id_b}/cometbft/config/config.toml + +# Restart each chain +${NAMADAN} --base-dir ${DATA_DIR}/namada-a/setup/validator-0 \ + ledger run > ${DATA_DIR}/namada-a/namada.log 2>&1 & +echo "Namada chain A's PID = $!" +sleep 5 + +${NAMADAN} --base-dir ${DATA_DIR}/namada-b/setup/validator-0 \ + ledger run > ${DATA_DIR}/namada-b/namada.log 2>&1 & +echo "Namada chain B's PID = $!" +sleep 5 + +# Create "relayer" account on each chain +init_relayer_acc "a" ${chain_id_a} +init_relayer_acc "b" ${chain_id_b} + +# Get token addresses +nam_addr_a=$(${NAMADAW} --base-dir ${DATA_DIR}/namada-a find --alias nam | awk '/"nam":/{print $3}') +nam_addr_b=$(${NAMADAW} --base-dir ${DATA_DIR}/namada-b find --alias nam | awk '/"nam":/{print $3}') + +# Make Hermes config +cd ${HERMES_DIR} +echo "${HERMES_CONFIG_TEMPLATE}" \ + | sed -e "s/_CHAIN_ID_A_/${chain_id_a}/g" -e "s/_CHAIN_ID_B_/${chain_id_b}/g" \ + | sed -e "s/_FEE_TOKEN_A_/${nam_addr_a}/g" -e "s/_FEE_TOKEN_B_/${nam_addr_b}/g" \ + > ${HERMES_DIR}/config_for_namada.toml + +# Add namada keys to Hermes +add_relayer_key "a" ${chain_id_a} +add_relayer_key "b" ${chain_id_b} + +echo "2 Namada chains are running" +echo "You can use Hermes with ${HERMES_DIR}/config_for_namada.toml" + +echo "You also want to run the following lines:" +echo "export CHAIN_A_ID=${chain_id_a}" +echo "export CHAIN_B_ID=${chain_id_b}" diff --git a/scripts/setup-namada-single-node b/scripts/setup-namada-single-node new file mode 100755 index 0000000000..9c33c15cd7 --- /dev/null +++ b/scripts/setup-namada-single-node @@ -0,0 +1,184 @@ +#!/bin/bash + +# This script sets up 1 Namada chain locally +# `make build` and `make build-wasm-scripts` on Namada directory in advance +# Run with `setup-namada-single-node ${namada_dir}` + +set -e + +NAMADA_DIR=$1 +if [ -z "${NAMADA_DIR}" ] +then + echo "ERROR: Namada directory should be given" + exit 1 +fi +cd $(dirname $0) +HERMES_DIR=${PWD%/scripts*} + +# edit for your environment +NAMADAC="${NAMADA_DIR}/target/debug/namadac" +NAMADAN="${NAMADA_DIR}/target/debug/namadan" +NAMADAW="${NAMADA_DIR}/target/debug/namadaw" +BASE_GENESIS_DIR="${NAMADA_DIR}/genesis/localnet" +CHECKSUM_PATH="${NAMADA_DIR}/wasm/checksums.json" +DATA_DIR="${HERMES_DIR}/data" + +LEDGER_ADDR="http://127.0.0.1:27657" + +HERMES_CONFIG_TEMPLATE=" +[global] +log_level = 'info' + +[mode] + +[mode.clients] +enabled = true +refresh = true +misbehaviour = true + +[mode.connections] +enabled = false + +[mode.channels] +enabled = false + +[mode.packets] +enabled = true +clear_interval = 10 +clear_on_start = false +tx_confirmation = true + +[telemetry] +enabled = false +host = '127.0.0.1' +port = 3001 + +[[chains]] +id = '_CHAIN_ID_' +type = 'Namada' +rpc_addr = 'http://127.0.0.1:27657' +grpc_addr = 'http://127.0.0.1:9090' +event_source = { mode = 'push', url = 'ws://127.0.0.1:27657/websocket', batch_delay = '500ms' } +account_prefix = '' +key_name = 'relayer' +store_prefix = 'ibc' +gas_price = { price = 0.001, denom = '_FEE_TOKEN_' } +" + +function make_genesis() { + local base_dir=${DATA_DIR}/namada + + mkdir -p ${base_dir}/templates + cp ${BASE_GENESIS_DIR}/*.toml ${base_dir}/templates + sed -i .bak "s/epochs_per_year = .*/epochs_per_year = 31536/g" ${base_dir}/templates/parameters.toml + sed -i .bak "s/default_mint_limit = .*/default_mint_limit = \"1000000000\"/g" ${base_dir}/templates/parameters.toml + sed -i .bak "s/default_per_epoch_throughput_limit = .*/default_per_epoch_throughput_limit = \"1000000000\"/g" ${base_dir}/templates/parameters.toml + + mkdir ${base_dir}/pre-genesis + cp -r ${BASE_GENESIS_DIR}/src/pre-genesis/* ${base_dir}/pre-genesis +} + +function init_network() { + local base_dir=${DATA_DIR}/namada + local validator_base_dir=${base_dir}/setup/validator-0 + + mkdir -p ${base_dir}/genesis + local chain_id=$(NAMADA_BASE_DIR=${base_dir} \ + ${NAMADAC} utils init-network \ + --chain-prefix namada-test \ + --genesis-time "2023-01-01T00:00:00Z" \ + --templates-path ${base_dir}/templates \ + --wasm-checksums-path ${CHECKSUM_PATH} \ + --archive-dir ${base_dir}/genesis \ + | awk '$1 == "Derived" {print $4}') + + NAMADA_NETWORK_CONFIGS_DIR=${base_dir}/genesis \ + ${NAMADAC} --base-dir ${validator_base_dir} \ + utils join-network \ + --chain-id ${chain_id} \ + --genesis-validator validator-0 \ + --pre-genesis-path \ + ${base_dir}/pre-genesis/validator-0 \ + --dont-prefetch-wasm + + # for non-validator + rm -rf ${base_dir}/${chain_id} + NAMADA_NETWORK_CONFIGS_DIR=${base_dir}/genesis \ + ${NAMADAC} --base-dir ${base_dir} \ + utils join-network \ + --chain-id ${chain_id} \ + --dont-prefetch-wasm +} + +function copy_wasm() { + local chain_id=$1 + local base_dir=${DATA_DIR}/namada + + cp ${NAMADA_DIR}/wasm/*.wasm ${base_dir}/setup/validator-0/${chain_id}/wasm/ +} + +function init_relayer_acc() { + local chain_id=$1 + + local base_dir=${DATA_DIR}/namada + + ${NAMADAW} --base-dir ${base_dir} \ + gen --alias relayer --unsafe-dont-encrypt +} + +function fund_relayer_acc() { + local account=$1 + local base_dir=${DATA_DIR}/namada + + ${NAMADAC} --base-dir ${base_dir} \ + transparent-transfer --node ${LEDGER_ADDR} \ + --source ${account} --target relayer --amount 10000 --token NAM +} + +function add_relayer_key() { + local chain_id=$1 + + local base_dir=${DATA_DIR}/namada + + cargo run --bin hermes -- --config ${HERMES_DIR}/config_for_namada.toml \ + keys add \ + --chain ${chain_id} \ + --key-file ${base_dir}/${chain_id}/wallet.toml \ + --overwrite +} + +# ==== main ==== + +mkdir -p ${DATA_DIR} + +make_genesis +result=$(init_network) +chain_id=$(echo "${result}" | awk '$5 == "ID" {id = $6} END {print id}') + +copy_wasm ${chain_id} + +${NAMADAN} --base-dir ${DATA_DIR}/namada/setup/validator-0 \ + ledger run > ${DATA_DIR}/namada/namada.log 2>&1 & +echo "Namada chain's PID = $!" +sleep 5 + +init_relayer_acc ${chain_id} +sleep 10 + +fund_relayer_acc "albert" ${LEDGER_ADDR} + +nam_addr=$(${NAMADAW} --base-dir ${DATA_DIR}/namada find --alias nam | awk '/"nam":/{print $3}') + +# for the relayer +cd ${HERMES_DIR} +echo "${HERMES_CONFIG_TEMPLATE}" \ + | sed -e "s/_CHAIN_ID_/${chain_id}/g" -e "s/_FEE_TOKEN_/${nam_addr}/g" \ + > ${HERMES_DIR}/config_for_namada.toml + +add_relayer_key ${chain_id} + +echo "A Namada chain is running" +echo "You can use Hermes with ${HERMES_DIR}/config_for_namada.toml" + +echo "You also want to run the following lines:" +echo "export CHAIN_ID=${chain_id}" diff --git a/tools/integration-test/Cargo.toml b/tools/integration-test/Cargo.toml index 8a0a8dacf7..e8bb6395b6 100644 --- a/tools/integration-test/Cargo.toml +++ b/tools/integration-test/Cargo.toml @@ -48,10 +48,11 @@ async-icq = [] juno = [] dynamic-gas-fee = [] new-register-interchain-account = [] +namada = [] [[bin]] name = "test_setup_with_binary_channel" -doc = true +doc = true [dev-dependencies] tempfile = { workspace = true } diff --git a/tools/integration-test/src/bin/test_setup_with_binary_channel.rs b/tools/integration-test/src/bin/test_setup_with_binary_channel.rs index 44d6cb40e4..85565698e2 100644 --- a/tools/integration-test/src/bin/test_setup_with_binary_channel.rs +++ b/tools/integration-test/src/bin/test_setup_with_binary_channel.rs @@ -43,7 +43,7 @@ impl TestOverrides for Test { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { // Modify the key store type to `Store::Test` so that the wallet // keys are stored to ~/.hermes/keys so that we can use them // with external relayer commands. diff --git a/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs b/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs index ac938158d2..39b749c3bf 100644 --- a/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs +++ b/tools/integration-test/src/bin/test_setup_with_fee_enabled_binary_channel.rs @@ -44,7 +44,7 @@ impl TestOverrides for Test { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { // Modify the key store type to `Store::Test` so that the wallet // keys are stored to ~/.hermes/keys so that we can use them // with external relayer commands. diff --git a/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs b/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs index 1cfcd0f921..b11f77634d 100644 --- a/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs +++ b/tools/integration-test/src/bin/test_setup_with_ternary_channel.rs @@ -43,7 +43,7 @@ impl TestOverrides for Test { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { // Modify the key store type to `Store::Test` so that the wallet // keys are stored to ~/.hermes/keys so that we can use them // with external relayer commands. diff --git a/tools/integration-test/src/mbt/handlers.rs b/tools/integration-test/src/mbt/handlers.rs index 32c445984e..aae54e2c92 100644 --- a/tools/integration-test/src/mbt/handlers.rs +++ b/tools/integration-test/src/mbt/handlers.rs @@ -219,7 +219,12 @@ pub fn ibc_transfer_receive_packet( DualTagged::new(channels.channel_id_b.value()), ); - let denom_target = derive_ibc_denom(&port_target, &channel_id_target, &denom_source)?; + let denom_target = derive_ibc_denom( + &node_target.value().chain_driver.chain_type, + &port_target, + &channel_id_target, + &denom_source, + )?; info!( "Waiting for user on chain {} to receive IBC transferred amount of {} {} (chain {}/{})", diff --git a/tools/integration-test/src/mbt/transfer.rs b/tools/integration-test/src/mbt/transfer.rs index 846edc822f..69c773d5a6 100644 --- a/tools/integration-test/src/mbt/transfer.rs +++ b/tools/integration-test/src/mbt/transfer.rs @@ -159,7 +159,7 @@ impl TestOverrides for IbcTransferMBT { for chain_config in config.chains.iter_mut() { match chain_config { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.trusting_period = Some(CLIENT_EXPIRY); } } diff --git a/tools/integration-test/src/tests/async_icq/simple_query.rs b/tools/integration-test/src/tests/async_icq/simple_query.rs index f8343d1811..5fc53f4f9c 100644 --- a/tools/integration-test/src/tests/async_icq/simple_query.rs +++ b/tools/integration-test/src/tests/async_icq/simple_query.rs @@ -1,6 +1,6 @@ use ibc_relayer::channel::version::Version; use ibc_relayer::config::ChainConfig; -use ibc_test_framework::chain::config::{ +use ibc_test_framework::chain::config::cosmos::{ add_allow_message_interchainquery, set_max_deposit_period, set_voting_period, }; use ibc_test_framework::chain::ext::async_icq::AsyncIcqMethodsExt; @@ -52,8 +52,10 @@ impl BinaryConnectionTest for AsyncIcqTest { chains: ConnectedChains, connection: ConnectedConnection, ) -> Result<(), Error> { - let fee_denom_a: MonoTagged = - MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a: MonoTagged = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let port_a = DualTagged::new(PortId::oracle()); let port_b = DualTagged::new(PortId::icqhost()); let (channel_id_b, channel_id_a) = init_channel_version( @@ -129,7 +131,7 @@ fn assert_eventual_async_icq_success( relayer: &RelayerDriver, ) -> Result<(), Error> { let rpc_addr = match relayer.config.chains.first().unwrap() { - ChainConfig::CosmosSdk(c) => c.rpc_addr.clone(), + ChainConfig::CosmosSdk(c) | ChainConfig::Namada(c) => c.rpc_addr.clone(), }; let mut rpc_client = HttpClient::new(rpc_addr).unwrap(); diff --git a/tools/integration-test/src/tests/channel_upgrade/flushing.rs b/tools/integration-test/src/tests/channel_upgrade/flushing.rs index 0e4bdf7143..3b2777f733 100644 --- a/tools/integration-test/src/tests/channel_upgrade/flushing.rs +++ b/tools/integration-test/src/tests/channel_upgrade/flushing.rs @@ -10,7 +10,7 @@ use ibc_relayer::chain::requests::{IncludeProof, QueryChannelRequest, QueryHeigh use ibc_relayer_types::core::ics04_channel::channel::State as ChannelState; use ibc_relayer_types::core::ics04_channel::packet::Sequence; use ibc_relayer_types::core::ics04_channel::version::Version; -use ibc_test_framework::chain::config::{set_max_deposit_period, set_voting_period}; +use ibc_test_framework::chain::config::cosmos::{set_max_deposit_period, set_voting_period}; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::channel::{ assert_eventually_channel_established, assert_eventually_channel_upgrade_ack, @@ -166,6 +166,7 @@ impl BinaryChannelTest for ChannelUpgradeFlushing { relayer.with_supervisor(|| { let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, @@ -384,6 +385,7 @@ impl BinaryChannelTest for ChannelUpgradeHandshakeFlushPackets { // and move channel ends to `FLUSH_COMPLETE` relayer.with_supervisor(|| { let ibc_denom_a = derive_ibc_denom( + &chains.node_a.chain_driver().value().chain_type, &channels.port_a.as_ref(), &channels.channel_id_a.as_ref(), &denom_b, @@ -395,6 +397,7 @@ impl BinaryChannelTest for ChannelUpgradeHandshakeFlushPackets { )?; let ibc_denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/channel_upgrade/ica.rs b/tools/integration-test/src/tests/channel_upgrade/ica.rs index 4b26c9d37b..d86ab682f3 100644 --- a/tools/integration-test/src/tests/channel_upgrade/ica.rs +++ b/tools/integration-test/src/tests/channel_upgrade/ica.rs @@ -32,7 +32,7 @@ use ibc_relayer_types::signer::Signer; use ibc_relayer_types::timestamp::Timestamp; use ibc_relayer_types::tx_msg::Msg; -use ibc_test_framework::chain::config::{ +use ibc_test_framework::chain::config::cosmos::{ add_allow_message_interchainaccounts, set_max_deposit_period, set_voting_period, }; use ibc_test_framework::chain::ext::ica::register_ordered_interchain_account; @@ -90,7 +90,7 @@ impl BinaryConnectionTest for ChannelUpgradeICACloseChannel { chains: ConnectedChains, connection: ConnectedConnection, ) -> Result<(), Error> { - let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake")); + let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); // Run the block with supervisor in order to open and then upgrade the ICA channel let (wallet, ica_address, controller_channel_id, controller_port_id) = relayer @@ -312,7 +312,7 @@ impl TestOverrides for ChannelUpgradeICAUnordered { for chain in &mut config.chains { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.packet_filter = self.packet_filter.clone(); } } @@ -340,7 +340,7 @@ impl BinaryConnectionTest for ChannelUpgradeICAUnordered { chains: ConnectedChains, connection: ConnectedConnection, ) -> Result<(), Error> { - let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake")); + let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); info!("Will register interchain account..."); diff --git a/tools/integration-test/src/tests/channel_upgrade/ics29.rs b/tools/integration-test/src/tests/channel_upgrade/ics29.rs index 02f90b2745..95db144604 100644 --- a/tools/integration-test/src/tests/channel_upgrade/ics29.rs +++ b/tools/integration-test/src/tests/channel_upgrade/ics29.rs @@ -7,7 +7,7 @@ use ibc_relayer::chain::requests::{IncludeProof, QueryChannelRequest, QueryHeight}; use ibc_relayer_types::core::ics04_channel::packet::Sequence; use ibc_relayer_types::core::ics04_channel::version::Version; -use ibc_test_framework::chain::config::{set_max_deposit_period, set_voting_period}; +use ibc_test_framework::chain::config::cosmos::{set_max_deposit_period, set_voting_period}; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::channel::{ assert_eventually_channel_established, assert_eventually_channel_upgrade_open, @@ -202,6 +202,7 @@ impl BinaryChannelTest for ChannelUpgradeICS29 { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/channel_upgrade/timeout.rs b/tools/integration-test/src/tests/channel_upgrade/timeout.rs index 42bdd288ed..ed391391f1 100644 --- a/tools/integration-test/src/tests/channel_upgrade/timeout.rs +++ b/tools/integration-test/src/tests/channel_upgrade/timeout.rs @@ -27,7 +27,7 @@ use ibc_relayer_types::core::ics04_channel::channel::State as ChannelState; use ibc_relayer_types::core::ics04_channel::packet::Sequence; use ibc_relayer_types::core::ics04_channel::version::Version; use ibc_relayer_types::events::IbcEventType; -use ibc_test_framework::chain::config::{set_max_deposit_period, set_voting_period}; +use ibc_test_framework::chain::config::cosmos::{set_max_deposit_period, set_voting_period}; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::channel::{ assert_eventually_channel_established, assert_eventually_channel_upgrade_ack, @@ -992,6 +992,7 @@ impl BinaryChannelTest for ChannelUpgradeHandshakeTimeoutOnPacketAck { // and move channel ends to `FLUSH_COMPLETE` relayer.with_supervisor(|| { let ibc_denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake.rs b/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake.rs index 1a8dbe27ed..2929bf649a 100644 --- a/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake.rs +++ b/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake.rs @@ -11,7 +11,7 @@ use std::thread::sleep; use ibc_relayer::chain::requests::{IncludeProof, QueryChannelRequest, QueryHeight}; use ibc_relayer_types::core::ics04_channel::packet::Sequence; use ibc_relayer_types::core::ics04_channel::version::Version; -use ibc_test_framework::chain::config::{set_max_deposit_period, set_voting_period}; +use ibc_test_framework::chain::config::cosmos::{set_max_deposit_period, set_voting_period}; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::channel::{ assert_eventually_channel_established, assert_eventually_channel_upgrade_open, diff --git a/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake_steps.rs b/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake_steps.rs index 31b665bc9a..c295ab55e4 100644 --- a/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake_steps.rs +++ b/tools/integration-test/src/tests/channel_upgrade/upgrade_handshake_steps.rs @@ -29,7 +29,7 @@ use ibc_relayer::chain::requests::{IncludeProof, QueryChannelRequest, QueryHeigh use ibc_relayer_types::core::ics04_channel::channel::{State as ChannelState, UpgradeState}; use ibc_relayer_types::core::ics04_channel::packet::Sequence; use ibc_relayer_types::core::ics04_channel::version::Version; -use ibc_test_framework::chain::config::{set_max_deposit_period, set_voting_period}; +use ibc_test_framework::chain::config::cosmos::{set_max_deposit_period, set_voting_period}; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::channel::{ assert_eventually_channel_established, assert_eventually_channel_upgrade_ack, diff --git a/tools/integration-test/src/tests/clear_packet.rs b/tools/integration-test/src/tests/clear_packet.rs index ce9a94ada9..68d1fba0dc 100644 --- a/tools/integration-test/src/tests/clear_packet.rs +++ b/tools/integration-test/src/tests/clear_packet.rs @@ -127,8 +127,11 @@ impl BinaryChannelTest for ClearPacketTest { sleep(Duration::from_secs(1)); - let amount_b = - amount2.transfer(&channel.port_b.as_ref(), &channel.channel_id_b.as_ref())?; + let amount_b = amount2.transfer( + &chains.node_b.chain_driver().value().chain_type, + &channel.port_b.as_ref(), + &channel.channel_id_b.as_ref(), + )?; // Wallet on chain A should have both amount deducted. chains.node_a.chain_driver().assert_eventual_wallet_amount( @@ -181,6 +184,7 @@ impl BinaryChannelTest for ClearPacketRecoveryTest { )?; let denom_b2 = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -224,7 +228,10 @@ impl BinaryChannelTest for ClearPacketNoScanTest { channel: ConnectedChannel, ) -> Result<(), Error> { let denom_a = chains.node_a.denom(); - let fee_denom_a = MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let wallet_a = chains.node_a.wallets().user1().cloned(); let wallet_b = chains.node_b.wallets().user1().cloned(); @@ -245,6 +252,7 @@ impl BinaryChannelTest for ClearPacketNoScanTest { )?; let denom_b2 = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -325,7 +333,9 @@ impl TestOverrides for ClearPacketOverrideTest { for chain_config in config.chains.iter_mut() { match chain_config { // Use a small clear interval in the chain configurations to override the global high interval - ChainConfig::CosmosSdk(chain_config) => chain_config.clear_interval = Some(10), + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.clear_interval = Some(10) + } } } } @@ -344,7 +354,10 @@ impl BinaryChannelTest for ClearPacketOverrideTest { channel: ConnectedChannel, ) -> Result<(), Error> { let denom_a = chains.node_a.denom(); - let fee_denom_a = MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let wallet_a = chains.node_a.wallets().user1().cloned(); let wallet_b = chains.node_b.wallets().user1().cloned(); @@ -365,6 +378,7 @@ impl BinaryChannelTest for ClearPacketOverrideTest { )?; let denom_b2 = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/client_expiration.rs b/tools/integration-test/src/tests/client_expiration.rs index 082cacf70a..80877b31ea 100644 --- a/tools/integration-test/src/tests/client_expiration.rs +++ b/tools/integration-test/src/tests/client_expiration.rs @@ -113,7 +113,7 @@ impl TestOverrides for ExpirationTestOverrides { for chain_config in config.chains.iter_mut() { match chain_config { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.trusting_period = Some(CLIENT_EXPIRY); } } @@ -313,6 +313,7 @@ impl BinaryChainTest for PacketExpirationTest { let denom_a = chains.node_a.denom(); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/client_refresh.rs b/tools/integration-test/src/tests/client_refresh.rs index e29adbb821..bac99acb09 100644 --- a/tools/integration-test/src/tests/client_refresh.rs +++ b/tools/integration-test/src/tests/client_refresh.rs @@ -14,11 +14,14 @@ fn test_client_default_refresh() -> Result<(), Error> { run_binary_chain_test(&ClientDefaultsTest) } +// TODO: it should work after surrpoting gas estimation +#[cfg(not(feature = "namada"))] #[test] fn test_client_fail_refresh() -> Result<(), Error> { run_binary_chain_test(&ClientFailsTest) } +#[allow(dead_code)] struct ClientFailsTest; struct ClientDefaultsTest; @@ -126,12 +129,24 @@ impl BinaryChainTest for ClientFailsTest { chains, |config| { { - let ChainConfig::CosmosSdk(config_chain_a) = &mut config.chains[0]; - config_chain_a.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + match &mut config.chains[0] { + ChainConfig::CosmosSdk(config_chain_a) => { + config_chain_a.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + } + ChainConfig::Namada(config_chain_a) => { + config_chain_a.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + } + } } - let ChainConfig::CosmosSdk(config_chain_b) = &mut config.chains[1]; - config_chain_b.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + match &mut config.chains[1] { + ChainConfig::CosmosSdk(config_chain_b) => { + config_chain_b.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + } + ChainConfig::Namada(config_chain_b) => { + config_chain_b.gas_multiplier = Some(GasMultiplier::unsafe_new(0.8)); + } + } }, config, )?; @@ -160,6 +175,7 @@ impl BinaryChainTest for ClientFailsTest { } } +#[allow(dead_code)] fn override_connected_chains( chains: ConnectedChains, config_modifier: impl FnOnce(&mut Config), @@ -202,6 +218,7 @@ where Ok(chains) } +#[allow(dead_code)] fn restore_foreign_client_pair( chain_a: &ChainA, chain_b: &ChainB, diff --git a/tools/integration-test/src/tests/client_settings.rs b/tools/integration-test/src/tests/client_settings.rs index 0a3c7656a4..ccaee68b41 100644 --- a/tools/integration-test/src/tests/client_settings.rs +++ b/tools/integration-test/src/tests/client_settings.rs @@ -26,7 +26,7 @@ struct ClientOptionsTest; impl TestOverrides for ClientDefaultsTest { fn modify_relayer_config(&self, config: &mut Config) { match &mut config.chains[0] { - ChainConfig::CosmosSdk(chain_config_a) => { + ChainConfig::CosmosSdk(chain_config_a) | ChainConfig::Namada(chain_config_a) => { chain_config_a.clock_drift = Duration::from_secs(3); chain_config_a.max_block_time = Duration::from_secs(5); chain_config_a.trusting_period = Some(Duration::from_secs(120_000)); @@ -35,7 +35,7 @@ impl TestOverrides for ClientDefaultsTest { } match &mut config.chains[1] { - ChainConfig::CosmosSdk(chain_config_b) => { + ChainConfig::CosmosSdk(chain_config_b) | ChainConfig::Namada(chain_config_b) => { chain_config_b.clock_drift = Duration::from_secs(6); chain_config_b.max_block_time = Duration::from_secs(15); chain_config_b.trusting_period = Some(Duration::from_secs(340_000)); diff --git a/tools/integration-test/src/tests/client_upgrade.rs b/tools/integration-test/src/tests/client_upgrade.rs index e6f94a0336..b420c481a5 100644 --- a/tools/integration-test/src/tests/client_upgrade.rs +++ b/tools/integration-test/src/tests/client_upgrade.rs @@ -21,7 +21,7 @@ use ibc_relayer::chain::requests::QueryHeight; use ibc_relayer::client_state::AnyClientState; use ibc_relayer::upgrade_chain::{build_and_send_ibc_upgrade_proposal, UpgradePlanOptions}; use ibc_relayer_types::core::ics02_client::height::Height; -use ibc_test_framework::chain::config::{ +use ibc_test_framework::chain::config::cosmos::{ set_max_deposit_period, set_min_deposit_amount, set_voting_period, }; use ibc_test_framework::chain::ext::bootstrap::ChainBootstrapMethodsExt; @@ -82,8 +82,10 @@ impl BinaryChainTest for ClientUpgradeTest { chains: ibc_test_framework::prelude::ConnectedChains, ) -> Result<(), ibc_test_framework::prelude::Error> { let upgraded_chain_id = ChainId::new("upgradedibc".to_owned(), 1); - let fee_denom_a: MonoTagged = - MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a: MonoTagged = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let foreign_clients = chains.clone().foreign_clients; // Create and send an chain upgrade proposal @@ -241,8 +243,10 @@ impl BinaryChainTest for HeightTooHighClientUpgradeTest { chains: ibc_test_framework::prelude::ConnectedChains, ) -> Result<(), ibc_test_framework::prelude::Error> { let upgraded_chain_id = ChainId::new("upgradedibc".to_owned(), 1); - let fee_denom_a: MonoTagged = - MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a: MonoTagged = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let foreign_clients = chains.clone().foreign_clients; // Create and send an chain upgrade proposal @@ -339,8 +343,10 @@ impl BinaryChainTest for HeightTooLowClientUpgradeTest { chains: ibc_test_framework::prelude::ConnectedChains, ) -> Result<(), ibc_test_framework::prelude::Error> { let upgraded_chain_id = ChainId::new("upgradedibc".to_owned(), 1); - let fee_denom_a: MonoTagged = - MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a: MonoTagged = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let foreign_clients = chains.clone().foreign_clients; let opts = create_upgrade_plan(config, &chains, &upgraded_chain_id)?; @@ -432,8 +438,10 @@ fn create_upgrade_plan( chains: &ibc_test_framework::prelude::ConnectedChains, upgraded_chain_id: &ChainId, ) -> Result { - let fee_denom_a: MonoTagged = - MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a: MonoTagged = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let foreign_clients = chains.clone().foreign_clients; let src_client_id = foreign_clients.client_id_b().0.clone(); diff --git a/tools/integration-test/src/tests/connection_delay.rs b/tools/integration-test/src/tests/connection_delay.rs index 0c8ca19e57..43f034f45e 100644 --- a/tools/integration-test/src/tests/connection_delay.rs +++ b/tools/integration-test/src/tests/connection_delay.rs @@ -58,6 +58,7 @@ impl BinaryChannelTest for ConnectionDelayTest { let time1 = OffsetDateTime::now_utc(); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/consensus_states.rs b/tools/integration-test/src/tests/consensus_states.rs index bfd0891679..845a7e67fc 100644 --- a/tools/integration-test/src/tests/consensus_states.rs +++ b/tools/integration-test/src/tests/consensus_states.rs @@ -1,9 +1,13 @@ -use ibc_relayer::chain::{ - cosmos::query::consensus_state::query_consensus_states, - requests::{PageRequest, QueryConsensusStateHeightsRequest, QueryConsensusStatesRequest}, +use ibc_relayer::{ + chain::{ + cosmos::query::consensus_state::query_consensus_states, + requests::{PageRequest, QueryConsensusStateHeightsRequest, QueryConsensusStatesRequest}, + }, + config::ChainConfig, }; use ibc_test_framework::prelude::*; +use ibc_test_framework::util::namada; #[test] fn test_consensus_state_heights() -> Result<(), Error> { @@ -48,29 +52,35 @@ impl BinaryChainTest for ConsensusStateHeights { &CONSENSUS_STATES_COUNT, )?; - let grpc_address = chains - .node_b - .value() - .chain_driver - .grpc_address() - .as_str() - .parse() - .unwrap(); + let states = match chains.handle_b().config().expect("Config should exist") { + ChainConfig::Namada(config) => chains.node_b.value().chain_driver.runtime.block_on( + namada::query_consensus_states(config.rpc_addr, chains.client_id_b().value()), + )?, + _ => { + let grpc_address = chains + .node_b + .value() + .chain_driver + .grpc_address() + .as_str() + .parse() + .unwrap(); - let states = - chains - .node_b - .value() - .chain_driver - .runtime - .block_on(query_consensus_states( - chains.node_b.chain_id().value(), - &grpc_address, - QueryConsensusStatesRequest { - client_id: (*chains.client_id_b().value()).clone(), - pagination: Some(PageRequest::all()), - }, - ))?; + chains + .node_b + .value() + .chain_driver + .runtime + .block_on(query_consensus_states( + chains.node_b.chain_id().value(), + &grpc_address, + QueryConsensusStatesRequest { + client_id: (*chains.client_id_b().value()).clone(), + pagination: Some(PageRequest::all()), + }, + ))? + } + }; assert_eq( "did not find the expected number of consensus states", diff --git a/tools/integration-test/src/tests/denom_trace.rs b/tools/integration-test/src/tests/denom_trace.rs index 3c56efbdcb..50dbbd4aa8 100644 --- a/tools/integration-test/src/tests/denom_trace.rs +++ b/tools/integration-test/src/tests/denom_trace.rs @@ -40,6 +40,7 @@ impl BinaryChannelTest for IbcDenomTraceTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -83,7 +84,8 @@ impl BinaryChannelTest for IbcDenomTraceTest { assert_eq( "Denom returned by denom_trace query should be the same as denom_a", &denom_trace.base_denom, - &denom_a.value().as_str().to_string(), + // check the raw address + &denom_a.value().hash_only(), )?; Ok(()) diff --git a/tools/integration-test/src/tests/dynamic_gas_fee.rs b/tools/integration-test/src/tests/dynamic_gas_fee.rs index 3e30ec468d..950e8b9617 100644 --- a/tools/integration-test/src/tests/dynamic_gas_fee.rs +++ b/tools/integration-test/src/tests/dynamic_gas_fee.rs @@ -52,6 +52,7 @@ impl TestOverrides for DynamicGasTest { GasPrice::new(0.1, chain_config_a.gas_price.denom.clone()); chain_config_a.dynamic_gas_price = DynamicGasPrice::unsafe_new(false, 1.1, 0.6); } + ChainConfig::Namada(_) => {} } match &mut config.chains[1] { @@ -61,6 +62,7 @@ impl TestOverrides for DynamicGasTest { chain_config_b.dynamic_gas_price = DynamicGasPrice::unsafe_new(self.dynamic_gas_enabled, 1.1, 0.6); } + ChainConfig::Namada(_) => {} } } @@ -84,15 +86,38 @@ impl BinaryChannelTest for DynamicGasTest { let a_to_b_amount = 12345u64; let denom_a_to_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, )?; + let gas_denom_str_a = match relayer + .config + .chains + .first() + .ok_or_else(|| eyre!("chain configuration is empty"))? + { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.gas_price.denom.clone() + } + }; + + let gas_denom_str_b: String = match relayer + .config + .chains + .get(1) + .ok_or_else(|| eyre!("chain configuration is empty"))? + { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.gas_price.denom.clone() + } + }; + let gas_denom_a: MonoTagged = - MonoTagged::new(Denom::Base("stake".to_owned())); + MonoTagged::new(Denom::base(&gas_denom_str_a, &gas_denom_str_a)); let gas_denom_b: MonoTagged = - MonoTagged::new(Denom::Base("stake".to_owned())); + MonoTagged::new(Denom::base(&gas_denom_str_b, &gas_denom_str_b)); let balance_relayer_b_before = chains.node_b.chain_driver().query_balance( &chains.node_b.wallets().relayer().address(), @@ -148,6 +173,7 @@ impl BinaryChannelTest for DynamicGasTest { let denom_b = chains.node_b.denom(); let denom_b_to_a = derive_ibc_denom( + &chains.node_a.chain_driver().value().chain_type, &channel.port_a.as_ref(), &channel.channel_id_a.as_ref(), &denom_b, diff --git a/tools/integration-test/src/tests/error_events.rs b/tools/integration-test/src/tests/error_events.rs index 24602d0122..7e5d7172d0 100644 --- a/tools/integration-test/src/tests/error_events.rs +++ b/tools/integration-test/src/tests/error_events.rs @@ -3,6 +3,8 @@ use ibc_relayer_types::events::IbcEvent; use ibc_test_framework::prelude::*; use ibc_test_framework::relayer::transfer::build_transfer_message; +// TODO: Need to fix Namada and Namada event checking +#[cfg(not(feature = "namada"))] #[test] fn test_error_events() -> Result<(), Error> { run_binary_channel_test(&ErrorEventsTest) diff --git a/tools/integration-test/src/tests/fee/auto_forward_relayer.rs b/tools/integration-test/src/tests/fee/auto_forward_relayer.rs index ca120394a5..e5aad208ce 100644 --- a/tools/integration-test/src/tests/fee/auto_forward_relayer.rs +++ b/tools/integration-test/src/tests/fee/auto_forward_relayer.rs @@ -76,6 +76,7 @@ impl BinaryChannelTest for AutoForwardRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee/filter_fees.rs b/tools/integration-test/src/tests/fee/filter_fees.rs index 6113d98c1f..5c96cdaaf4 100644 --- a/tools/integration-test/src/tests/fee/filter_fees.rs +++ b/tools/integration-test/src/tests/fee/filter_fees.rs @@ -29,7 +29,7 @@ impl TestOverrides for FilterIncentivizedFeesRelayerTest { let packet_filter = PacketFilter::new(ChannelPolicy::default(), min_fees); for chain_config in config.chains.iter_mut() { match chain_config { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.packet_filter = packet_filter.clone(); } } @@ -98,6 +98,7 @@ impl BinaryChannelTest for FilterIncentivizedFeesRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -159,6 +160,7 @@ impl BinaryChannelTest for FilterIncentivizedFeesRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -198,7 +200,7 @@ impl TestOverrides for FilterByChannelIncentivizedFeesRelayerTest { let packet_filter = PacketFilter::new(ChannelPolicy::default(), min_fees); for chain_config in config.chains.iter_mut() { match chain_config { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.packet_filter = packet_filter.clone(); } } @@ -251,6 +253,7 @@ impl BinaryChannelTest for FilterByChannelIncentivizedFeesRelayerTest { let balance_a2 = balance_a1.clone() - send_amount - max(receive_fee + ack_fee, timeout_fee); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee/forward_relayer.rs b/tools/integration-test/src/tests/fee/forward_relayer.rs index daa5bcf317..ca91aef498 100644 --- a/tools/integration-test/src/tests/fee/forward_relayer.rs +++ b/tools/integration-test/src/tests/fee/forward_relayer.rs @@ -115,6 +115,7 @@ impl BinaryChannelTest for ForwardRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee/no_forward_relayer.rs b/tools/integration-test/src/tests/fee/no_forward_relayer.rs index 8b840640e8..13683f9cfe 100644 --- a/tools/integration-test/src/tests/fee/no_forward_relayer.rs +++ b/tools/integration-test/src/tests/fee/no_forward_relayer.rs @@ -93,6 +93,7 @@ impl BinaryChannelTest for NoForwardRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -179,6 +180,7 @@ impl BinaryChannelTest for InvalidForwardRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee/non_fee_channel.rs b/tools/integration-test/src/tests/fee/non_fee_channel.rs index b7b026ae3a..e2c8c44c6a 100644 --- a/tools/integration-test/src/tests/fee/non_fee_channel.rs +++ b/tools/integration-test/src/tests/fee/non_fee_channel.rs @@ -93,6 +93,7 @@ impl BinaryChannelTest for NonFeeChannelTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee/pay_fee_async.rs b/tools/integration-test/src/tests/fee/pay_fee_async.rs index 37c486c07d..4af93c556d 100644 --- a/tools/integration-test/src/tests/fee/pay_fee_async.rs +++ b/tools/integration-test/src/tests/fee/pay_fee_async.rs @@ -274,6 +274,7 @@ impl BinaryChannelTest for PayPacketFeeAsyncTest { } let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee/register_payee.rs b/tools/integration-test/src/tests/fee/register_payee.rs index 638800c846..9ddab19fe0 100644 --- a/tools/integration-test/src/tests/fee/register_payee.rs +++ b/tools/integration-test/src/tests/fee/register_payee.rs @@ -130,6 +130,7 @@ impl BinaryChannelTest for ForwardRelayerTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/fee_grant.rs b/tools/integration-test/src/tests/fee_grant.rs index f12e30a981..2a0a8aa272 100644 --- a/tools/integration-test/src/tests/fee_grant.rs +++ b/tools/integration-test/src/tests/fee_grant.rs @@ -42,7 +42,10 @@ impl BinaryChannelTest for FeeGrantTest { let denom_a = chains.node_a.denom(); let wallet_a = chains.node_a.wallets().user1().cloned(); let wallet_b = chains.node_b.wallets().user1().cloned(); - let fee_denom_a = MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let a_to_b_amount = 12345u64; let granter = chains @@ -70,6 +73,7 @@ impl BinaryChannelTest for FeeGrantTest { thread::sleep(Duration::from_secs(5)); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, @@ -81,10 +85,13 @@ impl BinaryChannelTest for FeeGrantTest { .first() .ok_or_else(|| eyre!("chain configuration is empty"))? { - ChainConfig::CosmosSdk(chain_config) => chain_config.gas_price.denom.clone(), + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.gas_price.denom.clone() + } }; - let gas_denom: MonoTagged = MonoTagged::new(Denom::Base(gas_denom_str)); + let gas_denom: MonoTagged = + MonoTagged::new(Denom::base(&gas_denom_str, &gas_denom_str)); let balance_user1_before = chains .node_a @@ -104,7 +111,7 @@ impl BinaryChannelTest for FeeGrantTest { .for_each(|chain_config| { if chain_config.id() == chains.node_a.chain_id().0 { match chain_config { - ChainConfig::CosmosSdk(c) => { + ChainConfig::CosmosSdk(c) | ChainConfig::Namada(c) => { c.fee_granter = Some("user2".to_owned()); } } @@ -185,7 +192,10 @@ impl BinaryChannelTest for NoFeeGrantTest { let wallet_a = chains.node_a.wallets().user1().cloned(); let wallet_a2 = chains.node_a.wallets().user2().cloned(); let wallet_b = chains.node_b.wallets().user1().cloned(); - let fee_denom_a = MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let a_to_b_amount = 12345u64; let granter = chains @@ -213,6 +223,7 @@ impl BinaryChannelTest for NoFeeGrantTest { thread::sleep(Duration::from_secs(5)); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, @@ -224,10 +235,13 @@ impl BinaryChannelTest for NoFeeGrantTest { .first() .ok_or_else(|| eyre!("chain configuration is empty"))? { - ChainConfig::CosmosSdk(chain_config) => chain_config.gas_price.denom.clone(), + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.gas_price.denom.clone() + } }; - let gas_denom: MonoTagged = MonoTagged::new(Denom::Base(gas_denom_str)); + let gas_denom: MonoTagged = + MonoTagged::new(Denom::base(&gas_denom_str, &gas_denom_str)); let balance_user1_before = chains .node_a diff --git a/tools/integration-test/src/tests/forward/forward_hop_transfer.rs b/tools/integration-test/src/tests/forward/forward_hop_transfer.rs index 931ceddd23..aa82260b45 100644 --- a/tools/integration-test/src/tests/forward/forward_hop_transfer.rs +++ b/tools/integration-test/src/tests/forward/forward_hop_transfer.rs @@ -67,24 +67,28 @@ impl NaryChannelTest<4> for IbcForwardHopTransferTest { let denom_a = connected_chains.node_a.denom(); let denom_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_c = derive_ibc_denom( + &node_c.chain_driver().value().chain_type, &channel_b_to_c.port_b.as_ref(), &channel_b_to_c.channel_id_b.as_ref(), &denom_b.as_ref(), )?; let denom_a_to_d = derive_ibc_denom( + &node_d.chain_driver().value().chain_type, &channel_c_to_d.port_b.as_ref(), &channel_c_to_d.channel_id_b.as_ref(), &denom_a_to_c.as_ref(), @@ -188,24 +192,28 @@ impl NaryChannelTest<4> for AtomicIbcForwardHopTransferTest { let denom_a = connected_chains.node_a.denom(); let denom_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_c = derive_ibc_denom( + &node_c.chain_driver().value().chain_type, &channel_b_to_c.port_b.as_ref(), &channel_b_to_c.channel_id_b.as_ref(), &denom_b.as_ref(), )?; let denom_a_to_d = derive_ibc_denom( + &node_d.chain_driver().value().chain_type, &channel_c_to_d.port_b.as_ref(), &channel_c_to_d.channel_id_b.as_ref(), &denom_a_to_c.as_ref(), diff --git a/tools/integration-test/src/tests/forward/forward_transfer.rs b/tools/integration-test/src/tests/forward/forward_transfer.rs index 65827fc0d6..b63277e58a 100644 --- a/tools/integration-test/src/tests/forward/forward_transfer.rs +++ b/tools/integration-test/src/tests/forward/forward_transfer.rs @@ -85,18 +85,21 @@ impl NaryChannelTest<3> for IbcForwardTransferTest { let denom_a = connected_chains.node_a.denom(); let denom_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_c = derive_ibc_denom( + &node_c.chain_driver().value().chain_type, &channel_b_to_c.port_b.as_ref(), &channel_b_to_c.channel_id_b.as_ref(), &denom_b.as_ref(), @@ -188,18 +191,21 @@ impl NaryChannelTest<3> for MisspelledMemoFieldsIbcForwardTransferTest { let denom_a = connected_chains.node_a.denom(); let denom_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_c = derive_ibc_denom( + &node_c.chain_driver().value().chain_type, &channel_b_to_c.port_b.as_ref(), &channel_b_to_c.channel_id_b.as_ref(), &denom_b.as_ref(), @@ -434,18 +440,21 @@ impl NaryChannelTest<3> for MisspelledMemoContentIbcForwardTransferTest { let denom_a = connected_chains.node_a.denom(); let denom_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, )?; let denom_a_to_c = derive_ibc_denom( + &node_c.chain_driver().value().chain_type, &channel_b_to_c.port_b.as_ref(), &channel_b_to_c.channel_id_b.as_ref(), &denom_b.as_ref(), diff --git a/tools/integration-test/src/tests/ica.rs b/tools/integration-test/src/tests/ica.rs index a6b8427a89..ee6d8a32f3 100644 --- a/tools/integration-test/src/tests/ica.rs +++ b/tools/integration-test/src/tests/ica.rs @@ -17,7 +17,7 @@ use ibc_relayer_types::timestamp::Timestamp; use ibc_relayer_types::tx_msg::Msg; use ibc_test_framework::chain::{ - config::add_allow_message_interchainaccounts, + config::cosmos::add_allow_message_interchainaccounts, ext::ica::{register_interchain_account, register_ordered_interchain_account}, }; use ibc_test_framework::prelude::*; @@ -70,7 +70,7 @@ impl TestOverrides for IcaFilterTestAllow { for chain in &mut config.chains { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.packet_filter = self.packet_filter.clone(); } } @@ -112,7 +112,7 @@ impl BinaryConnectionTest for IcaFilterTestAllow { .chain_driver() .query_interchain_account(&wallet.address(), &connection.connection_id_a.as_ref())?; - let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake")); + let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); chains.node_b.chain_driver().assert_eventual_wallet_amount( &ica_address.as_ref(), @@ -184,7 +184,7 @@ impl TestOverrides for IcaFilterTestDeny { for chain in &mut config.chains { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.packet_filter.channel_policy = ChannelPolicy::Deny(ChannelFilters::new(vec![( FilterPattern::Wildcard("ica*".parse().unwrap()), @@ -247,7 +247,18 @@ impl BinaryConnectionTest for ICACloseChannelTest { chains: ConnectedChains, connection: ConnectedConnection, ) -> Result<(), Error> { - let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake")); + let gas_denom_str = match relayer + .config + .chains + .first() + .ok_or_else(|| eyre!("chain configuration is empty"))? + { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { + chain_config.gas_price.denom.clone() + } + }; + let stake_denom: MonoTagged = + MonoTagged::new(Denom::base(&gas_denom_str, &gas_denom_str)); let (wallet, ica_address, controller_channel_id, controller_port_id) = relayer .with_supervisor(|| { // Register an interchain account on behalf of diff --git a/tools/integration-test/src/tests/ics20_filter/memo.rs b/tools/integration-test/src/tests/ics20_filter/memo.rs index 0ec207af37..ca696ec150 100644 --- a/tools/integration-test/src/tests/ics20_filter/memo.rs +++ b/tools/integration-test/src/tests/ics20_filter/memo.rs @@ -71,6 +71,7 @@ impl BinaryChannelTest for IbcMemoFilterTest { info!("Assert that the IBC transfer was filtered"); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/ics31.rs b/tools/integration-test/src/tests/ics31.rs index 33065dc091..54e7408e78 100644 --- a/tools/integration-test/src/tests/ics31.rs +++ b/tools/integration-test/src/tests/ics31.rs @@ -13,7 +13,7 @@ use ibc_relayer::config::{self, ModeConfig}; use ibc_test_framework::chain::{ cli::host_zone::register_host_zone, - config::{ + config::cosmos::{ set_crisis_denom, set_mint_mint_denom, set_staking_bond_denom, set_staking_max_entries, set_voting_period, }, @@ -101,6 +101,7 @@ impl BinaryChannelTest for ICS31Test { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/interchain_security/dynamic_gas_fee.rs b/tools/integration-test/src/tests/interchain_security/dynamic_gas_fee.rs index 3d2f217554..e45d3dfd78 100644 --- a/tools/integration-test/src/tests/interchain_security/dynamic_gas_fee.rs +++ b/tools/integration-test/src/tests/interchain_security/dynamic_gas_fee.rs @@ -80,7 +80,7 @@ impl TestOverrides for DynamicGasTest { update_relayer_config_for_consumer_chain(config); match &mut config.chains[0] { - ChainConfig::CosmosSdk(chain_config_a) => { + ChainConfig::CosmosSdk(chain_config_a) | ChainConfig::Namada(chain_config_a) => { chain_config_a.gas_price = GasPrice::new(0.3, chain_config_a.gas_price.denom.clone()); @@ -89,7 +89,7 @@ impl TestOverrides for DynamicGasTest { } match &mut config.chains[1] { - ChainConfig::CosmosSdk(chain_config_b) => { + ChainConfig::CosmosSdk(chain_config_b) | ChainConfig::Namada(chain_config_b) => { chain_config_b.gas_price = GasPrice::new(0.3, chain_config_b.gas_price.denom.clone()); @@ -121,15 +121,14 @@ impl BinaryChannelTest for DynamicGasTest { let a_to_b_amount = 12345u64; let denom_a_to_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, )?; - let gas_denom_a: MonoTagged = - MonoTagged::new(Denom::Base("stake".to_owned())); - let gas_denom_b: MonoTagged = - MonoTagged::new(Denom::Base("stake".to_owned())); + let gas_denom_a: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); + let gas_denom_b: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); let balance_relayer_b_before = chains.node_b.chain_driver().query_balance( &chains.node_b.wallets().relayer().address(), @@ -185,6 +184,7 @@ impl BinaryChannelTest for DynamicGasTest { let denom_b = chains.node_b.denom(); let denom_b_to_a = derive_ibc_denom( + &chains.node_a.chain_driver().value().chain_type, &channel.port_a.as_ref(), &channel.channel_id_a.as_ref(), &denom_b, diff --git a/tools/integration-test/src/tests/interchain_security/ica_ordered_channel.rs b/tools/integration-test/src/tests/interchain_security/ica_ordered_channel.rs index ade71f8132..563e83dcb7 100644 --- a/tools/integration-test/src/tests/interchain_security/ica_ordered_channel.rs +++ b/tools/integration-test/src/tests/interchain_security/ica_ordered_channel.rs @@ -17,7 +17,7 @@ use ibc_relayer_types::bigint::U256; use ibc_relayer_types::signer::Signer; use ibc_relayer_types::timestamp::Timestamp; use ibc_relayer_types::tx_msg::Msg; -use ibc_test_framework::chain::config::add_allow_message_interchainaccounts; +use ibc_test_framework::chain::config::cosmos::add_allow_message_interchainaccounts; use ibc_test_framework::chain::ext::ica::register_interchain_account; use ibc_test_framework::framework::binary::channel::run_binary_interchain_security_channel_test; use ibc_test_framework::prelude::*; @@ -99,7 +99,7 @@ impl BinaryChannelTest for IcaOrderedChannelTest { &channel.connection.connection_id_b.as_ref(), )?; - let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake")); + let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); chains.node_a.chain_driver().assert_eventual_wallet_amount( &ica_address.as_ref(), diff --git a/tools/integration-test/src/tests/interchain_security/ica_transfer.rs b/tools/integration-test/src/tests/interchain_security/ica_transfer.rs index 28d05cad91..046e6d56e0 100644 --- a/tools/integration-test/src/tests/interchain_security/ica_transfer.rs +++ b/tools/integration-test/src/tests/interchain_security/ica_transfer.rs @@ -11,7 +11,7 @@ use ibc_relayer_types::bigint::U256; use ibc_relayer_types::signer::Signer; use ibc_relayer_types::timestamp::Timestamp; use ibc_relayer_types::tx_msg::Msg; -use ibc_test_framework::chain::config::add_allow_message_interchainaccounts; +use ibc_test_framework::chain::config::cosmos::add_allow_message_interchainaccounts; use ibc_test_framework::chain::ext::ica::register_interchain_account; use ibc_test_framework::framework::binary::channel::run_binary_interchain_security_channel_test; use ibc_test_framework::prelude::*; @@ -72,7 +72,7 @@ impl BinaryChannelTest for InterchainSecurityIcaTransferTest { &channel.connection.connection_id_b.as_ref(), )?; - let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake")); + let stake_denom: MonoTagged = MonoTagged::new(Denom::base("stake", "stake")); chains.node_a.chain_driver().assert_eventual_wallet_amount( &ica_address.as_ref(), diff --git a/tools/integration-test/src/tests/interchain_security/icq.rs b/tools/integration-test/src/tests/interchain_security/icq.rs index 3c78fbac3e..82b336f722 100644 --- a/tools/integration-test/src/tests/interchain_security/icq.rs +++ b/tools/integration-test/src/tests/interchain_security/icq.rs @@ -10,7 +10,7 @@ //! then processed. use ibc_test_framework::chain::cli::host_zone::register_host_zone; -use ibc_test_framework::chain::config::{ +use ibc_test_framework::chain::config::cosmos::{ set_crisis_denom, set_mint_mint_denom, set_staking_bond_denom, set_staking_max_entries, set_voting_period, }; @@ -114,6 +114,7 @@ impl BinaryChannelTest for InterchainSecurityIcqTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/interchain_security/simple_transfer.rs b/tools/integration-test/src/tests/interchain_security/simple_transfer.rs index 05317917ed..1d6afed1e5 100644 --- a/tools/integration-test/src/tests/interchain_security/simple_transfer.rs +++ b/tools/integration-test/src/tests/interchain_security/simple_transfer.rs @@ -69,6 +69,7 @@ impl BinaryChannelTest for InterchainSecurityTransferTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/manual/simulation.rs b/tools/integration-test/src/tests/manual/simulation.rs index 30c801bfcf..827f4ba969 100644 --- a/tools/integration-test/src/tests/manual/simulation.rs +++ b/tools/integration-test/src/tests/manual/simulation.rs @@ -29,7 +29,7 @@ impl TestOverrides for SimulationTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.max_msg_num = MaxMsgNum::new(MAX_MSGS).unwrap(); } } diff --git a/tools/integration-test/src/tests/memo.rs b/tools/integration-test/src/tests/memo.rs index a44ee417cf..ad49db460b 100644 --- a/tools/integration-test/src/tests/memo.rs +++ b/tools/integration-test/src/tests/memo.rs @@ -6,6 +6,7 @@ use ibc_relayer::config::types::Memo; use ibc_relayer::config::ChainConfig; +use ibc_test_framework::util::namada::query_receive_tx_memo; use serde_json as json; use ibc_test_framework::prelude::*; @@ -35,7 +36,7 @@ impl TestOverrides for MemoTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.memo_prefix = self.memo.clone(); } } @@ -69,6 +70,7 @@ impl BinaryChannelTest for MemoTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -79,12 +81,7 @@ impl BinaryChannelTest for MemoTest { &denom_b.with_amount(a_to_b_amount).as_ref(), )?; - let tx_info = chains - .node_b - .chain_driver() - .query_recipient_transactions(&chains.node_b.wallets().user1().address())?; - - assert_tx_memo_equals(&tx_info, self.memo.as_str())?; + assert_tx_memo_equals(&chains, &channel, self.memo.as_str())?; Ok(()) } @@ -98,7 +95,7 @@ impl TestOverrides for MemoOverwriteTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.memo_prefix = self.memo.clone(); chain_config.memo_overwrite = Some(Memo::new(OVERWRITE_MEMO).unwrap()) } @@ -133,6 +130,7 @@ impl BinaryChannelTest for MemoOverwriteTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -143,18 +141,13 @@ impl BinaryChannelTest for MemoOverwriteTest { &denom_b.with_amount(a_to_b_amount).as_ref(), )?; - let tx_info = chains - .node_b - .chain_driver() - .query_recipient_transactions(&chains.node_b.wallets().user1().address())?; - - assert_tx_memo_equals(&tx_info, OVERWRITE_MEMO)?; + assert_tx_memo_equals(&chains, &channel, OVERWRITE_MEMO)?; Ok(()) } } -fn assert_tx_memo_equals(tx_info: &json::Value, expected_memo: &str) -> Result<(), Error> { +fn get_tx_memo(tx_info: &json::Value) -> Result { debug!("comparing memo field from json value {}", tx_info); let memo_field = &tx_info["txs"][0]["tx"]["body"]["memo"]; @@ -165,7 +158,40 @@ fn assert_tx_memo_equals(tx_info: &json::Value, expected_memo: &str) -> Result<( .as_str() .ok_or_else(|| eyre!("expect memo string field to be present in JSON"))?; - assert_eq!(memo_str, expected_memo); + Ok(memo_str.to_string()) +} + +fn assert_tx_memo_equals( + chains: &ConnectedChains, + channel: &ConnectedChannel, + expected_memo: &str, +) -> Result<(), Error> { + let memo = match chains.handle_b().config().expect("Config should exist") { + ChainConfig::Namada(config) => { + chains + .node_b + .chain_driver() + .value() + .runtime + .block_on(query_receive_tx_memo( + config.rpc_addr, + channel.port_a.value(), + channel.channel_id_a.value(), + channel.port_b.value(), + channel.channel_id_b.value(), + 1.into(), + ))? + } + _ => { + let tx_info = chains + .node_b + .chain_driver() + .query_recipient_transactions(&chains.node_b.wallets().user1().address())?; + + get_tx_memo(&tx_info)? + } + }; + assert_eq!(memo, expected_memo); Ok(()) } diff --git a/tools/integration-test/src/tests/mod.rs b/tools/integration-test/src/tests/mod.rs index 6fb6ac2a74..524334af78 100644 --- a/tools/integration-test/src/tests/mod.rs +++ b/tools/integration-test/src/tests/mod.rs @@ -10,23 +10,24 @@ pub mod client_expiration; pub mod client_filter; pub mod client_refresh; pub mod client_settings; -#[cfg(not(feature = "celestia"))] +#[cfg(not(any(feature = "celestia", feature = "namada")))] pub mod client_upgrade; pub mod connection_delay; pub mod consensus_states; pub mod denom_trace; pub mod error_events; pub mod execute_schedule; +#[cfg(not(feature = "namada"))] pub mod handshake_on_start; pub mod ics20_filter; pub mod memo; +#[cfg(not(feature = "namada"))] pub mod python; pub mod query_packet; -#[cfg(not(feature = "celestia"))] -pub mod sequence_filter; +#[cfg(not(feature = "namada"))] pub mod supervisor; pub mod tendermint; -#[cfg(not(feature = "celestia"))] +#[cfg(not(any(feature = "celestia")))] pub mod ternary_transfer; pub mod transfer; diff --git a/tools/integration-test/src/tests/ordered_channel.rs b/tools/integration-test/src/tests/ordered_channel.rs index 8f36e516c8..c3c2069053 100644 --- a/tools/integration-test/src/tests/ordered_channel.rs +++ b/tools/integration-test/src/tests/ordered_channel.rs @@ -96,6 +96,7 @@ impl BinaryChannelTest for OrderedChannelTest { sleep(Duration::from_secs(1)); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/ordered_channel_clear.rs b/tools/integration-test/src/tests/ordered_channel_clear.rs index 85484e42d1..5dc9fa2c2e 100644 --- a/tools/integration-test/src/tests/ordered_channel_clear.rs +++ b/tools/integration-test/src/tests/ordered_channel_clear.rs @@ -50,7 +50,7 @@ impl TestOverrides for OrderedChannelClearTest { { let chain_a = &mut config.chains[0]; match chain_a { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.sequential_batch_tx = self.sequential_batch_tx; } } @@ -58,7 +58,7 @@ impl TestOverrides for OrderedChannelClearTest { let chain_b = &mut config.chains[1]; match chain_b { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.sequential_batch_tx = self.sequential_batch_tx; } } @@ -155,6 +155,7 @@ impl BinaryChannelTest for OrderedChannelClearTest { sleep(Duration::from_secs(10)); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, @@ -193,7 +194,7 @@ impl TestOverrides for OrderedChannelClearEqualCLITest { { let chain_a = &mut config.chains[0]; match chain_a { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.sequential_batch_tx = true; chain_config.max_msg_num = MaxMsgNum::new(3).unwrap(); } @@ -202,7 +203,7 @@ impl TestOverrides for OrderedChannelClearEqualCLITest { let chain_b = &mut config.chains[1]; match chain_b { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.sequential_batch_tx = true; chain_config.max_msg_num = MaxMsgNum::new(3).unwrap(); } diff --git a/tools/integration-test/src/tests/python.rs b/tools/integration-test/src/tests/python.rs index 29d6457885..96c77e8ba1 100644 --- a/tools/integration-test/src/tests/python.rs +++ b/tools/integration-test/src/tests/python.rs @@ -10,7 +10,7 @@ impl TestOverrides for PythonTest { fn modify_relayer_config(&self, config: &mut Config) { for chain in config.chains.iter_mut() { match chain { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { // Modify the key store type to `Store::Test` so that the wallet // keys are stored to ~/.hermes/keys so that we can use them // with external relayer commands. diff --git a/tools/integration-test/src/tests/sequence_filter.rs b/tools/integration-test/src/tests/sequence_filter.rs index 177773bf4a..11d330d633 100644 --- a/tools/integration-test/src/tests/sequence_filter.rs +++ b/tools/integration-test/src/tests/sequence_filter.rs @@ -51,7 +51,7 @@ impl TestOverrides for FilterClearOnStartTest { excluded_sequences.insert(ChannelId::new(2), vec![2.into()]); let chain_a = &mut config.chains[0]; match chain_a { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.excluded_sequences = excluded_sequences; } } @@ -88,7 +88,7 @@ impl TestOverrides for FilterClearIntervalTest { excluded_sequences.insert(ChannelId::new(2), vec![2.into()]); let chain_a = &mut config.chains[0]; match chain_a { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.excluded_sequences = excluded_sequences; } } @@ -247,7 +247,7 @@ impl TestOverrides for StandardRelayingNoFilterTest { excluded_sequences.insert(ChannelId::new(2), vec![2.into()]); let chain_a = &mut config.chains[0]; match chain_a { - ChainConfig::CosmosSdk(chain_config) => { + ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { chain_config.excluded_sequences = excluded_sequences; } } diff --git a/tools/integration-test/src/tests/supervisor.rs b/tools/integration-test/src/tests/supervisor.rs index fd24c71551..45d05e35db 100644 --- a/tools/integration-test/src/tests/supervisor.rs +++ b/tools/integration-test/src/tests/supervisor.rs @@ -91,7 +91,12 @@ impl BinaryChainTest for SupervisorTest { let denom_a = chains.node_a.denom(); - let denom_b = derive_ibc_denom(&port_b.as_ref(), &channel_id_b.as_ref(), &denom_a)?; + let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, + &port_b.as_ref(), + &channel_id_b.as_ref(), + &denom_a, + )?; // Use the same wallet as the relayer to perform token transfer. // This will cause an account sequence mismatch error. @@ -193,9 +198,13 @@ impl BinaryChannelTest for SupervisorScanTest { channels: ConnectedChannel, ) -> Result<(), Error> { let denom_a = chains.node_a.denom(); - let fee_denom_a = MonoTagged::new(Denom::base(&config.native_tokens[0])); + let fee_denom_a = MonoTagged::new(Denom::base( + &config.native_tokens[0], + &config.native_tokens[0], + )); let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channels.port_b.as_ref(), &channels.channel_id_b.as_ref(), &denom_a, diff --git a/tools/integration-test/src/tests/tendermint/sequential.rs b/tools/integration-test/src/tests/tendermint/sequential.rs index be9d254873..82569e09ec 100644 --- a/tools/integration-test/src/tests/tendermint/sequential.rs +++ b/tools/integration-test/src/tests/tendermint/sequential.rs @@ -13,6 +13,8 @@ const TOTAL_MESSAGES: usize = MESSAGES_PER_BATCH * TOTAL_TRANSACTIONS; const BLOCK_TIME_MILLIS: u64 = 1000; const BLOCK_TIME: Duration = Duration::from_millis(BLOCK_TIME_MILLIS); +// TODO: Need batching transactions +#[cfg(not(feature = "namada"))] #[test] fn test_sequential_commit() -> Result<(), Error> { run_binary_channel_test(&SequentialCommitTest) @@ -22,11 +24,20 @@ pub struct SequentialCommitTest; impl TestOverrides for SequentialCommitTest { fn modify_node_config(&self, config: &mut toml::Value) -> Result<(), Error> { - config::set_timeout_commit(config, BLOCK_TIME)?; - config::set_timeout_propose(config, BLOCK_TIME)?; + let config = if let Some(config) = config.get_mut("ledger") { + // Namada + config + .get_mut("cometbft") + .ok_or_else(|| eyre!("expect cometbft section"))? + } else { + config + }; + + config::cosmos::set_timeout_commit(config, BLOCK_TIME)?; + config::cosmos::set_timeout_propose(config, BLOCK_TIME)?; // Enable priority mempool - config::set_mempool_version(config, "v1")?; + config::cosmos::set_mempool_version(config, "v1")?; Ok(()) } @@ -34,14 +45,14 @@ impl TestOverrides for SequentialCommitTest { fn modify_relayer_config(&self, config: &mut Config) { // Use sequential batching for chain A, and default parallel batching for chain B match &mut config.chains[0] { - ChainConfig::CosmosSdk(chain_config_a) => { + ChainConfig::CosmosSdk(chain_config_a) | ChainConfig::Namada(chain_config_a) => { chain_config_a.max_msg_num = MaxMsgNum::new(MESSAGES_PER_BATCH).unwrap(); chain_config_a.sequential_batch_tx = true; } }; match &mut config.chains[1] { - ChainConfig::CosmosSdk(chain_config_b) => { + ChainConfig::CosmosSdk(chain_config_b) | ChainConfig::Namada(chain_config_b) => { chain_config_b.max_msg_num = MaxMsgNum::new(MESSAGES_PER_BATCH).unwrap(); chain_config_b.sequential_batch_tx = false; } diff --git a/tools/integration-test/src/tests/ternary_transfer.rs b/tools/integration-test/src/tests/ternary_transfer.rs index 8302c9b8bd..e3324d3242 100644 --- a/tools/integration-test/src/tests/ternary_transfer.rs +++ b/tools/integration-test/src/tests/ternary_transfer.rs @@ -61,6 +61,7 @@ impl NaryChannelTest<3> for TernaryIbcTransferTest { )?; let denom_a_to_b = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_a_to_b.port_b.as_ref(), &channel_a_to_b.channel_id_b.as_ref(), &denom_a, @@ -92,6 +93,7 @@ impl NaryChannelTest<3> for TernaryIbcTransferTest { let channel_b_to_c = channels.channel_at::<1, 2>()?; let denom_a_to_c = derive_ibc_denom( + &node_c.chain_driver().value().chain_type, &channel_b_to_c.port_b.as_ref(), &channel_b_to_c.channel_id_b.as_ref(), &denom_a_to_b.as_ref(), @@ -129,6 +131,7 @@ impl NaryChannelTest<3> for TernaryIbcTransferTest { let channel_c_to_a = channels.channel_at::<2, 0>()?; let denom_a_to_c_to_a = derive_ibc_denom( + &node_b.chain_driver().value().chain_type, &channel_c_to_a.port_b.as_ref(), &channel_c_to_a.channel_id_b.as_ref(), &denom_a_to_c.as_ref(), diff --git a/tools/integration-test/src/tests/transfer.rs b/tools/integration-test/src/tests/transfer.rs index f117dc742f..7a0e4ae8ca 100644 --- a/tools/integration-test/src/tests/transfer.rs +++ b/tools/integration-test/src/tests/transfer.rs @@ -10,7 +10,7 @@ fn test_ibc_transfer() -> Result<(), Error> { Test that IBC token transfer can still work with a single chain that is connected to itself. */ -#[cfg(not(feature = "celestia"))] +#[cfg(not(any(feature = "celestia", feature = "namada")))] #[test] fn test_self_connected_ibc_transfer() -> Result<(), Error> { run_self_connected_binary_chain_test(&RunBinaryConnectionTest::new(&RunBinaryChannelTest::new( @@ -25,13 +25,13 @@ fn test_self_connected_ibc_transfer() -> Result<(), Error> { this behind the "experimental" feature flag so that normal developers are not obligated to understand how this test works yet. */ -#[cfg(not(feature = "celestia"))] +#[cfg(not(any(feature = "celestia", feature = "namada")))] #[test] fn test_nary_ibc_transfer() -> Result<(), Error> { run_binary_as_nary_channel_test(&IbcTransferTest) } -#[cfg(not(feature = "celestia"))] +#[cfg(not(any(feature = "celestia", feature = "namada")))] #[test] fn test_self_connected_nary_ibc_transfer() -> Result<(), Error> { run_self_connected_nary_chain_test(&RunNaryConnectionTest::new(&RunNaryChannelTest::new( @@ -69,7 +69,7 @@ impl BinaryChannelTest for IbcTransferTest { chains.chain_id_a(), chains.chain_id_b(), a_to_b_amount, - denom_a + denom_a, ); chains.node_a.chain_driver().ibc_transfer_token( @@ -81,14 +81,15 @@ impl BinaryChannelTest for IbcTransferTest { )?; let denom_b = derive_ibc_denom( + &chains.node_b.chain_driver().value().chain_type, &channel.port_b.as_ref(), &channel.channel_id_b.as_ref(), &denom_a, )?; info!( - "Waiting for user on chain B to receive IBC transferred amount of {}", - a_to_b_amount + "Waiting for user on chain B to receive IBC transferred amount of {} {}", + a_to_b_amount, denom_b, ); chains.node_a.chain_driver().assert_eventual_wallet_amount( @@ -115,10 +116,11 @@ impl BinaryChannelTest for IbcTransferTest { let b_to_a_amount = random_u128_range(500, a_to_b_amount); info!( - "Sending IBC transfer from chain {} to chain {} with amount of {}", + "Sending IBC transfer from chain {} to chain {} with amount of {} {}", chains.chain_id_b(), chains.chain_id_a(), b_to_a_amount, + denom_b, ); chains.node_b.chain_driver().ibc_transfer_token( @@ -129,6 +131,12 @@ impl BinaryChannelTest for IbcTransferTest { &denom_b.with_amount(b_to_a_amount).as_ref(), )?; + info!( + "Waiting for user on chain A to receive IBC transferred amount of {} {}", + b_to_a_amount, + balance_c.denom(), + ); + chains.node_b.chain_driver().assert_eventual_wallet_amount( &wallet_b.address(), &denom_b.with_amount(a_to_b_amount - b_to_a_amount).as_ref(), diff --git a/tools/test-framework/Cargo.toml b/tools/test-framework/Cargo.toml index 730d2d5892..a32b544e44 100644 --- a/tools/test-framework/Cargo.toml +++ b/tools/test-framework/Cargo.toml @@ -18,6 +18,9 @@ ibc-relayer-types = { workspace = true } ibc-relayer = { workspace = true } ibc-relayer-cli = { workspace = true } ibc-proto = { workspace = true, features = ["serde"] } +namada_ibc = { workspace = true } +namada_sdk = { workspace = true } +tendermint = { workspace = true } tendermint-rpc = { workspace = true, features = ["http-client", "websocket-client"] } color-eyre = { workspace = true } diff --git a/tools/test-framework/src/bootstrap/binary/chain.rs b/tools/test-framework/src/bootstrap/binary/chain.rs index 365c079e8c..750c56d794 100644 --- a/tools/test-framework/src/bootstrap/binary/chain.rs +++ b/tools/test-framework/src/bootstrap/binary/chain.rs @@ -67,6 +67,9 @@ pub fn bootstrap_chains_with_full_nodes( let registry = new_registry(config.clone()); + // Wait before spawning the chain handle + std::thread::sleep(Duration::from_secs(10)); + // Pass in unique closure expressions `||{}` as the first argument so that // the returned chains are considered different types by Rust. // See [`spawn_chain_handle`] for more details. @@ -211,7 +214,7 @@ pub fn add_key_to_chain_handle( chain: &Chain, wallet: &Wallet, ) -> Result<(), Error> { - let res = chain.add_key(wallet.id.0.clone(), wallet.key.clone().into()); + let res = chain.add_key(wallet.id.0.clone(), wallet.key.clone()); // Ignore error if chain handle already have the given key match res { diff --git a/tools/test-framework/src/bootstrap/consumer.rs b/tools/test-framework/src/bootstrap/consumer.rs index 6c85595331..830ea104de 100644 --- a/tools/test-framework/src/bootstrap/consumer.rs +++ b/tools/test-framework/src/bootstrap/consumer.rs @@ -5,6 +5,7 @@ use eyre::eyre; use std::sync::{Arc, RwLock}; use std::thread; use std::time::Duration; +use toml; use tracing::info; use crate::chain::builder::ChainBuilder; @@ -23,9 +24,9 @@ pub fn bootstrap_consumer_node( chain_number: usize, provider_chain_driver: &ChainDriver, ) -> Result { - let stake_denom = Denom::base("stake"); + let stake_denom = Denom::base("stake", "stake"); - let denom = Denom::base("samoleans"); + let denom = Denom::base("samoleans", "samoleans"); let initial_amount = random_u128_range(1_000_000_000_000_000_000, 2_000_000_000_000_000_000); @@ -71,34 +72,34 @@ pub fn bootstrap_consumer_node( } ]); chain_driver.update_genesis_file("genesis.json", |genesis| { - config::set_soft_opt_out_threshold(genesis, "0.05")?; - config::consensus_params_max_gas(genesis, "3000000")?; - config::globalfee_minimum_gas_prices(genesis, globalfee_minimum_gas)?; - config::set_retry_delay_period(genesis, "100s")?; + config::cosmos::set_soft_opt_out_threshold(genesis, "0.05")?; + config::cosmos::consensus_params_max_gas(genesis, "3000000")?; + config::cosmos::globalfee_minimum_gas_prices(genesis, globalfee_minimum_gas)?; + config::cosmos::set_retry_delay_period(genesis, "100s")?; Ok(()) })?; let log_level = std::env::var("CHAIN_LOG_LEVEL").unwrap_or_else(|_| "info".to_string()); - chain_driver.update_chain_config("config.toml", |config| { - config::set_log_level(config, &log_level)?; - config::set_rpc_port(config, chain_driver.rpc_port)?; - config::set_p2p_port(config, chain_driver.p2p_port)?; - config::set_pprof_port(config, chain_driver.pprof_port)?; - config::set_timeout_commit(config, Duration::from_secs(1))?; - config::set_timeout_propose(config, Duration::from_secs(1))?; - config::set_mode(config, "validator")?; + chain_driver.update_chain_config("config/config.toml", |config| { + config::cosmos::set_log_level(config, &log_level)?; + config::cosmos::set_rpc_port(config, chain_driver.rpc_port)?; + config::cosmos::set_p2p_port(config, chain_driver.p2p_port)?; + config::cosmos::set_pprof_port(config, chain_driver.pprof_port)?; + config::cosmos::set_timeout_commit(config, Duration::from_secs(1))?; + config::cosmos::set_timeout_propose(config, Duration::from_secs(1))?; + config::cosmos::set_mode(config, "validator")?; config_modifier(config)?; Ok(()) })?; - chain_driver.update_chain_config("app.toml", |config| { - config::set_grpc_port(config, chain_driver.grpc_port)?; - config::disable_grpc_web(config)?; - config::disable_api(config)?; - config::set_minimum_gas_price(config, "0stake")?; + chain_driver.update_chain_config("config/app.toml", |config| { + config::cosmos::set_grpc_port(config, chain_driver.grpc_port)?; + config::cosmos::disable_grpc_web(config)?; + config::cosmos::disable_api(config)?; + config::cosmos::set_minimum_gas_price(config, "0stake")?; Ok(()) })?; diff --git a/tools/test-framework/src/bootstrap/mod.rs b/tools/test-framework/src/bootstrap/mod.rs index 17216d9455..b31132f5b6 100644 --- a/tools/test-framework/src/bootstrap/mod.rs +++ b/tools/test-framework/src/bootstrap/mod.rs @@ -14,5 +14,6 @@ pub mod binary; pub mod consumer; pub mod init; +pub mod namada; pub mod nary; pub mod single; diff --git a/tools/test-framework/src/bootstrap/namada.rs b/tools/test-framework/src/bootstrap/namada.rs new file mode 100644 index 0000000000..91759881ad --- /dev/null +++ b/tools/test-framework/src/bootstrap/namada.rs @@ -0,0 +1,338 @@ +/*! + Helper functions for bootstrapping a single full node. +*/ +use core::time::Duration; +use eyre::eyre; +use std::env; +use std::path::PathBuf; +use std::sync::{Arc, RwLock}; +use toml; + +use ibc_relayer::chain::namada::wallet::CliWalletUtils; +use ibc_relayer::keyring::{KeyRing, NamadaKeyPair, Store}; +use ibc_relayer_types::core::ics24_host::identifier::ChainId; + +use crate::chain::builder::ChainBuilder; +use crate::chain::config; +use crate::chain::exec::{simple_exec, simple_exec_with_envs}; +use crate::chain::ext::bootstrap::ChainBootstrapMethodsExt; +use crate::error::Error; +use crate::ibc::denom::Denom; +use crate::prelude::{TestWallets, Wallet}; +use crate::types::single::node::FullNode; +use crate::util::namada::get_namada_denom_address; + +use std::fs; +use std::process::{Command, Stdio}; +use std::str; +use std::thread::sleep; + +use crate::types::process::ChildProcess; +use crate::util::file::pipe_to_file; + +/** + Bootstrap a single Namada full node with the provided [`ChainBuilder`] and + a prefix for the chain ID. + + The bootstrap function follows the commands and configurations done in the + the setup-namada-single-node script found in the scripts/ directory. +*/ +pub fn bootstrap_namada_node( + builder: &ChainBuilder, + prefix: &str, + use_random_id: bool, + config_modifier: impl FnOnce(&mut toml::Value) -> Result<(), Error>, + _genesis_modifier: impl FnOnce(&mut serde_json::Value) -> Result<(), Error>, + parameters_modifier: impl FnOnce(&mut toml::Value) -> Result<(), Error>, + chain_number: usize, +) -> Result { + let namada_repo_path = env::var("NAMADA_REPO_PATH") + .map_err(|_| Error::generic(eyre!("missing environment variable `NAMADA_REPO_PATH")))?; + let chain_driver = builder.new_chain(prefix, use_random_id, chain_number)?; + let home_path = &chain_driver.home_path; + let templates_path = &format!("{home_path}/templates"); + fs::create_dir_all(templates_path)?; + + // Copy templates + let copy_loop = format!("for file in {namada_repo_path}/genesis/localnet/*.toml; do cp \"$file\" {templates_path}; done"); + simple_exec("namada", "sh", &["-c", ©_loop])?; + + chain_driver.update_chain_config("templates/parameters.toml", |parameters| { + config::namada::set_default_mint_limit(parameters, i64::MAX)?; + config::namada::set_epochs_per_year(parameters, 31536)?; + config::namada::set_default_per_epoch_throughput_limit(parameters, i64::MAX)?; + + Ok(()) + })?; + + let pre_genesis_path = &format!("{home_path}/pre-genesis"); + fs::create_dir_all(pre_genesis_path)?; + + // Copy pre-genesis + let copy_loop = format!("for file in {namada_repo_path}/genesis/localnet/src/pre-genesis/*; do cp \"$file\" {pre_genesis_path}; done"); + simple_exec("namada", "sh", &["-c", ©_loop])?; + simple_exec( + "namada", + "cp", + &[ + "-r", + &format!("{namada_repo_path}/genesis/localnet/src/pre-genesis/validator-0"), + pre_genesis_path, + ], + )?; + + let genesis_path = &format!("{home_path}/genesis"); + fs::create_dir_all(genesis_path)?; + + let wasm_checksum = &format!("{namada_repo_path}/wasm/checksums.json"); + + // Init network + let output = simple_exec_with_envs( + "namada", + "namadac", + &[ + "utils", + "init-network", + "--chain-prefix", + &chain_driver.chain_id.to_string(), + "--genesis-time", + "2023-01-01T00:00:00Z", + "--templates-path", + templates_path, + "--wasm-checksums-path", + wasm_checksum, + "--archive-dir", + genesis_path, + ], + &[("NAMADA_BASE_DIR", home_path)], + )?; + + let chain_id = extract_chain_id(output.stdout)?; + + let validator_base_dir = &format!("{home_path}/setup/validator-0"); + let pre_genesis_path = &format!("{home_path}/pre-genesis/validator-0"); + + simple_exec_with_envs( + &chain_id, + "namadac", + &[ + "--base-dir", + validator_base_dir, + "utils", + "join-network", + "--chain-id", + &chain_id, + "--genesis-validator", + "validator-0", + "--pre-genesis-path", + pre_genesis_path, + "--dont-prefetch-wasm", + ], + &[("NAMADA_NETWORK_CONFIGS_DIR", genesis_path)], + )?; + + let chain_dir = &format!("{home_path}/{chain_id}"); + simple_exec("namada", "rm", &["-rf", chain_dir])?; + + simple_exec_with_envs( + &chain_id, + "namadac", + &[ + "--base-dir", + home_path, + "utils", + "join-network", + "--chain-id", + &chain_id, + "--dont-prefetch-wasm", + ], + &[("NAMADA_NETWORK_CONFIGS_DIR", genesis_path)], + )?; + + let dst_cp = &format!("{home_path}/setup/validator-0/{chain_id}/wasm/"); + + // Copy wasm + let copy_loop = + format!("for file in {namada_repo_path}/wasm/*.wasm; do cp \"$file\" {dst_cp}; done"); + simple_exec("namada", "sh", &["-c", ©_loop])?; + + let config_path = format!("{home_path}/setup/validator-0/{chain_id}/config.toml"); + + chain_driver.update_chain_config(&config_path, |config| { + config::namada::set_rpc_port(config, chain_driver.rpc_port)?; + config::namada::set_p2p_port(config, chain_driver.p2p_port)?; + config::namada::set_proxy_app_port(config, chain_driver.pprof_port)?; + config::namada::set_block_cache_bytes(config, 268435456)?; + + config_modifier(config)?; + + Ok(()) + })?; + + let parameters_path = format!("{home_path}/setup/validator-0/{chain_id}/parameters.toml"); + + chain_driver.update_chain_config(¶meters_path, |parameters| { + config::namada::set_pipeline_len(parameters, 2000)?; + + parameters_modifier(parameters)?; + + Ok(()) + })?; + + let base_args = ["--base-dir", validator_base_dir, "ledger", "run"]; + + let args: Vec<&str> = base_args.to_vec(); + + //let mut child = Command::new(&chain_driver.command_path) + let mut child = Command::new("namadan") + .args(&args) + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn()?; + + let stdout = child + .stdout + .take() + .ok_or_else(|| eyre!("expected stdout to be present in child process"))?; + + let stderr = child + .stderr + .take() + .ok_or_else(|| eyre!("expected stderr to be present in child process"))?; + + let stderr_path = format!("{home_path}/stdout.log"); + let stdout_path = format!("{home_path}/stderr.log"); + + pipe_to_file(stdout, &stdout_path)?; + pipe_to_file(stderr, &stderr_path)?; + + // Wait for a while and check if the child process exited immediately. + // If so, return error since we expect the full node to be running in the background. + + sleep(Duration::from_millis(1000)); + + let status = child + .try_wait() + .map_err(|e| eyre!("error try waiting for child status: {}", e))?; + + let process = match status { + None => ChildProcess::new(child), + Some(status) => { + let stdout_output = fs::read_to_string(stdout_path)?; + let stderr_output = fs::read_to_string(stderr_path)?; + + return Err(eyre!( + "expected full node process to be running, but it exited immediately with exit status {} and output: {}\n{}", + status, + stdout_output, + stderr_output, + ).into()); + } + }; + + let ks_folder = Some(format!("{}/hermes_keyring", builder.base_store_dir).into()); + + let albert_key = add_namada_key(home_path, &chain_id, "albert-key", "albert", &ks_folder)?; + let bertha_key = add_namada_key(home_path, &chain_id, "bertha-key", "bertha", &ks_folder)?; + let christel_key = + add_namada_key(home_path, &chain_id, "christel-key", "christel", &ks_folder)?; + let daewon_key = add_namada_key(home_path, &chain_id, "daewon", "daewon", &ks_folder)?; + + let albert = Wallet::new_namada( + "albert".to_string(), + albert_key.address.to_string(), + albert_key, + ); + let bertha = Wallet::new_namada( + "bertha".to_string(), + bertha_key.address.to_string(), + bertha_key, + ); + let christel = Wallet::new_namada( + "christel".to_string(), + christel_key.address.to_string(), + christel_key, + ); + let daewon = Wallet::new_namada( + "daewon".to_string(), + daewon_key.address.to_string(), + daewon_key, + ); + + let wallets = TestWallets { + validator: albert, + relayer: bertha, + user1: christel, + user2: daewon, + }; + + sleep(Duration::from_secs(10)); + + let mut updated_chain_driver = chain_driver.clone(); + updated_chain_driver.chain_id = ChainId::from_string(&chain_id); + + let denom_str = get_namada_denom_address(&chain_id, home_path, "nam")?; + let denom = Denom::base("nam", &denom_str); + + let node = FullNode { + chain_driver: updated_chain_driver, + denom, + wallets, + process: Arc::new(RwLock::new(process)), + }; + + Ok(node) +} + +fn extract_chain_id(output: String) -> Result { + let words: Vec<&str> = output.split_whitespace().collect(); + + if let Some(derived_index) = words.iter().position(|&w| w == "Derived") { + if let Some(&chain_id) = words.get(derived_index + 3) { + return Ok(chain_id.to_owned()); + } + return Err(Error::generic(eyre!( + "chain id is not 3 words after `Derived`: {output}" + ))); + } + Err(Error::generic(eyre!( + "could not find `Derived` in output: {output}" + ))) +} + +fn add_namada_key( + home_path: &str, + chain_id: &str, + key_name: &str, + address_name: &str, + ks_folder: &Option, +) -> Result { + let chain_id = ChainId::from_string(chain_id); + let mut keyring = KeyRing::new_namada(Store::Test, &chain_id, ks_folder) + .map_err(|e| Error::generic(eyre!("error creating keyring: {e}")))?; + + let key_file: PathBuf = format!("{home_path}/{chain_id}").into(); + + let mut wallet = CliWalletUtils::new(key_file.to_path_buf()); + wallet + .load() + .map_err(|e| eyre!("error loading Namada wallet: {e}"))?; + + let secret_key = wallet + .find_secret_key(key_name, None) + .map_err(|e| eyre!("error loading the key from Namada wallet: {e}"))?; + let address = wallet + .find_address(address_name) + .ok_or_else(|| eyre!("error loading the address from Namada wallet"))?; + let namada_key = NamadaKeyPair { + alias: address_name.to_string(), + address: address.into_owned(), + secret_key: secret_key.clone(), + }; + keyring + .add_key(address_name, namada_key.clone()) + .map_err(|e| Error::generic(eyre!("error adding Namada key: {e}")))?; + + Ok(namada_key) +} diff --git a/tools/test-framework/src/bootstrap/single.rs b/tools/test-framework/src/bootstrap/single.rs index 508d0b28ba..5f81d17cbe 100644 --- a/tools/test-framework/src/bootstrap/single.rs +++ b/tools/test-framework/src/bootstrap/single.rs @@ -46,12 +46,13 @@ pub fn bootstrap_single_node( ) -> Result { let native_token_number = chain_number % builder.native_tokens.len(); let native_token = &builder.native_tokens[native_token_number]; - let native_denom = Denom::base(native_token); + let native_denom = Denom::base(native_token, native_token); let denom = if use_random_id { - Denom::base(&format!("coin{:x}", random_u32())) + let random_coin = format!("coin{:x}", random_u32()); + Denom::base(&random_coin, &random_coin) } else { - Denom::base("samoleans") + Denom::base("samoleans", "samoleans") }; // Evmos requires of at least 1_000_000_000_000_000_000 or else there will be the @@ -95,15 +96,15 @@ pub fn bootstrap_single_node( let log_level = std::env::var("CHAIN_LOG_LEVEL").unwrap_or_else(|_| "info".to_string()); - chain_driver.update_chain_config("config.toml", |config| { - config::set_log_level(config, &log_level)?; - config::set_rpc_port(config, chain_driver.rpc_port)?; - config::set_p2p_port(config, chain_driver.p2p_port)?; - config::set_pprof_port(config, chain_driver.pprof_port)?; - config::set_timeout_commit(config, Duration::from_secs(1))?; - config::set_timeout_propose(config, Duration::from_secs(1))?; - config::set_mode(config, "validator")?; - config::set_indexer(config, "kv")?; + chain_driver.update_chain_config("config/config.toml", |config| { + config::cosmos::set_log_level(config, &log_level)?; + config::cosmos::set_rpc_port(config, chain_driver.rpc_port)?; + config::cosmos::set_p2p_port(config, chain_driver.p2p_port)?; + config::cosmos::set_pprof_port(config, chain_driver.pprof_port)?; + config::cosmos::set_timeout_commit(config, Duration::from_secs(1))?; + config::cosmos::set_timeout_propose(config, Duration::from_secs(1))?; + config::cosmos::set_mode(config, "validator")?; + config::cosmos::set_indexer(config, "kv")?; config_modifier(config)?; @@ -111,12 +112,12 @@ pub fn bootstrap_single_node( })?; let minimum_gas = format!("0{}", native_token); - chain_driver.update_chain_config("app.toml", |config| { - config::set_grpc_port(config, chain_driver.grpc_port)?; - config::enable_grpc(config)?; - config::disable_grpc_web(config)?; - config::disable_api(config)?; - config::set_minimum_gas_price(config, &minimum_gas)?; + chain_driver.update_chain_config("config/app.toml", |config| { + config::cosmos::set_grpc_port(config, chain_driver.grpc_port)?; + config::cosmos::enable_grpc(config)?; + config::cosmos::disable_grpc_web(config)?; + config::cosmos::disable_api(config)?; + config::cosmos::set_minimum_gas_price(config, &minimum_gas)?; Ok(()) })?; diff --git a/tools/test-framework/src/chain/chain_type.rs b/tools/test-framework/src/chain/chain_type.rs index 1eba905087..e7806f6ca2 100644 --- a/tools/test-framework/src/chain/chain_type.rs +++ b/tools/test-framework/src/chain/chain_type.rs @@ -8,6 +8,7 @@ use crate::util::random::{random_u32, random_unused_tcp_port}; const COSMOS_HD_PATH: &str = "m/44'/118'/0'/0/0"; const EVMOS_HD_PATH: &str = "m/44'/60'/0'/0/0"; const PROVENANCE_HD_PATH: &str = "m/44'/505'/0'/0/0"; +const NAMADA_HD_PATH: &str = "m/44'/877'/0'/0'/0'"; #[derive(Clone, Debug)] pub enum ChainType { @@ -16,6 +17,7 @@ pub enum ChainType { Evmos, Provenance, Injective, + Namada, } impl ChainType { @@ -24,6 +26,7 @@ impl ChainType { Self::Cosmos | Self::Osmosis => COSMOS_HD_PATH, Self::Evmos | Self::Injective => EVMOS_HD_PATH, Self::Provenance => PROVENANCE_HD_PATH, + Self::Namada => NAMADA_HD_PATH, } } @@ -46,6 +49,7 @@ impl ChainType { Self::Injective => ChainId::from_string(&format!("injective-{prefix}")), Self::Evmos => ChainId::from_string(&format!("evmos_9000-{prefix}")), Self::Provenance => ChainId::from_string(&format!("pio-mainnet-{prefix}")), + Self::Namada => ChainId::from_string(&format!("namada-{prefix}")), } } @@ -54,7 +58,7 @@ impl ChainType { let mut res = vec![]; let json_rpc_port = random_unused_tcp_port(); match self { - Self::Cosmos | Self::Injective | Self::Provenance => {} + Self::Cosmos | Self::Injective | Self::Provenance | Self::Namada => {} Self::Osmosis => { res.push("--reject-config-defaults".to_owned()); } @@ -70,7 +74,7 @@ impl ChainType { pub fn extra_add_genesis_account_args(&self, chain_id: &ChainId) -> Vec { let mut res = vec![]; match self { - Self::Cosmos | Self::Osmosis | Self::Evmos | Self::Provenance => {} + Self::Cosmos | Self::Osmosis | Self::Evmos | Self::Provenance | Self::Namada => {} Self::Injective => { res.push("--chain-id".to_owned()); res.push(format!("{chain_id}")); @@ -81,7 +85,9 @@ impl ChainType { pub fn address_type(&self) -> AddressType { match self { - Self::Cosmos | Self::Osmosis | Self::Provenance => AddressType::default(), + Self::Cosmos | Self::Osmosis | Self::Provenance | Self::Namada => { + AddressType::default() + } Self::Evmos => AddressType::Ethermint { pk_type: "/ethermint.crypto.v1.ethsecp256k1.PubKey".to_string(), }, @@ -101,6 +107,7 @@ impl FromStr for ChainType { name if name.contains("injectived") => Ok(ChainType::Injective), name if name.contains("provenanced") => Ok(ChainType::Provenance), name if name.contains("osmosisd") => Ok(ChainType::Osmosis), + name if name.contains("namada") => Ok(ChainType::Namada), _ => Ok(ChainType::Cosmos), } } diff --git a/tools/test-framework/src/chain/cli/query.rs b/tools/test-framework/src/chain/cli/query.rs index 5bfb0801b5..9eec5c51d0 100644 --- a/tools/test-framework/src/chain/cli/query.rs +++ b/tools/test-framework/src/chain/cli/query.rs @@ -8,6 +8,7 @@ use tracing::debug; use crate::chain::exec::simple_exec; use crate::error::{handle_generic_error, Error}; +use crate::prelude::*; pub fn query_balance( chain_id: &str, @@ -102,6 +103,59 @@ pub fn query_balance( } } +pub fn query_namada_balance( + chain_id: &str, + _command_path: &str, + home_path: &str, + denom: &Denom, + wallet_id: &str, + rpc_listen_address: &str, +) -> Result { + let output = simple_exec( + chain_id, + //command_path, + "namadac", + &[ + "--base-dir", + home_path, + "balance", + "--owner", + wallet_id, + "--token", + &denom.hash_only(), + "--node", + rpc_listen_address, + ], + )?; + + let words: Vec<&str> = output.stdout.split_whitespace().collect(); + let raw_addr = &format!("{}:", denom.hash_only()); + + if let Some(derived_index) = words.iter().position(|&w| w.contains(raw_addr)) { + if let Some(&amount_str) = words.get(derived_index + 1) { + return Amount::from_str(amount_str).map_err(handle_generic_error); + } + Err(Error::generic(eyre!( + "chain id is not 1 words after `{raw_addr}`: raw output `{}` split output `{words:#?}`", + output.stdout + ))) + } else { + let denom_display_name = &format!("{}:", denom.namada_display_name()); + if let Some(derived_index) = words.iter().position(|&w| w.contains(denom_display_name)) { + if let Some(&amount_str) = words.get(derived_index + 1) { + return Amount::from_str(amount_str).map_err(handle_generic_error); + } + Err(Error::generic(eyre!( + "chain id is not 1 words after `{denom_display_name}`: raw output `{}` split output `{words:#?}`", + output.stdout + ))) + } else { + debug!("Denom `{denom_display_name}` not found when querying for balance, will return 0{denom}"); + Ok(Amount::from_str("0").map_err(handle_generic_error)?) + } + } +} + /** Query for the transactions related to a wallet on `Chain` receiving token transfer from others. diff --git a/tools/test-framework/src/chain/config.rs b/tools/test-framework/src/chain/config/cosmos.rs similarity index 100% rename from tools/test-framework/src/chain/config.rs rename to tools/test-framework/src/chain/config/cosmos.rs diff --git a/tools/test-framework/src/chain/config/mod.rs b/tools/test-framework/src/chain/config/mod.rs new file mode 100644 index 0000000000..5cffe3a80f --- /dev/null +++ b/tools/test-framework/src/chain/config/mod.rs @@ -0,0 +1,2 @@ +pub mod cosmos; +pub mod namada; diff --git a/tools/test-framework/src/chain/config/namada.rs b/tools/test-framework/src/chain/config/namada.rs new file mode 100644 index 0000000000..960e620a07 --- /dev/null +++ b/tools/test-framework/src/chain/config/namada.rs @@ -0,0 +1,144 @@ +use eyre::{eyre, Report as Error}; +use toml::Value; + +/// Set the `rpc` field in the full node config. +pub fn set_rpc_port(config: &mut Value, port: u16) -> Result<(), Error> { + config + .get_mut("ledger") + .ok_or_else(|| eyre!("expect ledger section"))? + .get_mut("cometbft") + .ok_or_else(|| eyre!("expect cometbft section"))? + .get_mut("rpc") + .ok_or_else(|| eyre!("expect cometbft rpc"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "laddr".to_string(), + format!("tcp://0.0.0.0:{}", port).into(), + ); + + Ok(()) +} + +/// Set the `p2p` field in the full node config. +pub fn set_p2p_port(config: &mut Value, port: u16) -> Result<(), Error> { + config + .get_mut("ledger") + .ok_or_else(|| eyre!("expect ledger section"))? + .get_mut("cometbft") + .ok_or_else(|| eyre!("expect cometbft section"))? + .get_mut("p2p") + .ok_or_else(|| eyre!("expect cometbft rpc"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "laddr".to_string(), + format!("tcp://0.0.0.0:{}", port).into(), + ); + + Ok(()) +} + +/// Set the `p2p` field in the full node config. +pub fn set_proxy_app_port(config: &mut Value, port: u16) -> Result<(), Error> { + config + .get_mut("ledger") + .ok_or_else(|| eyre!("expect ledger section"))? + .get_mut("cometbft") + .ok_or_else(|| eyre!("expect cometbft section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "proxy_app".to_string(), + format!("tcp://0.0.0.0:{}", port).into(), + ); + + Ok(()) +} + +/// Set the `p2p` field in the full node config. +pub fn set_block_cache_bytes(config: &mut Value, block_cache_bytes: i64) -> Result<(), Error> { + config + .get_mut("ledger") + .ok_or_else(|| eyre!("expect ledger section"))? + .get_mut("shell") + .ok_or_else(|| eyre!("expect shell section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "block_cache_bytes".to_string(), + Value::Integer(block_cache_bytes), + ); + + Ok(()) +} + +pub fn set_unbonding_len(parameters: &mut Value, unbonding_len: i64) -> Result<(), Error> { + parameters + .get_mut("pos_params") + .ok_or_else(|| eyre!("expect pos_params section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert("unbonding_len".to_string(), Value::Integer(unbonding_len)); + + Ok(()) +} + +pub fn set_pipeline_len(parameters: &mut Value, pipeline_len: i64) -> Result<(), Error> { + parameters + .get_mut("pos_params") + .ok_or_else(|| eyre!("expect pos_params section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert("pipeline_len".to_string(), Value::Integer(pipeline_len)); + + Ok(()) +} + +pub fn set_default_mint_limit( + parameters: &mut Value, + default_mint_limit: i64, +) -> Result<(), Error> { + parameters + .get_mut("ibc_params") + .ok_or_else(|| eyre!("expect ibc_params section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "default_mint_limit".to_string(), + Value::String(default_mint_limit.to_string()), + ); + + Ok(()) +} + +pub fn set_default_per_epoch_throughput_limit( + parameters: &mut Value, + default_per_epoch_throughput_limit: i64, +) -> Result<(), Error> { + parameters + .get_mut("ibc_params") + .ok_or_else(|| eyre!("expect ibc_params section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "default_per_epoch_throughput_limit".to_string(), + Value::String(default_per_epoch_throughput_limit.to_string()), + ); + + Ok(()) +} + +pub fn set_epochs_per_year(parameters: &mut Value, epochs_per_year: i64) -> Result<(), Error> { + parameters + .get_mut("parameters") + .ok_or_else(|| eyre!("expect parameters section"))? + .as_table_mut() + .ok_or_else(|| eyre!("expect object"))? + .insert( + "epochs_per_year".to_string(), + Value::Integer(epochs_per_year), + ); + + Ok(()) +} diff --git a/tools/test-framework/src/chain/driver.rs b/tools/test-framework/src/chain/driver.rs index 4b3414c554..1b4950d8a0 100644 --- a/tools/test-framework/src/chain/driver.rs +++ b/tools/test-framework/src/chain/driver.rs @@ -23,6 +23,8 @@ use crate::types::env::{EnvWriter, ExportEnv}; use crate::types::wallet::WalletAddress; use crate::util::retry::assert_eventually_succeed; +use super::cli::query::query_namada_balance; + /** Number of times (seconds) to try and query a wallet to reach the target amount, as used by [`assert_eventual_wallet_amount`]. @@ -174,7 +176,11 @@ impl ChainDriver { as it requires the `"tcp://"` scheme. */ pub fn rpc_listen_address(&self) -> String { - format!("tcp://localhost:{}", self.rpc_port) + if self.command_path == "namada" { + format!("http://localhost:{}", self.rpc_port) + } else { + format!("tcp://localhost:{}", self.rpc_port) + } } /** @@ -192,13 +198,23 @@ impl ChainDriver { Query for the balances for a given wallet address and denomination */ pub fn query_balance(&self, wallet_id: &WalletAddress, denom: &Denom) -> Result { - query_balance( - self.chain_id.as_str(), - &self.command_path, - &self.rpc_listen_address(), - &wallet_id.0, - &denom.to_string(), - ) + match self.chain_type { + ChainType::Namada => query_namada_balance( + self.chain_id.as_str(), + &self.command_path, + &self.home_path, + denom, + &wallet_id.0, + &self.rpc_listen_address(), + ), + _ => query_balance( + self.chain_id.as_str(), + &self.command_path, + &self.rpc_listen_address(), + &wallet_id.0, + &denom.to_string(), + ), + } } /** diff --git a/tools/test-framework/src/chain/exec.rs b/tools/test-framework/src/chain/exec.rs index c9b958de3f..1ca6134d8b 100644 --- a/tools/test-framework/src/chain/exec.rs +++ b/tools/test-framework/src/chain/exec.rs @@ -49,3 +49,54 @@ pub fn simple_exec(desc: &str, command_path: &str, args: &[&str]) -> Result Result { + debug!( + "Executing command for {}: {} {}", + desc, + command_path, + itertools::join(args, " ") + ); + + let mut cmd = Command::new(command_path); + + for (key, value) in envs { + cmd.env(key, value); + } + + let output = cmd + .args(args) + .output() + .map_err(handle_exec_error(command_path))?; + + if output.status.success() { + let stdout = str::from_utf8(&output.stdout) + .map_err(handle_generic_error)? + .to_string(); + + let stderr = str::from_utf8(&output.stderr) + .map_err(handle_generic_error)? + .to_string(); + + trace!( + "command executed successfully with stdout: {}, stderr: {}", + stdout, + stderr + ); + + Ok(ExecOutput { stdout, stderr }) + } else { + let message = str::from_utf8(&output.stderr).map_err(handle_generic_error)?; + + Err(Error::generic(eyre!( + "command exited with error status {:?} and message: {}", + output.status.code(), + message + ))) + } +} diff --git a/tools/test-framework/src/chain/ext/bootstrap.rs b/tools/test-framework/src/chain/ext/bootstrap.rs index 37313be246..5617135555 100644 --- a/tools/test-framework/src/chain/ext/bootstrap.rs +++ b/tools/test-framework/src/chain/ext/bootstrap.rs @@ -162,9 +162,7 @@ impl ChainBootstrapMethodsExt for ChainDriver { file: &str, cont: impl FnOnce(&mut toml::Value) -> Result<(), Error>, ) -> Result<(), Error> { - let config_path = format!("config/{file}"); - - let config1 = self.read_file(&config_path)?; + let config1 = self.read_file(file)?; let mut config2 = toml::from_str(&config1).map_err(handle_generic_error)?; @@ -172,7 +170,7 @@ impl ChainBootstrapMethodsExt for ChainDriver { let config3 = toml::to_string_pretty(&config2).map_err(handle_generic_error)?; - self.write_file(&config_path, &config3)?; + self.write_file(file, &config3)?; Ok(()) } @@ -225,7 +223,11 @@ impl ChainBootstrapMethodsExt for ChainDriver { let key = Secp256k1KeyPair::from_seed_file(&seed_content, &hd_path) .map_err(handle_generic_error)?; - Ok(Wallet::new(wallet_id.to_string(), wallet_address, key)) + Ok(Wallet::new_secp256( + wallet_id.to_string(), + wallet_address, + key, + )) } fn add_genesis_account(&self, wallet: &WalletAddress, amounts: &[&Token]) -> Result<(), Error> { diff --git a/tools/test-framework/src/chain/ext/transfer.rs b/tools/test-framework/src/chain/ext/transfer.rs index 94707ff8da..2bc0864e6c 100644 --- a/tools/test-framework/src/chain/ext/transfer.rs +++ b/tools/test-framework/src/chain/ext/transfer.rs @@ -1,15 +1,18 @@ use core::time::Duration; use ibc_relayer_types::core::ics02_client::height::Height; -use ibc_relayer_types::core::ics04_channel::packet::Packet; use ibc_relayer_types::core::ics24_host::identifier::{ChannelId, PortId}; +use crate::chain::chain_type::ChainType; use crate::chain::cli::transfer::{local_transfer_token, transfer_from_chain}; use crate::chain::driver::ChainDriver; use crate::chain::tagged::TaggedChainDriverExt; use crate::error::Error; use crate::ibc::token::TaggedTokenRef; -use crate::relayer::transfer::{batched_ibc_token_transfer, ibc_token_transfer}; +use crate::relayer::transfer::{ + batched_ibc_token_transfer, ibc_namada_token_transfer, ibc_token_transfer, + local_namada_token_transfer, +}; use crate::types::id::{TaggedChannelIdRef, TaggedPortIdRef}; use crate::types::tagged::*; use crate::types::wallet::{Wallet, WalletAddress}; @@ -42,7 +45,7 @@ pub trait ChainTransferMethodsExt { sender: &MonoTagged, recipient: &MonoTagged, token: &TaggedTokenRef, - ) -> Result; + ) -> Result<(), Error>; fn ibc_transfer_token_with_memo_and_timeout( &self, @@ -53,7 +56,7 @@ pub trait ChainTransferMethodsExt { token: &TaggedTokenRef, memo: Option, timeout: Option, - ) -> Result; + ) -> Result<(), Error>; fn ibc_transfer_token_multiple( &self, @@ -93,19 +96,34 @@ impl<'a, Chain: Send> ChainTransferMethodsExt for MonoTagged, recipient: &MonoTagged, token: &TaggedTokenRef, - ) -> Result { - let rpc_client = self.rpc_client()?; - self.value().runtime.block_on(ibc_token_transfer( - rpc_client.as_ref(), - &self.tx_config(), - port_id, - channel_id, - sender, - recipient, - token, - None, - None, - )) + ) -> Result<(), Error> { + match self.value().chain_type { + crate::chain::chain_type::ChainType::Namada => ibc_namada_token_transfer( + &self.value().home_path, + &sender.value().id.to_string(), + recipient.value().as_str(), + token.value().denom.as_str(), + &token.value().amount.to_string(), + &channel_id.to_string(), + &self.value().rpc_port.to_string(), + None, + None, + ), + _ => { + let rpc_client = self.rpc_client()?; + self.value().runtime.block_on(ibc_token_transfer( + rpc_client.as_ref(), + &self.tx_config(), + port_id, + channel_id, + sender, + recipient, + token, + None, + None, + )) + } + } } fn ibc_transfer_token_with_memo_and_timeout( @@ -117,19 +135,39 @@ impl<'a, Chain: Send> ChainTransferMethodsExt for MonoTagged, memo: Option, timeout: Option, - ) -> Result { - let rpc_client = self.rpc_client()?; - self.value().runtime.block_on(ibc_token_transfer( - rpc_client.as_ref(), - &self.tx_config(), - port_id, - channel_id, - sender, - recipient, - token, - memo, - timeout, - )) + ) -> Result<(), Error> { + match self.value().chain_type { + ChainType::Namada => { + let denom = token.value().denom.to_string(); + let amount = token.value().amount.to_string(); + let rpc_port = self.value().rpc_port.to_string(); + ibc_namada_token_transfer( + &self.value().home_path, + &sender.value().id.to_string(), + recipient.value().as_str(), + &denom, + &amount, + channel_id.value().as_ref(), + &rpc_port, + memo, + timeout, + ) + } + _ => { + let rpc_client = self.rpc_client()?; + self.value().runtime.block_on(ibc_token_transfer( + rpc_client.as_ref(), + &self.tx_config(), + port_id, + channel_id, + sender, + recipient, + token, + memo, + timeout, + )) + } + } } fn ibc_transfer_token_multiple( @@ -142,18 +180,42 @@ impl<'a, Chain: Send> ChainTransferMethodsExt for MonoTagged, ) -> Result<(), Error> { - let rpc_client = self.rpc_client()?; - self.value().runtime.block_on(batched_ibc_token_transfer( - rpc_client.as_ref(), - &self.tx_config(), - port_id, - channel_id, - sender, - recipient, - token, - num_msgs, - memo, - )) + match self.value().chain_type { + ChainType::Namada => { + let denom = token.value().denom.to_string(); + let amount = token.value().amount.to_string(); + let rpc_port = self.value().rpc_port.to_string(); + // Namada CLI doesn't support batching transactions + for _ in 0..num_msgs { + ibc_namada_token_transfer( + &self.value().home_path, + &sender.value().id.to_string(), + recipient.value().as_str(), + &denom, + &amount, + &channel_id.to_string(), + &rpc_port, + memo.clone(), + None, + )?; + } + Ok(()) + } + _ => { + let rpc_client = self.rpc_client()?; + self.value().runtime.block_on(batched_ibc_token_transfer( + rpc_client.as_ref(), + &self.tx_config(), + port_id, + channel_id, + sender, + recipient, + token, + num_msgs, + memo, + )) + } + } } fn local_transfer_token( @@ -163,15 +225,30 @@ impl<'a, Chain: Send> ChainTransferMethodsExt for MonoTagged, ) -> Result<(), Error> { let driver = *self.value(); - local_transfer_token( - driver.chain_id.as_str(), - &driver.command_path, - &driver.home_path, - &driver.rpc_listen_address(), - sender.value().address.as_str(), - recipient.value().as_str(), - &token.value().to_string(), - ) + match driver.chain_type { + ChainType::Namada => { + let denom = token.value().denom.to_string(); + let amount = token.value().amount.to_string(); + let rpc_port = self.value().rpc_port.to_string(); + local_namada_token_transfer( + &driver.home_path, + &sender.value().id.to_string(), + recipient.value().as_str(), + &denom, + &amount, + &rpc_port, + ) + } + _ => local_transfer_token( + driver.chain_id.as_str(), + &driver.command_path, + &driver.home_path, + &driver.rpc_listen_address(), + sender.value().address.as_str(), + recipient.value().as_str(), + &token.value().to_string(), + ), + } } fn transfer_from_chain( @@ -185,19 +262,39 @@ impl<'a, Chain: Send> ChainTransferMethodsExt for MonoTagged Result<(), Error> { let driver = *self.value(); - let timeout_height_str = timeout_height.revision_height() + 100; - transfer_from_chain( - driver.chain_id.as_str(), - &driver.command_path, - &driver.home_path, - &driver.rpc_listen_address(), - sender.value().address.as_str(), - port.as_ref(), - channel.as_ref(), - recipient.value().as_str(), - &token.value().to_string(), - &fees.value().to_string(), - &timeout_height_str.to_string(), - ) + match driver.chain_type { + ChainType::Namada => { + let denom = token.value().denom.to_string(); + let amount = token.value().amount.to_string(); + let rpc_port = self.value().rpc_port.to_string(); + ibc_namada_token_transfer( + &driver.home_path, + &sender.value().id.to_string(), + recipient.value().as_str(), + &denom, + &amount, + channel.as_ref(), + &rpc_port, + None, + None, + ) + } + _ => { + let timeout_height_str = timeout_height.revision_height() + 100; + transfer_from_chain( + driver.chain_id.as_str(), + &driver.command_path, + &driver.home_path, + &driver.rpc_listen_address(), + sender.value().address.as_str(), + port.as_ref(), + channel.as_ref(), + recipient.value().as_str(), + &token.value().to_string(), + &fees.value().to_string(), + &timeout_height_str.to_string(), + ) + } + } } } diff --git a/tools/test-framework/src/chain/tagged.rs b/tools/test-framework/src/chain/tagged.rs index 64b73ef171..92e3a3b3b9 100644 --- a/tools/test-framework/src/chain/tagged.rs +++ b/tools/test-framework/src/chain/tagged.rs @@ -1,13 +1,14 @@ /*! Methods for tagged version of the chain driver. */ +use eyre::eyre; +use serde_json as json; use ibc_proto::google::protobuf::Any; use ibc_relayer::chain::cosmos::tx::simple_send_tx; use ibc_relayer::chain::cosmos::types::config::TxConfig; use ibc_relayer::event::IbcEventWithHeight; use ibc_relayer::util::compat_mode::compat_mode_from_version; -use serde_json as json; use tendermint_rpc::client::{Client, HttpClient}; use crate::chain::cli::query::query_auth_module; @@ -120,12 +121,18 @@ impl<'a, Chain: Send> TaggedChainDriverExt for MonoTagged Result, Error> { let rpc_client = self.rpc_client()?; + let key = &wallet + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; self.value() .runtime .block_on(simple_send_tx( rpc_client.as_ref().into_value(), &self.value().tx_config, - &wallet.value().key, + key, messages, )) .map_err(Error::relayer) diff --git a/tools/test-framework/src/docs/walkthroughs/memo.rs b/tools/test-framework/src/docs/walkthroughs/memo.rs index 7c0887a76c..336bc5d874 100644 --- a/tools/test-framework/src/docs/walkthroughs/memo.rs +++ b/tools/test-framework/src/docs/walkthroughs/memo.rs @@ -10,8 +10,7 @@ //! //! ```no_run //! # use serde_json as json; -//! # use ibc_relayer::config::{types::Memo, Config}; -//! # use ibc_relayer::config::ChainConfig; +//! # use ibc_relayer::config::{types::Memo, Config, ChainConfig}; //! # use ibc_test_framework::ibc::denom::derive_ibc_denom; //! # use ibc_test_framework::prelude::*; //! # use ibc_test_framework::util::random::{random_string, random_u128_range}; @@ -32,9 +31,9 @@ //! fn modify_relayer_config(&self, config: &mut Config) { //! for mut chain in config.chains.iter_mut() { //! match chain { -//! ChainConfig::CosmosSdk(chain_config) => { +//! ChainConfig::CosmosSdk(chain_config) | ChainConfig::Namada(chain_config) => { //! chain_config.memo_prefix = self.memo.clone(); -//! }, +//! } //! } //! } //! } @@ -61,6 +60,7 @@ //! )?; //! //! let denom_b = derive_ibc_denom( +//! &chains.node_b.chain_driver().value().chain_type, //! &channel.port_b.as_ref(), //! &channel.channel_id_b.as_ref(), //! &denom_a, diff --git a/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs b/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs index 36c04807a6..6f717d436e 100644 --- a/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs +++ b/tools/test-framework/src/docs/walkthroughs/ordered_channel.rs @@ -95,6 +95,7 @@ //! sleep(Duration::from_secs(1)); //! //! let denom_b = derive_ibc_denom( +//! &chains.node_b.chain_driver().value().chain_type, //! &channel.port_b.as_ref(), //! &channel.channel_id_b.as_ref(), //! &denom_a, diff --git a/tools/test-framework/src/framework/binary/chain.rs b/tools/test-framework/src/framework/binary/chain.rs index a1a3aae940..9cfd9e9532 100644 --- a/tools/test-framework/src/framework/binary/chain.rs +++ b/tools/test-framework/src/framework/binary/chain.rs @@ -13,8 +13,8 @@ use crate::error::Error; use crate::framework::base::{HasOverrides, TestConfigOverride}; use crate::framework::binary::ics::InterchainSecurityChainTest; use crate::framework::binary::node::{ - run_binary_node_test, run_single_node_test, BinaryNodeTest, NodeConfigOverride, - NodeGenesisOverride, + run_binary_node_test, run_single_node_test, BinaryNodeTest, NamadaParametersOverride, + NodeConfigOverride, NodeGenesisOverride, }; use crate::framework::supervisor::{RunWithSupervisor, SupervisorOverride}; use crate::relayer::driver::RelayerDriver; @@ -38,7 +38,8 @@ where + RelayerConfigOverride + ClientOptionsOverride + SupervisorOverride - + TestConfigOverride, + + TestConfigOverride + + NamadaParametersOverride, { run_binary_chain_test(&RunTwoWayBinaryChainTest::new(test)) } @@ -55,7 +56,8 @@ where + RelayerConfigOverride + ClientOptionsOverride + SupervisorOverride - + TestConfigOverride, + + TestConfigOverride + + NamadaParametersOverride, { run_binary_node_test(&RunBinaryChainTest::new(&RunWithSupervisor::new(test))) } diff --git a/tools/test-framework/src/framework/binary/channel.rs b/tools/test-framework/src/framework/binary/channel.rs index 00ae9efd89..c53120b951 100644 --- a/tools/test-framework/src/framework/binary/channel.rs +++ b/tools/test-framework/src/framework/binary/channel.rs @@ -24,7 +24,7 @@ use crate::framework::binary::connection::{ }; use crate::framework::binary::ics::run_binary_interchain_security_node_test; use crate::framework::binary::node::{ - run_binary_node_test, NodeConfigOverride, NodeGenesisOverride, + run_binary_node_test, NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, }; use crate::framework::supervisor::{RunWithSupervisor, SupervisorOverride}; use crate::relayer::driver::RelayerDriver; @@ -54,7 +54,8 @@ where + ConnectionDelayOverride + PortsOverride + ChannelOrderOverride - + ChannelVersionOverride, + + ChannelVersionOverride + + NamadaParametersOverride, { run_binary_channel_test(&RunTwoWayBinaryChannelTest::new(test)) } @@ -75,7 +76,8 @@ where + ConnectionDelayOverride + PortsOverride + ChannelOrderOverride - + ChannelVersionOverride, + + ChannelVersionOverride + + NamadaParametersOverride, { run_binary_node_test(&RunBinaryChainTest::new(&RunBinaryConnectionTest::new( &RunBinaryChannelTest::new(&RunWithSupervisor::new(test)), diff --git a/tools/test-framework/src/framework/binary/connection.rs b/tools/test-framework/src/framework/binary/connection.rs index 9e96a7665e..8b7c3ec56f 100644 --- a/tools/test-framework/src/framework/binary/connection.rs +++ b/tools/test-framework/src/framework/binary/connection.rs @@ -16,7 +16,7 @@ use crate::framework::binary::chain::{ BinaryChainTest, ClientOptionsOverride, RelayerConfigOverride, RunBinaryChainTest, }; use crate::framework::binary::node::{ - run_binary_node_test, NodeConfigOverride, NodeGenesisOverride, + run_binary_node_test, NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, }; use crate::framework::supervisor::{RunWithSupervisor, SupervisorOverride}; use crate::relayer::driver::RelayerDriver; @@ -41,7 +41,8 @@ where + RelayerConfigOverride + ClientOptionsOverride + SupervisorOverride - + ConnectionDelayOverride, + + ConnectionDelayOverride + + NamadaParametersOverride, { run_binary_connection_test(&RunTwoWayBinaryConnectionTest::new(test)) } @@ -59,7 +60,8 @@ where + RelayerConfigOverride + ClientOptionsOverride + SupervisorOverride - + ConnectionDelayOverride, + + ConnectionDelayOverride + + NamadaParametersOverride, { run_binary_node_test(&RunBinaryChainTest::new(&RunBinaryConnectionTest::new( &RunWithSupervisor::new(test), diff --git a/tools/test-framework/src/framework/binary/node.rs b/tools/test-framework/src/framework/binary/node.rs index ff59b4a13e..779003d3a8 100644 --- a/tools/test-framework/src/framework/binary/node.rs +++ b/tools/test-framework/src/framework/binary/node.rs @@ -3,8 +3,14 @@ running without setting up the relayer. */ +use std::str::FromStr; + +use toml; + +use crate::bootstrap::namada::bootstrap_namada_node; use crate::bootstrap::single::bootstrap_single_node; use crate::chain::builder::ChainBuilder; +use crate::chain::chain_type::ChainType; use crate::error::Error; use crate::framework::base::HasOverrides; use crate::framework::base::{run_basic_test, BasicTest, TestConfigOverride}; @@ -18,7 +24,8 @@ pub fn run_binary_node_test(test: &Test) -> Result<(), Error> where Test: BinaryNodeTest, Test: HasOverrides, - Overrides: NodeConfigOverride + NodeGenesisOverride + TestConfigOverride, + Overrides: + NodeConfigOverride + NodeGenesisOverride + TestConfigOverride + NamadaParametersOverride, { run_basic_test(&RunBinaryNodeTest { test }) } @@ -87,6 +94,10 @@ pub trait NodeGenesisOverride { fn modify_genesis_file(&self, genesis: &mut serde_json::Value) -> Result<(), Error>; } +pub trait NamadaParametersOverride { + fn namada_modify_parameter_file(&self, parameter: &mut toml::Value) -> Result<(), Error>; +} + /** A wrapper type that lifts a test case that implements [`BinaryNodeTest`] into a test case that implements [`BasicTest`]. @@ -105,26 +116,59 @@ impl<'a, Test, Overrides> BasicTest for RunBinaryNodeTest<'a, Test> where Test: BinaryNodeTest, Test: HasOverrides, - Overrides: NodeConfigOverride + NodeGenesisOverride, + Overrides: NodeConfigOverride + NodeGenesisOverride + NamadaParametersOverride, { fn run(&self, config: &TestConfig, builder: &ChainBuilder) -> Result<(), Error> { - let node_a = bootstrap_single_node( - builder, - "1", - config.bootstrap_with_random_ids, - |config| self.test.get_overrides().modify_node_config(config), - |genesis| self.test.get_overrides().modify_genesis_file(genesis), - 0, - )?; - - let node_b = bootstrap_single_node( - builder, - "2", - config.bootstrap_with_random_ids, - |config| self.test.get_overrides().modify_node_config(config), - |genesis| self.test.get_overrides().modify_genesis_file(genesis), - 1, - )?; + let command_paths_len = builder.command_paths.len(); + let node_a_type = ChainType::from_str(&builder.command_paths[0 % command_paths_len])?; + let node_a = match node_a_type { + ChainType::Namada => bootstrap_namada_node( + builder, + "a", + false, + |config| self.test.get_overrides().modify_node_config(config), + |genesis| self.test.get_overrides().modify_genesis_file(genesis), + |parameters| { + self.test + .get_overrides() + .namada_modify_parameter_file(parameters) + }, + 0, + ), + _ => bootstrap_single_node( + builder, + "1", + config.bootstrap_with_random_ids, + |config| self.test.get_overrides().modify_node_config(config), + |genesis| self.test.get_overrides().modify_genesis_file(genesis), + 0, + ), + }?; + let node_b_type = ChainType::from_str(&builder.command_paths[1 % command_paths_len])?; + + let node_b = match node_b_type { + ChainType::Namada => bootstrap_namada_node( + builder, + "b", + false, + |config| self.test.get_overrides().modify_node_config(config), + |genesis| self.test.get_overrides().modify_genesis_file(genesis), + |parameters| { + self.test + .get_overrides() + .namada_modify_parameter_file(parameters) + }, + 1, + ), + _ => bootstrap_single_node( + builder, + "2", + config.bootstrap_with_random_ids, + |config| self.test.get_overrides().modify_node_config(config), + |genesis| self.test.get_overrides().modify_genesis_file(genesis), + 1, + ), + }?; let _node_process_a = node_a.process.clone(); let _node_process_b = node_b.process.clone(); diff --git a/tools/test-framework/src/framework/nary/chain.rs b/tools/test-framework/src/framework/nary/chain.rs index 392114cc5e..756d4f4745 100644 --- a/tools/test-framework/src/framework/nary/chain.rs +++ b/tools/test-framework/src/framework/nary/chain.rs @@ -12,7 +12,9 @@ use crate::bootstrap::nary::chain::{ use crate::error::Error; use crate::framework::base::{HasOverrides, TestConfigOverride}; use crate::framework::binary::chain::RelayerConfigOverride; -use crate::framework::binary::node::{NodeConfigOverride, NodeGenesisOverride}; +use crate::framework::binary::node::{ + NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, +}; use crate::framework::nary::node::{run_nary_node_test, NaryNodeTest}; use crate::framework::supervisor::{RunWithSupervisor, SupervisorOverride}; use crate::relayer::driver::RelayerDriver; @@ -48,7 +50,8 @@ where + NodeConfigOverride + NodeGenesisOverride + RelayerConfigOverride - + SupervisorOverride, + + SupervisorOverride + + NamadaParametersOverride, { run_nary_node_test(&RunNaryChainTest::new(&RunWithSupervisor::new(test))) } @@ -77,7 +80,8 @@ where + NodeConfigOverride + NodeGenesisOverride + RelayerConfigOverride - + SupervisorOverride, + + SupervisorOverride + + NamadaParametersOverride, { run_nary_node_test(&RunSelfConnectedNaryChainTest::new( &RunWithSupervisor::new(test), diff --git a/tools/test-framework/src/framework/nary/channel.rs b/tools/test-framework/src/framework/nary/channel.rs index cd7ccdfe78..219d507792 100644 --- a/tools/test-framework/src/framework/nary/channel.rs +++ b/tools/test-framework/src/framework/nary/channel.rs @@ -14,7 +14,9 @@ use crate::framework::base::{HasOverrides, TestConfigOverride}; use crate::framework::binary::chain::RelayerConfigOverride; use crate::framework::binary::channel::{BinaryChannelTest, ChannelOrderOverride}; use crate::framework::binary::connection::ConnectionDelayOverride; -use crate::framework::binary::node::{NodeConfigOverride, NodeGenesisOverride}; +use crate::framework::binary::node::{ + NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, +}; use crate::framework::nary::chain::RunNaryChainTest; use crate::framework::nary::connection::{NaryConnectionTest, RunNaryConnectionTest}; use crate::framework::nary::node::run_nary_node_test; @@ -38,7 +40,8 @@ where + SupervisorOverride + ConnectionDelayOverride + PortsOverride - + ChannelOrderOverride, + + ChannelOrderOverride + + NamadaParametersOverride, { run_nary_node_test(&RunNaryChainTest::new(&RunNaryConnectionTest::new( &RunNaryChannelTest::new(&RunWithSupervisor::new(test)), @@ -56,7 +59,8 @@ where + SupervisorOverride + ConnectionDelayOverride + PortsOverride<2> - + ChannelOrderOverride, + + ChannelOrderOverride + + NamadaParametersOverride, { run_nary_channel_test(&RunBinaryAsNaryChannelTest::new(test)) } diff --git a/tools/test-framework/src/framework/nary/connection.rs b/tools/test-framework/src/framework/nary/connection.rs index 485b2ecd1b..a58b3a0eec 100644 --- a/tools/test-framework/src/framework/nary/connection.rs +++ b/tools/test-framework/src/framework/nary/connection.rs @@ -12,7 +12,9 @@ use crate::error::Error; use crate::framework::base::{HasOverrides, TestConfigOverride}; use crate::framework::binary::chain::RelayerConfigOverride; use crate::framework::binary::connection::{BinaryConnectionTest, ConnectionDelayOverride}; -use crate::framework::binary::node::{NodeConfigOverride, NodeGenesisOverride}; +use crate::framework::binary::node::{ + NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, +}; use crate::framework::nary::chain::{NaryChainTest, RunNaryChainTest}; use crate::framework::nary::node::run_nary_node_test; use crate::framework::supervisor::{RunWithSupervisor, SupervisorOverride}; @@ -34,7 +36,8 @@ where + NodeGenesisOverride + RelayerConfigOverride + SupervisorOverride - + ConnectionDelayOverride, + + ConnectionDelayOverride + + NamadaParametersOverride, { run_nary_node_test(&RunNaryChainTest::new(&RunNaryConnectionTest::new( &RunWithSupervisor::new(test), diff --git a/tools/test-framework/src/framework/nary/node.rs b/tools/test-framework/src/framework/nary/node.rs index cea7c81ac4..664ac67328 100644 --- a/tools/test-framework/src/framework/nary/node.rs +++ b/tools/test-framework/src/framework/nary/node.rs @@ -3,12 +3,15 @@ running without setting up the relayer. */ +use crate::bootstrap::namada::bootstrap_namada_node; use crate::bootstrap::single::bootstrap_single_node; use crate::chain::builder::ChainBuilder; use crate::error::Error; use crate::framework::base::HasOverrides; use crate::framework::base::{run_basic_test, BasicTest, TestConfigOverride}; -use crate::framework::binary::node::{NodeConfigOverride, NodeGenesisOverride}; +use crate::framework::binary::node::{ + NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, +}; use crate::types::config::TestConfig; use crate::types::single::node::FullNode; use crate::util::array::try_into_array; @@ -17,7 +20,8 @@ pub fn run_nary_node_test(test: &Test) -> Re where Test: NaryNodeTest, Test: HasOverrides, - Overrides: NodeConfigOverride + NodeGenesisOverride + TestConfigOverride, + Overrides: + NodeConfigOverride + NodeGenesisOverride + TestConfigOverride + NamadaParametersOverride, { run_basic_test(&RunNaryNodeTest { test }) } @@ -49,21 +53,37 @@ impl<'a, Test, Overrides, const SIZE: usize> BasicTest for RunNaryNodeTest<'a, T where Test: NaryNodeTest, Test: HasOverrides, - Overrides: NodeConfigOverride + NodeGenesisOverride, + Overrides: NodeConfigOverride + NodeGenesisOverride + NamadaParametersOverride, { fn run(&self, config: &TestConfig, builder: &ChainBuilder) -> Result<(), Error> { let mut nodes = Vec::new(); let mut node_processes = Vec::new(); for i in 0..SIZE { - let node = bootstrap_single_node( - builder, - &format!("{}", i + 1), - config.bootstrap_with_random_ids, - |config| self.test.get_overrides().modify_node_config(config), - |genesis| self.test.get_overrides().modify_genesis_file(genesis), - i, - )?; + let node = if builder.command_paths.contains(&"namada".to_string()) { + bootstrap_namada_node( + builder, + &format!("{}", i + 1), + config.bootstrap_with_random_ids, + |config| self.test.get_overrides().modify_node_config(config), + |genesis| self.test.get_overrides().modify_genesis_file(genesis), + |parameters| { + self.test + .get_overrides() + .namada_modify_parameter_file(parameters) + }, + i, + )? + } else { + bootstrap_single_node( + builder, + &format!("{}", i + 1), + config.bootstrap_with_random_ids, + |config| self.test.get_overrides().modify_node_config(config), + |genesis| self.test.get_overrides().modify_genesis_file(genesis), + i, + )? + }; node_processes.push(node.process.clone()); nodes.push(node); diff --git a/tools/test-framework/src/framework/overrides.rs b/tools/test-framework/src/framework/overrides.rs index 0338224469..387759db09 100644 --- a/tools/test-framework/src/framework/overrides.rs +++ b/tools/test-framework/src/framework/overrides.rs @@ -18,7 +18,9 @@ use crate::framework::binary::channel::{ ChannelOrderOverride, ChannelVersionOverride, PortsOverride, }; use crate::framework::binary::connection::ConnectionDelayOverride; -use crate::framework::binary::node::{NodeConfigOverride, NodeGenesisOverride}; +use crate::framework::binary::node::{ + NamadaParametersOverride, NodeConfigOverride, NodeGenesisOverride, +}; use crate::framework::nary::channel::PortsOverride as NaryPortsOverride; use crate::framework::supervisor::SupervisorOverride; use crate::types::config::TestConfig; @@ -78,6 +80,10 @@ pub trait TestOverrides { // No modification by default } + fn namada_modify_parameter_file(&self, _parameter: &mut toml::Value) -> Result<(), Error> { + Ok(()) + } + /// Returns the settings for the foreign client on the first chain for the /// second chain. The defaults are for a client connecting two Cosmos chains /// with no custom settings. @@ -173,6 +179,12 @@ impl NodeGenesisOverride for Test { } } +impl NamadaParametersOverride for Test { + fn namada_modify_parameter_file(&self, parameter: &mut toml::Value) -> Result<(), Error> { + TestOverrides::namada_modify_parameter_file(self, parameter) + } +} + impl RelayerConfigOverride for Test { fn modify_relayer_config(&self, config: &mut Config) { TestOverrides::modify_relayer_config(self, config) diff --git a/tools/test-framework/src/ibc/denom.rs b/tools/test-framework/src/ibc/denom.rs index 965a56b1b7..e22fa87994 100644 --- a/tools/test-framework/src/ibc/denom.rs +++ b/tools/test-framework/src/ibc/denom.rs @@ -8,6 +8,7 @@ use ibc_relayer_types::core::ics24_host::identifier::{ChannelId, PortId}; use sha2::{Digest, Sha256}; use subtle_encoding::hex; +use crate::chain::chain_type::ChainType; use crate::types::id::{TaggedChannelIdRef, TaggedPortIdRef}; use crate::types::tagged::*; @@ -16,10 +17,13 @@ use crate::types::tagged::*; */ #[derive(Debug, Clone)] pub enum Denom { - Base(String), + Base { + display_name: String, + raw_address: String, + }, Ibc { path: String, - denom: String, + denom: Box, hashed: String, }, } @@ -51,6 +55,18 @@ pub type TaggedDenomRef<'a, Chain> = MonoTagged; Returns the derived denomination on `ChainB`. */ pub fn derive_ibc_denom( + chain_type: &ChainType, + port_id: &TaggedPortIdRef, + channel_id: &TaggedChannelIdRef, + denom: &TaggedDenomRef, +) -> Result, Error> { + match chain_type { + ChainType::Namada => derive_namada_ibc_denom(port_id, channel_id, denom), + _ => derive_cosmos_ibc_denom(port_id, channel_id, denom), + } +} + +fn derive_cosmos_ibc_denom( port_id: &TaggedPortIdRef, channel_id: &TaggedChannelIdRef, denom: &TaggedDenomRef, @@ -77,12 +93,12 @@ pub fn derive_ibc_denom( } match denom.value() { - Denom::Base(denom) => { - let hashed = derive_denom(port_id.value(), channel_id.value(), denom)?; + Denom::Base { raw_address, .. } => { + let hashed = derive_denom(port_id.value(), channel_id.value(), raw_address)?; Ok(MonoTagged::new(Denom::Ibc { path: format!("{port_id}/{channel_id}"), - denom: denom.clone(), + denom: Box::new((*denom.value()).clone()), hashed, })) } @@ -99,14 +115,47 @@ pub fn derive_ibc_denom( } } +fn derive_namada_ibc_denom( + port_id: &TaggedPortIdRef, + channel_id: &TaggedChannelIdRef, + denom: &TaggedDenomRef, +) -> Result, Error> { + match denom.value() { + Denom::Base { raw_address, .. } => { + let path = format!("{port_id}/{channel_id}"); + let ibc_token_addr = namada_ibc::storage::ibc_token(format!("{path}/{raw_address}")); + + Ok(MonoTagged::new(Denom::Ibc { + path, + denom: Box::new((*denom.value()).clone()), + hashed: ibc_token_addr.to_string(), + })) + } + Denom::Ibc { path, denom, .. } => { + let new_path = format!("{port_id}/{channel_id}/{path}"); + let ibc_token_addr = + namada_ibc::storage::ibc_token(format!("{new_path}/{}", denom.hash_only())); + + Ok(MonoTagged::new(Denom::Ibc { + path: new_path, + denom: denom.clone(), + hashed: ibc_token_addr.to_string(), + })) + } + } +} + impl Denom { - pub fn base(denom: &str) -> Self { - Denom::Base(denom.to_string()) + pub fn base(display_name: &str, raw_address: &str) -> Self { + Denom::Base { + display_name: display_name.to_owned(), + raw_address: raw_address.to_owned(), + } } pub fn hash_only(&self) -> String { match self { - Denom::Base(denom) => denom.to_string(), + Denom::Base { raw_address, .. } => raw_address.to_string(), Denom::Ibc { hashed, .. } => match hashed.find('/') { Some(index) => hashed[index + 1..].to_string(), None => hashed.to_string(), @@ -114,9 +163,23 @@ impl Denom { } } + pub fn display_name(&self) -> String { + match self { + Denom::Base { display_name, .. } => display_name.to_string(), + Denom::Ibc { hashed, .. } => hashed.to_string(), + } + } + + pub fn namada_display_name(&self) -> String { + match self { + Denom::Base { display_name, .. } => display_name.to_string(), + Denom::Ibc { path, denom, .. } => format!("{path}/{}", denom.namada_display_name()), + } + } + pub fn as_str(&self) -> &str { match self { - Denom::Base(denom) => denom, + Denom::Base { display_name, .. } => display_name, Denom::Ibc { hashed, .. } => hashed, } } @@ -125,8 +188,8 @@ impl Denom { impl Display for Denom { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match self { - Denom::Base(denom) => { - write!(f, "{denom}") + Denom::Base { display_name, .. } => { + write!(f, "{display_name}") } Denom::Ibc { hashed, .. } => { write!(f, "{hashed}") @@ -138,7 +201,16 @@ impl Display for Denom { impl PartialEq for Denom { fn eq(&self, other: &Self) -> bool { match (self, other) { - (Self::Base(d1), Self::Base(d2)) => d1 == d2, + ( + Self::Base { + display_name: d1, + raw_address: a1, + }, + Self::Base { + display_name: d2, + raw_address: a2, + }, + ) => (d1 == d2) && (a1 == a2), ( Self::Ibc { path: p1, diff --git a/tools/test-framework/src/ibc/token.rs b/tools/test-framework/src/ibc/token.rs index ac7b6785ad..4e6844e47c 100644 --- a/tools/test-framework/src/ibc/token.rs +++ b/tools/test-framework/src/ibc/token.rs @@ -2,6 +2,7 @@ use core::ops::{Add, Sub}; use ibc_relayer_types::applications::transfer::amount::Amount; use ibc_relayer_types::applications::transfer::coin::{Coin, RawCoin}; +use crate::chain::chain_type::ChainType; use crate::error::Error; use crate::ibc::denom::{derive_ibc_denom, Denom, TaggedDenom, TaggedDenomRef}; use crate::types::id::{TaggedChannelIdRef, TaggedPortIdRef}; @@ -21,6 +22,7 @@ pub trait TaggedTokenExt { fn transfer( &self, + chain_type: &ChainType, port_id: &TaggedPortIdRef, channel_id: &TaggedChannelIdRef, ) -> Result, Error>; @@ -45,10 +47,11 @@ impl TaggedTokenExt for TaggedToken { fn transfer( &self, + chain_type: &ChainType, port_id: &TaggedPortIdRef, channel_id: &TaggedChannelIdRef, ) -> Result, Error> { - let denom = derive_ibc_denom(port_id, channel_id, &self.denom())?; + let denom = derive_ibc_denom(chain_type, port_id, channel_id, &self.denom())?; Ok(denom.with_amount(self.value().amount)) } @@ -69,10 +72,11 @@ impl<'a, Chain> TaggedTokenExt for TaggedTokenRef<'a, Chain> { fn transfer( &self, + chain_type: &ChainType, port_id: &TaggedPortIdRef, channel_id: &TaggedChannelIdRef, ) -> Result, Error> { - let denom = derive_ibc_denom(port_id, channel_id, &self.denom())?; + let denom = derive_ibc_denom(chain_type, port_id, channel_id, &self.denom())?; Ok(denom.with_amount(self.value().amount)) } diff --git a/tools/test-framework/src/relayer/fee.rs b/tools/test-framework/src/relayer/fee.rs index 51b1ff6814..e4a2a92bd4 100644 --- a/tools/test-framework/src/relayer/fee.rs +++ b/tools/test-framework/src/relayer/fee.rs @@ -1,3 +1,5 @@ +use eyre::eyre; + use core::time::Duration; use http::uri::Uri; use ibc_relayer::chain::cosmos::query::fee::{ @@ -63,13 +65,13 @@ pub async fn ibc_token_transfer_with_fee( let messages = vec![pay_message, transfer_message]; - let events = simple_send_tx( - rpc_client.value(), - tx_config.value(), - &sender.value().key, - messages, - ) - .await?; + let key = &sender + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; + let events = simple_send_tx(rpc_client.value(), tx_config.value(), key, messages).await?; Ok(events) } @@ -101,14 +103,15 @@ pub async fn pay_packet_fee( ) .map_err(handle_generic_error)?; - let events = simple_send_tx( - rpc_client.value(), - tx_config.value(), - &payer.value().key, - vec![message], - ) - .await - .map_err(Error::relayer)?; + let key = &payer + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; + let events = simple_send_tx(rpc_client.value(), tx_config.value(), key, vec![message]) + .await + .map_err(Error::relayer)?; Ok(events) } @@ -140,13 +143,13 @@ pub async fn register_counterparty_payee( let messages = vec![message]; - simple_send_tx( - rpc_client.value(), - tx_config.value(), - &wallet.value().key, - messages, - ) - .await?; + let key = &wallet + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; + simple_send_tx(rpc_client.value(), tx_config.value(), key, messages).await?; Ok(()) } @@ -174,13 +177,13 @@ pub async fn register_payee( let messages = vec![message]; - simple_send_tx( - rpc_client.value(), - tx_config.value(), - &wallet.value().key, - messages, - ) - .await?; + let key = &wallet + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; + simple_send_tx(rpc_client.value(), tx_config.value(), key, messages).await?; Ok(()) } diff --git a/tools/test-framework/src/relayer/transfer.rs b/tools/test-framework/src/relayer/transfer.rs index 26595051a5..91a0445043 100644 --- a/tools/test-framework/src/relayer/transfer.rs +++ b/tools/test-framework/src/relayer/transfer.rs @@ -6,8 +6,8 @@ use core::ops::Add; use core::time::Duration; use eyre::eyre; -use ibc_relayer_types::core::ics04_channel::packet::Packet; use ibc_relayer_types::events::IbcEvent; +use std::io::Write; use ibc_proto::google::protobuf::Any; use ibc_relayer::chain::cosmos::tx::batched_send_tx; @@ -20,6 +20,7 @@ use ibc_relayer_types::core::ics04_channel::timeout::TimeoutHeight; use ibc_relayer_types::timestamp::Timestamp; use tendermint_rpc::HttpClient; +use crate::chain::exec::simple_exec; use crate::error::{handle_generic_error, Error}; use crate::ibc::token::TaggedTokenRef; use crate::types::id::{TaggedChannelIdRef, TaggedPortIdRef}; @@ -92,7 +93,7 @@ pub async fn ibc_token_transfer( token: &TaggedTokenRef<'_, SrcChain>, memo: Option, timeout: Option, -) -> Result { +) -> Result<(), Error> { let message = build_transfer_message( port_id, channel_id, @@ -103,15 +104,21 @@ pub async fn ibc_token_transfer( memo.clone(), )?; + let key = &sender + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; let events = simple_send_tx( rpc_client.into_value(), tx_config.value(), - &sender.value().key, + key, vec![message], ) .await?; - let packet = events + let _packet = events .into_iter() .find_map(|event| match event.event { IbcEvent::SendPacket(ev) => Some(ev.packet), @@ -119,7 +126,96 @@ pub async fn ibc_token_transfer( }) .ok_or_else(|| eyre!("failed to find send packet event"))?; - Ok(packet) + //Ok(packet) + Ok(()) +} + +pub fn local_namada_token_transfer( + home_path: &str, + sender: &str, + recipient: &str, + denom: &str, + amount: &str, + rpc_port: &str, +) -> Result<(), Error> { + simple_exec( + "namada local transfer", + "namadac", + &[ + "--base-dir", + home_path, + "transparent-transfer", + "--source", + sender, + "--target", + recipient, + "--token", + denom, + "--amount", + amount, + "--signing-keys", + &format!("{sender}-key"), + "--node", + &format!("http://127.0.0.1:{rpc_port}"), + ], + )?; + + Ok(()) +} + +pub fn ibc_namada_token_transfer( + home_path: &str, + sender: &str, + receiver: &str, + denom: &str, + amount: &str, + channel_id: &str, + rpc_port: &str, + memo: Option, + timeout: Option, +) -> Result<(), Error> { + let signing_key = format!("{sender}-key"); + let node = format!("http://127.0.0.1:{rpc_port}"); + let mut args = vec![ + "--base-dir", + home_path, + "ibc-transfer", + "--source", + sender, + "--receiver", + receiver, + "--token", + denom, + "--amount", + amount, + "--signing-keys", + &signing_key, + "--channel-id", + channel_id, + "--node", + &node, + ]; + + let path = format!("{home_path}/memo.txt"); + if let Some(memo) = memo { + let mut memo_file = std::fs::File::create(&path).expect("Creating a memo file failed"); + memo_file + .write_all(memo.as_bytes()) + .expect("Writing memo failed"); + args.push("--memo-path"); + args.push(&path); + } + + let timeout_str; + if let Some(timeout) = timeout { + args.push("--timeout-sec-offset"); + timeout_str = timeout.as_secs().to_string(); + args.push(&timeout_str); + } + + simple_exec("namada transfer", "namadac", &args)?; + + Ok(()) } pub async fn batched_ibc_token_transfer( @@ -147,13 +243,13 @@ pub async fn batched_ibc_token_transfer( .take(num_msgs) .collect::, _>>()?; - batched_send_tx( - rpc_client.value(), - tx_config.value(), - &sender.value().key, - messages, - ) - .await?; + let key = &sender + .value() + .key + .downcast() + .ok_or_else(|| eyre!("unable to downcast key")) + .map_err(Error::generic)?; + batched_send_tx(rpc_client.value(), tx_config.value(), key, messages).await?; Ok(()) } diff --git a/tools/test-framework/src/types/single/node.rs b/tools/test-framework/src/types/single/node.rs index b6241c0ade..453373d8c8 100644 --- a/tools/test-framework/src/types/single/node.rs +++ b/tools/test-framework/src/types/single/node.rs @@ -20,6 +20,7 @@ use tendermint_rpc::WebSocketClientUrl; use crate::chain::chain_type::ChainType as TestedChainType; use crate::chain::driver::ChainDriver; +use crate::chain::exec::simple_exec; use crate::ibc::denom::Denom; use crate::prelude::TestConfig; use crate::types::env::{prefix_writer, EnvWriter, ExportEnv}; @@ -150,56 +151,112 @@ impl FullNode { 5000.0, test_config.native_tokens[native_token_number].clone(), ), + TestedChainType::Namada => { + let denom = get_denom(&self.chain_driver.home_path)?; + config::GasPrice::new(0.003, denom) + } _ => config::GasPrice::new( 0.003, test_config.native_tokens[native_token_number].clone(), ), }; - Ok(config::ChainConfig::CosmosSdk(CosmosSdkConfig { - id: self.chain_driver.chain_id.clone(), - rpc_addr: Url::from_str(&self.chain_driver.rpc_address())?, - grpc_addr: Url::from_str(&self.chain_driver.grpc_address())?, - event_source: config::EventSourceMode::Push { - url: WebSocketClientUrl::from_str(&self.chain_driver.websocket_address())?, - batch_delay: config::default::batch_delay(), - }, - rpc_timeout: config::default::rpc_timeout(), - trusted_node: false, - genesis_restart: None, - account_prefix: self.chain_driver.account_prefix.clone(), - key_name: self.wallets.relayer.id.0.clone(), - key_store_type: Store::Test, - key_store_folder: Some(hermes_keystore_dir.into()), - store_prefix: "ibc".to_string(), - default_gas: None, - max_gas: Some(3000000), - gas_adjustment: None, - gas_multiplier: Some(GasMultiplier::unsafe_new(1.5)), - dynamic_gas_price: DynamicGasPrice::default(), - fee_granter: None, - max_msg_num: Default::default(), - max_tx_size: Default::default(), - max_grpc_decoding_size: config::default::max_grpc_decoding_size(), - query_packets_chunk_size: config::default::query_packets_chunk_size(), - max_block_time: Duration::from_secs(30), - clock_drift: Duration::from_secs(5), - trusting_period: Some(Duration::from_secs(14 * 24 * 3600)), - client_refresh_rate: config::default::client_refresh_rate(), - ccv_consumer_chain: false, - trust_threshold: Default::default(), - gas_price, - packet_filter: Default::default(), - address_type: chain_type.address_type(), - memo_prefix: Default::default(), - memo_overwrite: None, - proof_specs: Default::default(), - extension_options: Default::default(), - sequential_batch_tx: false, - compat_mode, - clear_interval: None, - excluded_sequences: BTreeMap::new(), - })) + let chain_config = match chain_type { + TestedChainType::Cosmos + | TestedChainType::Provenance + | TestedChainType::Evmos + | TestedChainType::Osmosis + | TestedChainType::Injective => config::ChainConfig::CosmosSdk(CosmosSdkConfig { + id: self.chain_driver.chain_id.clone(), + rpc_addr: Url::from_str(&self.chain_driver.rpc_address())?, + grpc_addr: Url::from_str(&self.chain_driver.grpc_address())?, + event_source: config::EventSourceMode::Push { + url: WebSocketClientUrl::from_str(&self.chain_driver.websocket_address())?, + batch_delay: config::default::batch_delay(), + }, + rpc_timeout: config::default::rpc_timeout(), + trusted_node: false, + genesis_restart: None, + account_prefix: self.chain_driver.account_prefix.clone(), + key_name: self.wallets.relayer.id.0.clone(), + key_store_type: Store::Test, + key_store_folder: Some(hermes_keystore_dir.into()), + store_prefix: "ibc".to_string(), + default_gas: None, + max_gas: Some(3000000), + gas_adjustment: None, + gas_multiplier: Some(GasMultiplier::unsafe_new(1.5)), + dynamic_gas_price: DynamicGasPrice::default(), + fee_granter: None, + max_msg_num: Default::default(), + max_tx_size: Default::default(), + max_grpc_decoding_size: config::default::max_grpc_decoding_size(), + query_packets_chunk_size: config::default::query_packets_chunk_size(), + max_block_time: Duration::from_secs(30), + clock_drift: Duration::from_secs(5), + trusting_period: Some(Duration::from_secs(14 * 24 * 3600)), + client_refresh_rate: config::default::client_refresh_rate(), + ccv_consumer_chain: false, + trust_threshold: Default::default(), + gas_price, + packet_filter: Default::default(), + address_type: chain_type.address_type(), + memo_prefix: Default::default(), + memo_overwrite: None, + proof_specs: Default::default(), + extension_options: Default::default(), + sequential_batch_tx: false, + compat_mode, + clear_interval: None, + excluded_sequences: BTreeMap::new(), + }), + TestedChainType::Namada => config::ChainConfig::Namada(CosmosSdkConfig { + id: self.chain_driver.chain_id.clone(), + rpc_addr: Url::from_str(&self.chain_driver.rpc_address())?, + grpc_addr: Url::from_str(&self.chain_driver.grpc_address())?, + event_source: config::EventSourceMode::Push { + url: WebSocketClientUrl::from_str(&self.chain_driver.websocket_address())?, + batch_delay: config::default::batch_delay(), + }, + rpc_timeout: config::default::rpc_timeout(), + trusted_node: false, + genesis_restart: None, + account_prefix: "".to_owned(), + key_name: self.wallets.relayer.id.0.clone(), + key_store_type: Store::Test, + key_store_folder: Some(hermes_keystore_dir.into()), + store_prefix: "ibc".to_string(), + default_gas: None, + max_gas: Some(3000000), + gas_adjustment: None, + gas_multiplier: Some(GasMultiplier::unsafe_new(1.2)), + dynamic_gas_price: DynamicGasPrice::default(), + fee_granter: None, + max_msg_num: Default::default(), + max_tx_size: Default::default(), + max_grpc_decoding_size: config::default::max_grpc_decoding_size(), + query_packets_chunk_size: config::default::query_packets_chunk_size(), + max_block_time: Duration::from_secs(30), + clock_drift: Duration::from_secs(5), + trusting_period: Some(Duration::from_secs(1999)), + client_refresh_rate: config::default::client_refresh_rate(), + ccv_consumer_chain: false, + trust_threshold: Default::default(), + gas_price, + packet_filter: Default::default(), + address_type: chain_type.address_type(), + memo_prefix: Default::default(), + memo_overwrite: None, + proof_specs: Default::default(), + extension_options: Default::default(), + sequential_batch_tx: false, + compat_mode, + clear_interval: None, + excluded_sequences: BTreeMap::new(), + }), + }; + + Ok(chain_config) } /** @@ -217,6 +274,27 @@ impl FullNode { } } +fn get_denom(home_path: &str) -> Result { + let output = simple_exec( + "namada", + "namadaw", + &["--base-dir", home_path, "find", "--alias", "nam"], + )? + .stdout; + + let words: Vec<&str> = output.split_whitespace().collect(); + + if let Some(derived_index) = words.iter().position(|&w| w == "Established:") { + if let Some(&denom) = words.get(derived_index + 1) { + return Ok(denom.to_owned()); + } + return Err(eyre!( + "chain id is not 3 words after `Established:`: {output}" + )); + } + Err(eyre!("could not find `Derived` in output: {output}")) +} + impl ExportEnv for FullNode { fn export_env(&self, writer: &mut impl EnvWriter) { self.chain_driver.export_env(writer); diff --git a/tools/test-framework/src/types/wallet.rs b/tools/test-framework/src/types/wallet.rs index 9886c19cbe..7c22e7fac0 100644 --- a/tools/test-framework/src/types/wallet.rs +++ b/tools/test-framework/src/types/wallet.rs @@ -3,7 +3,7 @@ */ use core::fmt::{self, Display}; -use ibc_relayer::keyring::Secp256k1KeyPair; +use ibc_relayer::keyring::{AnySigningKeyPair, NamadaKeyPair, Secp256k1KeyPair}; use crate::types::env::{prefix_writer, EnvWriter, ExportEnv}; use crate::types::tagged::*; @@ -36,7 +36,7 @@ pub struct Wallet { // TODO: Parameterize this type on `SigningKeyPair` /// The wallet key information in the form of `SigningKeyPair` /// that is used by the relayer. - pub key: Secp256k1KeyPair, + pub key: AnySigningKeyPair, } /** @@ -82,7 +82,7 @@ pub trait TaggedWallet { fn address(&self) -> MonoTagged; /// Get the `SigningKeyPair` tagged with the given `Chain`. - fn key(&self) -> MonoTagged; + fn key(&self) -> MonoTagged; } /** @@ -107,11 +107,19 @@ pub trait TaggedTestWalletsExt { impl Wallet { /// Create a new [`Wallet`] - pub fn new(id: String, address: String, key: Secp256k1KeyPair) -> Self { + pub fn new_secp256(id: String, address: String, secp256_key: Secp256k1KeyPair) -> Self { Self { id: WalletId(id), address: WalletAddress(address), - key, + key: secp256_key.into(), + } + } + + pub fn new_namada(id: String, address: String, namada_key: NamadaKeyPair) -> Self { + Self { + id: WalletId(id), + address: WalletAddress(address), + key: namada_key.into(), } } } @@ -131,7 +139,7 @@ impl TaggedWallet for MonoTagged { self.map_ref(|w| &w.address) } - fn key(&self) -> MonoTagged { + fn key(&self) -> MonoTagged { self.map_ref(|w| &w.key) } } @@ -145,7 +153,7 @@ impl<'a, Chain> TaggedWallet for MonoTagged { self.map_ref(|w| &w.address) } - fn key(&self) -> MonoTagged { + fn key(&self) -> MonoTagged { self.map_ref(|w| &w.key) } } diff --git a/tools/test-framework/src/util/interchain_security.rs b/tools/test-framework/src/util/interchain_security.rs index ea66e12f4f..70a0e5da39 100644 --- a/tools/test-framework/src/util/interchain_security.rs +++ b/tools/test-framework/src/util/interchain_security.rs @@ -1,4 +1,4 @@ -use crate::chain::config::set_voting_period; +use crate::chain::config::cosmos::set_voting_period; use crate::prelude::*; use ibc_relayer::chain::tracking::TrackedMsgs; @@ -35,7 +35,7 @@ pub fn update_relayer_config_for_consumer_chain(config: &mut Config) { chain_config.ccv_consumer_chain = true; chain_config.trusting_period = Some(Duration::from_secs(99)); } - ChainConfig::CosmosSdk(_) => {} + ChainConfig::CosmosSdk(_) | ChainConfig::Namada(_) => {} } } } diff --git a/tools/test-framework/src/util/mod.rs b/tools/test-framework/src/util/mod.rs index 8fcd82a5dc..f805d23198 100644 --- a/tools/test-framework/src/util/mod.rs +++ b/tools/test-framework/src/util/mod.rs @@ -6,6 +6,7 @@ pub mod array; pub mod assert; pub mod file; pub mod interchain_security; +pub mod namada; pub mod proposal_status; pub mod random; pub mod retry; diff --git a/tools/test-framework/src/util/namada.rs b/tools/test-framework/src/util/namada.rs new file mode 100644 index 0000000000..c8f8944c40 --- /dev/null +++ b/tools/test-framework/src/util/namada.rs @@ -0,0 +1,174 @@ +use ibc_proto::Protobuf; +use ibc_relayer::consensus_state::{AnyConsensusState, AnyConsensusStateWithHeight}; +use ibc_relayer_types::core::ics04_channel::packet::Sequence; +use ibc_relayer_types::core::ics24_host::identifier::{ChannelId, ClientId, PortId}; +use ibc_relayer_types::events::IbcEventType; +use ibc_relayer_types::Height; +use itertools::Itertools; +use namada_ibc::storage::{consensus_height, consensus_state_prefix}; +use namada_sdk::events::extend::Height as HeightAttr; +use namada_sdk::queries::RPC; +use namada_sdk::storage::{Key, PrefixValue}; +use namada_sdk::tx::Tx; +use std::fs::File; +use std::io::Read; +use tendermint_rpc::{Client, HttpClient, Url}; +use toml::Value; + +use crate::prelude::*; + +pub fn get_namada_denom_address( + chain_id: &str, + home_path: &str, + denom: &str, +) -> Result { + let file_path = format!("{}/{}/wallet.toml", home_path, chain_id); + tracing::warn!("file path: {file_path}"); + let mut toml_content = String::new(); + let mut file = File::open(file_path).expect("Failed to open file"); + file.read_to_string(&mut toml_content) + .expect("Failed to read file"); + + // Parse the TOML content into a `toml::Value` object + let toml_value: Value = toml::from_str(&toml_content).expect("Failed to parse TOML"); + + // Extract a field from the TOML file + let denom_address = toml_value + .get("addresses") + .ok_or_else(|| eyre!("missing `addresses` field"))? + .get(denom) + .ok_or_else(|| eyre!("missing `{denom}` field"))? + .as_str() + .unwrap_or(denom) + .to_owned(); + + Ok(denom_address) +} + +pub async fn query_consensus_states( + rpc_address: Url, + client_id: &ClientId, +) -> Result, Error> { + // convert to that of ibc-rs + let client_id = client_id + .to_string() + .parse() + .expect("Client ID conversion shouldn't fail"); + let prefix = consensus_state_prefix(&client_id); + let mut states = vec![]; + for PrefixValue { key, value } in query_prefix(rpc_address, &prefix).await? { + let height = consensus_height(&key).expect("Key should have the height"); + let state = AnyConsensusStateWithHeight { + height: Height::new(height.revision_number(), height.revision_height()).unwrap(), + consensus_state: AnyConsensusState::decode_vec(&value) + .map_err(|_| Error::query_client())?, + }; + states.push(state); + } + Ok(states) +} + +async fn query_prefix(rpc_address: Url, prefix: &Key) -> Result, Error> { + let client = HttpClient::new(rpc_address).expect("Failed to make a RPC client"); + let response = RPC + .shell() + .storage_prefix(&client, None, None, false, prefix) + .await + .map_err(|e| eyre!("Namada query with prefix failed: {e}"))?; + Ok(response.data) +} + +pub async fn query_receive_tx_memo( + rpc_address: Url, + src_port_id: &PortId, + src_channel_id: &ChannelId, + dst_port_id: &PortId, + dst_channel_id: &ChannelId, + sequence: Sequence, +) -> Result { + let client = HttpClient::new(rpc_address).expect("Failed to make a RPC client"); + let height = query_write_ack_packet_height( + &client, + src_port_id, + src_channel_id, + dst_port_id, + dst_channel_id, + sequence, + ) + .await?; + + let response = client + .block(height) + .await + .map_err(|e| eyre!("Query a block failed: {e}"))?; + let memo: Vec = response + .block + .data + .iter() + .flat_map(|tx_bytes| { + let tx = Tx::try_from(&tx_bytes[..]) + .map_err(|e| e.to_string()) + .expect("Decoding tx failed"); + let memo: Vec = tx + .header() + .batch + .iter() + .filter_map(|cmt| { + tx.memo(cmt) + .map(|memo_bytes| String::from_utf8_lossy(&memo_bytes).to_string()) + }) + .collect(); + memo + }) + .collect(); + + // All memo should be the same for now + assert!(memo.iter().all_equal()); + + let memo = memo.first().ok_or_else(|| eyre!("No memo field"))?; + Ok(memo.to_string()) +} + +async fn query_write_ack_packet_height( + client: &HttpClient, + src_port_id: &PortId, + src_channel_id: &ChannelId, + dst_port_id: &PortId, + dst_channel_id: &ChannelId, + sequence: Sequence, +) -> Result { + let event = RPC + .shell() + .ibc_packet( + client, + &IbcEventType::WriteAck + .as_str() + .parse() + .expect("IbcEventType should be parsable"), + &src_port_id + .as_str() + .parse() + .expect("PortId should be parsable"), + &src_channel_id + .as_str() + .parse() + .expect("ChannelId should be parsable"), + &dst_port_id + .as_str() + .parse() + .expect("PortId should be parsable"), + &dst_channel_id + .as_str() + .parse() + .expect("ChannelId should be parsable"), + &u64::from(sequence).into(), + ) + .await + .map_err(|e| eyre!("Namada packet query failed: {e}"))? + .ok_or_else(|| eyre!("No write ack event"))?; + let height = event + .read_attribute::() + .expect("Height should exist"); + + Ok(Height::new(0, height.0).expect("Height conversion shouldn't fail")) +}