diff --git a/.cargo/config b/.cargo/config index 34fad86cb..e61e7526b 100644 --- a/.cargo/config +++ b/.cargo/config @@ -1,5 +1,5 @@ [alias] -wasm = "build --release --lib --target wasm32-unknown-unknown --locked --workspace --exclude ampd" +wasm = "build --release --lib --target wasm32-unknown-unknown --locked --workspace --exclude ampd --exclude integration-tests" unit-test = "test --lib" [build] diff --git a/.github/workflows/build-ampd-and-push-to-r2.yaml b/.github/workflows/build-ampd-and-push-to-r2.yaml new file mode 100644 index 000000000..f1cdb6e0a --- /dev/null +++ b/.github/workflows/build-ampd-and-push-to-r2.yaml @@ -0,0 +1,61 @@ +name: Upload ampd contracts to Cloudflare R2 bucket + +on: + push: + branches: + - main + workflow_dispatch: + inputs: + branch: + description: Github branch to checkout for compilation + required: true + default: main + type: string + + +jobs: + compile-and-upload: + name: Compile contracts and push to R2 + runs-on: ubuntu-22.04 + permissions: + contents: write + packages: write + id-token: write + steps: + - name: Determine branch + id: get-branch-name + run: | + if [ "${{ github.event_name }}" == "push" ]; then + branch="main" + else + branch="${{ inputs.branch }}" + fi + echo "branch=$branch" >> $GITHUB_OUTPUT + + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: "0" + path: axelar-amplifier + submodules: recursive + ref: ${{ steps.get-branch-name.outputs.branch }} + + - name: Compile amplifier contracts + id: compile-contracts + run: | + cd axelar-amplifier + docker run --rm -v "$(pwd)":/code --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry cosmwasm/rust-optimizer:0.15.1 + commit_hash=$(git rev-parse --short HEAD) + cd .. + mkdir -p ./artifacts/$commit_hash/ + sudo mv axelar-amplifier/artifacts/*.wasm ./artifacts/$commit_hash/ + echo "wasm-directory=./artifacts" >> $GITHUB_OUTPUT + + - uses: ryand56/r2-upload-action@latest + with: + r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} + r2-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID_CF }} + r2-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY_CF }} + r2-bucket: ${{ secrets.R2_BUCKET }} + source-dir: ${{ steps.compile-contracts.outputs.wasm-directory }} + destination-dir: ./pre-releases/ampd/contracts/ diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b07e12117..ca54b0576 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,6 +17,7 @@ on: - rewards - service-registry - voting-verifier + - monitoring dry-run: description: Dry run type: boolean @@ -48,6 +49,7 @@ jobs: ["rewards"]="rewards,/(major-rewards)|(major-contracts)/,/(minor-rewards)|(minor-contracts)/,contracts/rewards packages" ["service-registry"]="service-registry,/(major-service-registry)|(major-contracts)/,/(minor-service-registry)|(minor-contracts)/,contracts/service-registry packages" ["voting-verifier"]="voting-verifier,/(major-voting-verifier)|(major-contracts)/,/(minor-voting-verifier)|(minor-contracts)/,contracts/voting-verifier packages" + ["monitoring"]="monitoring,/(major-monitoring)|(major-contracts)/,/(minor-monitoring)|(minor-contracts)/,contracts/monitoring packages" ) if [[ -n "${binaries_data[$binary]}" ]]; then diff --git a/Cargo.lock b/Cargo.lock index cade1a4ec..9496da4b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -114,20 +114,17 @@ version = "0.1.0" dependencies = [ "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", + "client", "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", "error-stack", "integration-tests", - "itertools 0.11.0", "report 0.1.0", - "schemars", "serde", - "serde_json", "thiserror", "voting-verifier 0.1.0", ] @@ -160,7 +157,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", "once_cell", "version_check", ] @@ -172,7 +169,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.14", "once_cell", "version_check", "zerocopy", @@ -210,9 +207,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "ampd" @@ -220,6 +217,7 @@ version = "0.1.0" dependencies = [ "async-trait", "axelar-wasm-std 0.1.0", + "axum 0.7.5", "base64 0.21.7", "bcs", "borsh 1.4.0", @@ -315,7 +313,7 @@ dependencies = [ "ed25519 1.5.3", "futures", "hex", - "http", + "http 0.2.12", "matchit 0.5.0", "pin-project-lite", "pkcs8 0.9.0", @@ -324,7 +322,7 @@ dependencies = [ "rand 0.8.5", "rcgen 0.9.3", "ring 0.16.20", - "rustls 0.21.10", + "rustls 0.21.11", "rustls-webpki", "serde", "serde_json", @@ -397,9 +395,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "ark-bls12-381" @@ -485,7 +483,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "quote 1.0.35", + "quote 1.0.36", "syn 1.0.109", ] @@ -497,8 +495,8 @@ checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint 0.4.4", "num-traits", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -570,8 +568,8 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -646,8 +644,8 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "synstructure", ] @@ -658,8 +656,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -686,7 +684,7 @@ version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" dependencies = [ - "brotli", + "brotli 3.5.0", "flate2", "futures-core", "memchr", @@ -696,11 +694,11 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86a9249d1447a85f95810c620abea82e001fe58a31713fcce614caf52499f905" +checksum = "07dbbf24db18d609b1462965249abdf49129ccad073ec257da372adc83259c60" dependencies = [ - "brotli", + "brotli 4.0.0", "flate2", "futures-core", "memchr", @@ -734,9 +732,9 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -746,13 +744,13 @@ source = "git+https://github.com/mystenmark/async-task?rev=4e45b26e11126b191701b [[package]] name = "async-trait" -version = "0.1.79" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -783,9 +781,9 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -817,14 +815,15 @@ version = "0.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "error-stack", "flagset", "hex", + "lazy_static", "num-traits", "rand 0.8.5", + "regex", "report 0.1.0", "schemars", "serde", @@ -863,9 +862,9 @@ version = "0.1.0" dependencies = [ "axelar-wasm-std 0.1.0", "error-stack", - "quote 1.0.35", + "quote 1.0.36", "report 0.1.0", - "syn 2.0.57", + "syn 2.0.60", "thiserror", ] @@ -876,9 +875,9 @@ source = "git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c9 dependencies = [ "axelar-wasm-std 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "error-stack", - "quote 1.0.35", + "quote 1.0.36", "report 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", - "syn 2.0.57", + "syn 2.0.60", "thiserror", ] @@ -889,15 +888,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", - "axum-core", + "axum-core 0.3.4", "base64 0.21.7", "bitflags 1.3.2", "bytes", "futures-util", "headers", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "itoa", "matchit 0.7.3", "memchr", @@ -910,7 +909,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper", + "sync_wrapper 0.1.2", "tokio", "tokio-tungstenite", "tower", @@ -918,6 +917,40 @@ dependencies = [ "tower-service", ] +[[package]] +name = "axum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" +dependencies = [ + "async-trait", + "axum-core 0.4.3", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-util", + "itoa", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "axum-core" version = "0.3.4" @@ -927,14 +960,35 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", "tower-service", ] +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -1053,13 +1107,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.17", - "proc-macro2 1.0.79", - "quote 1.0.35", + "prettyplease 0.2.19", + "proc-macro2 1.0.81", + "quote 1.0.36", "regex", "rustc-hash", "shlex", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -1266,6 +1320,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "bnum" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" + [[package]] name = "bnum" version = "0.10.0" @@ -1315,7 +1375,7 @@ dependencies = [ "borsh-derive-internal 0.9.3", "borsh-schema-derive-internal 0.9.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.79", + "proc-macro2 1.0.81", "syn 1.0.109", ] @@ -1328,7 +1388,7 @@ dependencies = [ "borsh-derive-internal 0.10.3", "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.79", + "proc-macro2 1.0.81", "syn 1.0.109", ] @@ -1340,9 +1400,9 @@ checksum = "51670c3aa053938b0ee3bd67c3817e471e626151131b934038e83c5bf8de48f5" dependencies = [ "once_cell", "proc-macro-crate 3.1.0", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", "syn_derive", ] @@ -1352,8 +1412,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -1363,8 +1423,8 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -1374,8 +1434,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -1385,8 +1445,8 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -1398,7 +1458,18 @@ checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", - "brotli-decompressor", + "brotli-decompressor 2.5.1", +] + +[[package]] +name = "brotli" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "125740193d7fee5cc63ab9e16c2fdc4e07c74ba755cc53b327d6ea029e9fc569" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor 3.0.0", ] [[package]] @@ -1411,6 +1482,16 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "brotli-decompressor" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65622a320492e09b5e0ac436b14c54ff68199bac392d0e89a6832c4518eea525" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bs58" version = "0.4.0" @@ -1449,9 +1530,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.15.4" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bv" @@ -1471,9 +1552,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" @@ -1490,9 +1571,9 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -1584,9 +1665,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.90" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" dependencies = [ "jobserver", "libc", @@ -1615,9 +1696,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1625,7 +1706,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -1708,7 +1789,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex 0.7.0", - "strsim 0.11.0", + "strsim 0.11.1", ] [[package]] @@ -1718,9 +1799,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck 0.5.0", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -1747,6 +1828,16 @@ dependencies = [ "cc", ] +[[package]] +name = "client" +version = "0.1.0" +dependencies = [ + "cosmwasm-std", + "error-stack", + "serde", + "thiserror", +] + [[package]] name = "codespan" version = "0.11.1" @@ -1892,7 +1983,6 @@ dependencies = [ "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "error-stack", @@ -1904,12 +1994,6 @@ dependencies = [ "mockall", "rand 0.8.5", "report 0.1.0", - "schemars", - "serde", - "serde_json", - "sha3 0.10.8", - "thiserror", - "valuable", ] [[package]] @@ -1949,7 +2033,6 @@ dependencies = [ "flagset", "hex", "rand 0.8.5", - "regex", "report 0.1.0", "schemars", "serde", @@ -2102,7 +2185,7 @@ dependencies = [ "cosmos-sdk-proto 0.19.0", "ecdsa", "eyre", - "getrandom 0.2.12", + "getrandom 0.2.14", "k256", "rand_core 0.6.4", "serde", @@ -2114,9 +2197,9 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" dependencies = [ "digest 0.10.7", "ecdsa", @@ -2154,20 +2237,20 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5d803bea6bd9ed61bd1ee0b4a2eb09ee20dbb539cc6e0b8795614d20952ebb1" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "cosmwasm-std" -version = "1.5.3" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8666e572a3a2519010dde88c04d16e9339ae751b56b2bb35081fe3f7d6be74" +checksum = "ad011ae7447188e26e4a7dbca2fcd0fc186aa21ae5c86df0503ea44c78f9e469" dependencies = [ "base64 0.21.7", "bech32", - "bnum", + "bnum 0.8.1", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -2345,9 +2428,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2491,8 +2574,8 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "strsim 0.10.0", "syn 1.0.109", ] @@ -2505,10 +2588,10 @@ checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "strsim 0.10.0", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -2518,7 +2601,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" dependencies = [ "darling_core 0.14.4", - "quote 1.0.35", + "quote 1.0.36", "syn 1.0.109", ] @@ -2529,8 +2612,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core 0.20.8", - "quote 1.0.35", - "syn 2.0.57", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2594,9 +2677,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid 0.9.6", "der_derive", @@ -2624,9 +2707,9 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fe87ce4529967e0ba1dcf8450bab64d97dfd5010a6256187ffe2e43e6f0e049" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2645,8 +2728,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4255bb7dd538590188bd0aea52e48bd699b19bd90b0d069ec2ced8461fe23273" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -2662,8 +2745,8 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -2683,8 +2766,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -2705,8 +2788,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case 0.4.0", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustc_version", "syn 1.0.109", ] @@ -2804,9 +2887,9 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2827,9 +2910,9 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cbae11b3de8fce2a456e8ea3dada226b35fe791f0dc1d360c0941f0bb681f3" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -2846,9 +2929,9 @@ checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "dunce" @@ -2880,7 +2963,7 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der 0.7.9", "digest 0.10.7", "elliptic-curve", "rfc6979", @@ -2983,9 +3066,9 @@ dependencies = [ [[package]] name = "either" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" [[package]] name = "elliptic-curve" @@ -3024,9 +3107,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] @@ -3063,8 +3146,8 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -3079,13 +3162,13 @@ dependencies = [ [[package]] name = "enum-iterator-derive" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" +checksum = "c19cbb53d33b57ac4df1f0af6b92c38c107cded663c4aea9fae1189dcfc17cf5" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -3095,9 +3178,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ "once_cell", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -3279,14 +3362,14 @@ dependencies = [ "ethers-core", "ethers-etherscan", "eyre", - "prettyplease 0.2.17", - "proc-macro2 1.0.79", - "quote 1.0.35", + "prettyplease 0.2.19", + "proc-macro2 1.0.81", + "quote 1.0.36", "regex", "reqwest", "serde", "serde_json", - "syn 2.0.57", + "syn 2.0.60", "toml 0.8.12", "walkdir", ] @@ -3301,10 +3384,10 @@ dependencies = [ "const-hex", "ethers-contract-abigen", "ethers-core", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "serde_json", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -3330,7 +3413,7 @@ dependencies = [ "serde", "serde_json", "strum 0.26.2", - "syn 2.0.57", + "syn 2.0.60", "tempfile", "thiserror", "tiny-keccak", @@ -3397,7 +3480,7 @@ dependencies = [ "futures-timer", "futures-util", "hashers", - "http", + "http 0.2.12", "instant", "jsonwebtoken", "once_cell", @@ -3499,10 +3582,10 @@ version = "0.1.0" dependencies = [ "error-stack", "events", - "quote 1.0.35", + "quote 1.0.36", "serde", "serde_json", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -3577,8 +3660,8 @@ version = "0.1.3" source = "git+https://github.com/MystenLabs/fastcrypto?rev=69180dc7275f5f0efb69e11e9d03f6db338d1dd6#69180dc7275f5f0efb69e11e9d03f6db338d1dd6" dependencies = [ "convert_case 0.6.0", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -3690,8 +3773,8 @@ dependencies = [ "num-bigint 0.3.3", "num-integer", "num-traits", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -3888,9 +3971,9 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -3949,18 +4032,16 @@ dependencies = [ "aggregate-verifier 0.1.0", "axelar-wasm-std 0.1.0", "axelar-wasm-std-derive 0.1.0", + "client", "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "error-stack", "gateway-api", "itertools 0.11.0", - "mockall", "report 0.1.0", - "schemars", "serde", "serde_json", "thiserror", @@ -4034,9 +4115,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "js-sys", @@ -4089,7 +4170,7 @@ dependencies = [ "base64 0.21.7", "bcs", "bimap", - "bnum", + "bnum 0.10.0", "borsh 1.4.0", "bytemuck", "connection-router 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", @@ -4134,16 +4215,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fbd2820c5e49886948654ab546d0688ff24530286bdcf8fca3cefb16d4618eb" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", "indexmap 2.2.6", "slab", "tokio", @@ -4229,7 +4310,7 @@ dependencies = [ "base64 0.21.7", "bytes", "headers-core", - "http", + "http 0.2.12", "httpdate", "mime", "sha1", @@ -4241,7 +4322,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" dependencies = [ - "http", + "http 0.2.12", ] [[package]] @@ -4354,6 +4435,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -4361,7 +4453,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -4410,8 +4525,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -4423,6 +4538,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + [[package]] name = "hyper-proxy" version = "0.9.1" @@ -4432,8 +4566,8 @@ dependencies = [ "bytes", "futures", "headers", - "http", - "hyper", + "http 0.2.12", + "hyper 0.14.28", "hyper-rustls 0.22.1", "rustls-native-certs 0.5.0", "tokio", @@ -4450,7 +4584,7 @@ checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" dependencies = [ "ct-logs", "futures-util", - "hyper", + "hyper 0.14.28", "log", "rustls 0.19.1", "rustls-native-certs 0.5.0", @@ -4467,9 +4601,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ "futures-util", - "http", - "hyper", - "rustls 0.21.10", + "http 0.2.12", + "hyper 0.14.28", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", ] @@ -4480,12 +4614,28 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.28", "pin-project-lite", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.3.1", + "pin-project-lite", + "socket2 0.5.6", + "tokio", +] + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -4592,8 +4742,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -4676,32 +4826,24 @@ dependencies = [ name = "integration-tests" version = "0.1.0" dependencies = [ - "aggregate-verifier 0.1.0", "axelar-wasm-std 0.1.0", - "axelar-wasm-std-derive 0.1.0", "connection-router 0.1.0", "connection-router-api", - "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", - "cw-storage-plus 1.2.0", "error-stack", "gateway 0.1.0", "gateway-api", - "itertools 0.11.0", "k256", - "mockall", + "monitoring", "multisig 0.1.0", "multisig-prover 0.1.0", "report 0.1.0", "rewards 0.1.0", - "schemars", "serde", "serde_json", "service-registry 0.1.0", "sha3 0.10.8", - "thiserror", "tofn", "voting-verifier 0.1.0", ] @@ -4769,9 +4911,9 @@ checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.28" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6" +checksum = "685a7d121ee3f65ae4fddd72b25a04bb36b6af81bc0828f7d5434c0fe60fa3a2" dependencies = [ "libc", ] @@ -4836,9 +4978,9 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.1" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" dependencies = [ "cfg-if", "ecdsa", @@ -4915,7 +5057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" dependencies = [ "cfg-if", - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -5257,8 +5399,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -5271,13 +5413,13 @@ dependencies = [ "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "error-stack", "integration-tests", "multisig 0.1.0", "report 0.1.0", + "thiserror", ] [[package]] @@ -5415,7 +5557,7 @@ dependencies = [ "ethnum", "hex", "move-proc-macros", - "num 0.4.1", + "num 0.4.2", "once_cell", "primitive-types 0.10.1", "rand 0.8.5", @@ -5475,7 +5617,7 @@ dependencies = [ "log", "move-compiler", "move-model", - "num 0.4.1", + "num 0.4.2", "once_cell", "regex", "serde", @@ -5544,7 +5686,7 @@ dependencies = [ "move-disassembler", "move-ir-types", "move-symbol-pool", - "num 0.4.1", + "num 0.4.2", "once_cell", "regex", "serde", @@ -5588,8 +5730,8 @@ version = "0.1.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ "enum-compat-util", - "quote 1.0.35", - "syn 2.0.57", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -5683,8 +5825,8 @@ version = "0.1.0" source = "git+https://github.com/MystenLabs/mysten-sim.git?rev=1a52783d6600ecc22e15253a982f77881bd47c77#1a52783d6600ecc22e15253a982f77881bd47c77" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -5737,8 +5879,8 @@ checksum = "1d6d4752e6230d8ef7adf7bd5d8c4b1f6561c1014c5ba9a37445ccefe18aa1db" dependencies = [ "proc-macro-crate 1.1.3", "proc-macro-error", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "synstructure", ] @@ -5759,17 +5901,16 @@ dependencies = [ "cosmwasm-crypto", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", + "curve25519-dalek 4.1.2", "cw-multi-test", "cw-storage-plus 1.2.0", "ed25519-dalek 2.1.1", "enum-display-derive", "error-stack", - "getrandom 0.2.12", + "getrandom 0.2.14", "k256", "report 0.1.0", "rewards 0.1.0", - "schemars", "serde", "serde_json", "sha3 0.10.8", @@ -5792,7 +5933,7 @@ dependencies = [ "cw-storage-plus 1.2.0", "enum-display-derive", "error-stack", - "getrandom 0.2.12", + "getrandom 0.2.14", "k256", "report 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", "rewards 0.1.0 (git+https://github.com/axelarnetwork/axelar-amplifier?rev=c0904e1c72c99a174a93b5f6c18b30f52d20b71f)", @@ -5814,11 +5955,9 @@ dependencies = [ "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "cw-utils 1.0.3", - "either", "elliptic-curve", "error-stack", "ethabi", @@ -5829,10 +5968,9 @@ dependencies = [ "hex", "itertools 0.11.0", "k256", + "monitoring", "multisig 0.1.0", "report 0.1.0", - "schemars", - "serde", "serde_json", "service-registry 0.1.0", "sha3 0.10.8", @@ -5878,7 +6016,7 @@ version = "0.7.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ "async-trait", - "axum", + "axum 0.6.20", "dashmap", "futures", "once_cell", @@ -5903,7 +6041,7 @@ dependencies = [ "bytes", "eyre", "futures", - "http", + "http 0.2.12", "multiaddr", "serde", "snap", @@ -5942,7 +6080,7 @@ name = "mysten-util-mem-derive" version = "0.1.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ - "proc-macro2 1.0.79", + "proc-macro2 1.0.81", "syn 1.0.109", "synstructure", "workspace-hack", @@ -6100,9 +6238,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" dependencies = [ "num-bigint 0.4.4", "num-complex 0.4.5", @@ -6194,8 +6332,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -6205,9 +6343,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6299,9 +6437,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6311,9 +6449,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ "proc-macro-crate 3.1.0", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6372,8 +6510,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ "bytes", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -6424,9 +6562,9 @@ checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6502,8 +6640,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1557010476e0595c9b568d16dcfb81b93cdeb157612726f5170d31aa707bed27" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -6514,8 +6652,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" dependencies = [ "proc-macro-crate 2.0.0", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -6643,8 +6781,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" dependencies = [ "peg-runtime", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", ] [[package]] @@ -6697,9 +6835,9 @@ dependencies = [ [[package]] name = "pest" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f8023d0fb78c8e03784ea1c7f3fa36e68a723138990b8d5a47d916b651e7a8" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" dependencies = [ "memchr", "thiserror", @@ -6708,9 +6846,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0d24f72393fd16ab6ac5738bc33cdb6a9aa73f8b902e8fe29cf4e67d7dd1026" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" dependencies = [ "pest", "pest_generator", @@ -6718,22 +6856,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc17e2a6c7d0a492f0158d7a4bd66cc17280308bbaff78d5bef566dca35ab80" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] name = "pest_meta" -version = "2.7.8" +version = "2.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934cd7631c050f4674352a6e835d5f6711ffbfb9345c2fc0107155ac495ae293" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" dependencies = [ "once_cell", "pest", @@ -6798,9 +6936,9 @@ checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" dependencies = [ "phf_generator", "phf_shared 0.11.2", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6836,9 +6974,9 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -6892,7 +7030,7 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", + "der 0.7.9", "spki 0.7.3", ] @@ -6998,18 +7136,18 @@ version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" dependencies = [ - "proc-macro2 1.0.79", + "proc-macro2 1.0.81", "syn 1.0.109", ] [[package]] name = "prettyplease" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3928fb5db768cb86f891ff014f0144589297e3c6a1aba6ed7cecfdace270c7" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ - "proc-macro2 1.0.79", - "syn 2.0.57", + "proc-macro2 1.0.81", + "syn 2.0.60", ] [[package]] @@ -7091,8 +7229,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "version_check", ] @@ -7103,8 +7241,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "version_check", ] @@ -7119,9 +7257,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -7215,12 +7353,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.12.4", ] [[package]] @@ -7253,8 +7391,8 @@ checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -7266,22 +7404,22 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools 0.10.5", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.11.0", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "itertools 0.12.1", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -7317,9 +7455,9 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e2e25ee72f5b24d773cae88422baddefff7714f97aab68d96fe2b6fc4a28fb2" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -7340,7 +7478,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.21.10", + "rustls 0.21.11", "thiserror", "tokio", "tracing", @@ -7356,7 +7494,7 @@ dependencies = [ "rand 0.8.5", "ring 0.16.20", "rustc-hash", - "rustls 0.21.10", + "rustls 0.21.11", "rustls-native-certs 0.6.3", "slab", "thiserror", @@ -7388,11 +7526,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "proc-macro2 1.0.79", + "proc-macro2 1.0.81", ] [[package]] @@ -7466,7 +7604,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", ] [[package]] @@ -7555,9 +7693,9 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a25d631e41bfb5fdcde1d4e2215f62f7f0afa3ff11e26563765bd6ea1d229aeb" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -7593,7 +7731,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", "libredox", "thiserror", ] @@ -7613,9 +7751,9 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -7676,16 +7814,16 @@ version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "async-compression 0.4.7", + "async-compression 0.4.8", "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-rustls 0.24.2", "ipnet", "js-sys", @@ -7694,12 +7832,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.10", + "rustls 0.21.11", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper", + "sync_wrapper 0.1.2", "system-configuration", "tokio", "tokio-rustls 0.24.1", @@ -7726,9 +7864,7 @@ dependencies = [ "cw-storage-plus 1.2.0", "error-stack", "itertools 0.11.0", - "mockall", "report 0.1.0", - "serde", "thiserror", ] @@ -7783,7 +7919,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.14", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -7816,8 +7952,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -7968,9 +8104,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", "ring 0.17.8", @@ -8023,9 +8159,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "rusty-fork" @@ -8065,9 +8201,9 @@ dependencies = [ [[package]] name = "scale-info" -version = "2.11.1" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788745a868b0e751750388f4e6546eb921ef714a4317fa6954f7cde114eb2eb7" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" dependencies = [ "cfg-if", "derive_more", @@ -8077,13 +8213,13 @@ dependencies = [ [[package]] name = "scale-info-derive" -version = "2.11.1" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc2f4e8bc344b9fc3d5f74f72c2e55bfc38d28dc2ebc69c194a3df424e4d9ac" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -8115,8 +8251,8 @@ version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "serde_derive_internals", "syn 1.0.109", ] @@ -8142,9 +8278,9 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -8186,7 +8322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der 0.7.8", + "der 0.7.9", "generic-array", "pkcs8 0.10.2", "subtle", @@ -8259,9 +8395,9 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" [[package]] name = "serde" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" dependencies = [ "serde_derive", ] @@ -8316,13 +8452,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.198" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -8331,16 +8467,16 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "indexmap 2.2.6", "itoa", @@ -8360,13 +8496,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -8431,9 +8567,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ "darling 0.20.8", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -8443,9 +8579,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6561dc161a9224638a31d876ccdfefbc1df91d3f3a8342eddb35f055d48c7655" dependencies = [ "darling 0.20.8", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -8469,7 +8605,6 @@ dependencies = [ "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", "error-stack", @@ -8477,7 +8612,6 @@ dependencies = [ "report 0.1.0", "schemars", "serde", - "serde_json", "thiserror", ] @@ -8632,7 +8766,6 @@ version = "0.1.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "error-stack", "thiserror", ] @@ -8714,9 +8847,9 @@ dependencies = [ [[package]] name = "solana-account-decoder" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5f49893e9e7cd1a45869e03ad6d767666544e47aa39cff5bcfd10c9b156177" +checksum = "ff098f24024f1046d9ba778c48b9a68c590c15cf5c42af67e2578a240fb141a4" dependencies = [ "Inflector", "base64 0.21.7", @@ -8739,9 +8872,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce8528b2853d64e0b27889948e9f41b264d758074be9d9b8ba4e0ddce7c476dd" +checksum = "751789b7c7a3d78afe7f1ddbf48942463253167e67e85034a9695e0a05fba63e" dependencies = [ "chrono", "clap 2.34.0", @@ -8756,9 +8889,9 @@ dependencies = [ [[package]] name = "solana-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914b2b8e68c4b57a916400a77a66078a96b2914d7b218572ef8dff5a84e48ea2" +checksum = "ae5a780ff360acc9794d6e7fae8cd449c0b01bb5f0cec9c4bd8b0e6c6d111487" dependencies = [ "async-trait", "bincode", @@ -8789,9 +8922,9 @@ dependencies = [ [[package]] name = "solana-config-program" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617228f9569238e544b526c422b632de368a5ce748a7af04f7f762bd937f42f3" +checksum = "3fd4f18daab90c2f703da8dc094b1dc80721178977302d66d21df43e61b4a97b" dependencies = [ "bincode", "chrono", @@ -8803,9 +8936,9 @@ dependencies = [ [[package]] name = "solana-connection-cache" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec06c0772e0ebc54d22626ddb433eb798404fdc21b0175ac504f5fff4e50612" +checksum = "9a7b949fb3d3abc092b0c1dfb437a63d3cb7968f92d74820ef46732093517083" dependencies = [ "async-trait", "bincode", @@ -8825,9 +8958,9 @@ dependencies = [ [[package]] name = "solana-frozen-abi" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc46edad65d122c8b8634aa9ad11276a804c1aa2404755577fdfdea67484b620" +checksum = "3b8177685ab2bc8cc8b3bf63aa1eaa0580d5af850ecefac323ca1c2473085d77" dependencies = [ "block-buffer 0.10.4", "bs58 0.4.0", @@ -8850,21 +8983,21 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c71c603d2203da423cfd8862572ffca7165268e76cab181035f50d106c3710eb" +checksum = "4a68241cad17b74c6034a68ba4890632d409a2c886e7bead9c1e1432befdb7c9" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustc_version", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] name = "solana-logger" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5b3eef85d82c2c3030acb1d3272d77984d118d2a026d9b1a2cecc6e4c6602eb" +checksum = "fea560989ef67ba4a1a0fd62a248721f1aa5bac8fa5ede9ccf4fe9ee484ccadf" dependencies = [ "env_logger", "lazy_static", @@ -8873,9 +9006,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd072023ab870dcb7d524980d9481317bfd29c1dfd74a067747c8d1d249d1075" +checksum = "2abdc65120ba03eac69a668c0085166e969ea6717aee1f5b0a2ffbdd07afe7a6" dependencies = [ "log", "solana-sdk", @@ -8883,9 +9016,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f594ca2a2698983b515580925d10be20b079617154bbed07d6cd455d1661b90" +checksum = "6e4874fea432f89b6ef0902fdada2cbca715b094419897dcfc7ef82d88b0a308" dependencies = [ "crossbeam-channel", "gethostname", @@ -8898,9 +9031,9 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e632ad2071b8c911baf873403273c574bb11da95947e2f56db4e53ef06b771fe" +checksum = "05afd6080d20db4dc862603178535c7d648cba7462ca23241ff5670fb0026d38" dependencies = [ "bincode", "clap 3.2.25", @@ -8920,9 +9053,9 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3012434718bf3e76ef46cbf3be98a2de877afe7bff6571232d64cc67dce219a" +checksum = "cff0f2ea9735a5452a3fe837c61f30231c8f5b455a2b12665d3bb6e0c56e49c8" dependencies = [ "ahash 0.8.11", "bincode", @@ -8949,9 +9082,9 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760e9e923050f30f03a159aec9ba1fe09ae7c7494ebd8ba74dc5b7429b11085b" +checksum = "8bddf573103c890b4ab8f9a6641d4f969d4148bce9a451c263f4a62afa949fae" dependencies = [ "ark-bn254", "ark-ec", @@ -8971,7 +9104,7 @@ dependencies = [ "console_error_panic_hook", "console_log", "curve25519-dalek 3.2.1", - "getrandom 0.2.12", + "getrandom 0.2.14", "itertools 0.10.5", "js-sys", "lazy_static", @@ -9004,9 +9137,9 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a61b65be846413bc504ecae468b6a3fa91b1b37631c80074c41ada8cdc36d165" +checksum = "e22d035b370d65bff46c7d7582a1619c4edac8e8059e2dec0e151df09882c7b3" dependencies = [ "base64 0.21.7", "bincode", @@ -9032,9 +9165,9 @@ dependencies = [ [[package]] name = "solana-pubsub-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4173029a0e3a20930791886dce92c1a6d293a59754e418ac68547f3e14a8f025" +checksum = "f1b3aaa906f6b222be23423a0dd5deed254f092d27ad3bc05371acd9685d2db0" dependencies = [ "crossbeam-channel", "futures-util", @@ -9057,9 +9190,9 @@ dependencies = [ [[package]] name = "solana-quic-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae1b9224efc32579fe61a9e06dc8efb2a3cd167c458091cc093086304441285" +checksum = "82e75ba7e460865a7f556d7b7bc59e70c049eab4448bf2528bed1c5e5a1b672d" dependencies = [ "async-mutex", "async-trait", @@ -9070,7 +9203,7 @@ dependencies = [ "quinn", "quinn-proto", "rcgen 0.10.0", - "rustls 0.21.10", + "rustls 0.21.11", "solana-connection-cache", "solana-measure", "solana-metrics", @@ -9084,9 +9217,9 @@ dependencies = [ [[package]] name = "solana-rayon-threadlimit" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9460642bcb89090dcc15ecf11b6c4a1994c538ba49a4c5d99023365600631009" +checksum = "5a6ccb1910cc9efd4bae450d18a57c387e51ebebade1bd9bdf006ae539dd012f" dependencies = [ "lazy_static", "num_cpus", @@ -9094,9 +9227,9 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3de3b65d0fdbf0b2de6dc9aecac03d79ea7ef11c29efbdd67bf17a13d061a95" +checksum = "24cda66f8ed8860870cd4bf26235fb7fd08d8e5a75a4fce26b279c8d5c9db81f" dependencies = [ "console", "dialoguer", @@ -9113,9 +9246,9 @@ dependencies = [ [[package]] name = "solana-rpc-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b27d16eaebd5889c4dd873d715be0bad4651a0bc2509ba99ec6fc7d3b3416278" +checksum = "efae5c8740d8eb49e504e728de10aed0a5ddc53af3004b32ecdea2f7ca12c97b" dependencies = [ "async-trait", "base64 0.21.7", @@ -9139,9 +9272,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-api" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82323f7b130105a4789101b5e7d97142110774ee06aa84346effa661898d407" +checksum = "cdd1597ebe177b6fd68a9b33b682a5f0c9445c02be3783e7f51e570cbbbb3aa4" dependencies = [ "base64 0.21.7", "bs58 0.4.0", @@ -9161,9 +9294,9 @@ dependencies = [ [[package]] name = "solana-rpc-client-nonce-utils" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092867e337f366d1b719d28b4e02cffff4734cbbf9945daf5f172715db378e2c" +checksum = "1ae385b37c59a8507b9871d5162ea7709206360a55cf2859adb4274be4a870e1" dependencies = [ "clap 2.34.0", "solana-clap-utils", @@ -9174,9 +9307,9 @@ dependencies = [ [[package]] name = "solana-sdk" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1788023924ebb072288868f8b4b72f5459c1ff653238d769700da9c8043a8aea" +checksum = "08b24b06fa176209ddb2a2f8172a00b07e8a3b18229fbfc49f1eb3ce6ad11ff1" dependencies = [ "assert_matches", "base64 0.21.7", @@ -9229,15 +9362,15 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3b24f46820e8912b81719a828a3d05f4fbd2f6afdc13826b0327df065ab795" +checksum = "869483c05f18d37d4d95a08d9e05e00a4f76a8c8349aeedeee9ba2d013cbacde" dependencies = [ "bs58 0.4.0", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustversion", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -9248,9 +9381,9 @@ checksum = "468aa43b7edb1f9b7b7b686d5c3aeb6630dc1708e86e31343499dd5c4d775183" [[package]] name = "solana-streamer" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7403972b4233b87598c0a8e8fac26db549f8cb18076d385b8ef8deb1e36a6bc3" +checksum = "b76711141dd5b052e29e4825b33cf09ca9cf3987b8ac0c703d36e3d80ad5dc91" dependencies = [ "async-channel", "bytes", @@ -9269,7 +9402,8 @@ dependencies = [ "quinn-proto", "rand 0.8.5", "rcgen 0.10.0", - "rustls 0.21.10", + "rustls 0.21.11", + "smallvec", "solana-metrics", "solana-perf", "solana-sdk", @@ -9280,9 +9414,9 @@ dependencies = [ [[package]] name = "solana-thin-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63740969c229c77306024ed3ad809fabc0a1269cfe75a9c982c7cbd20c38d26" +checksum = "21b6b476b4572453f93a9827fa9312537b8a8ed253006919ab17d921b271b125" dependencies = [ "bincode", "log", @@ -9295,9 +9429,9 @@ dependencies = [ [[package]] name = "solana-tpu-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f910ac2556498a889d393309110bf4ec7607208104b40260df822e925fce933" +checksum = "9cfa13af3f54db31bde6f2d5462588f03be95f7cf66610d5942e7b52e556d1d9" dependencies = [ "async-trait", "bincode", @@ -9319,9 +9453,9 @@ dependencies = [ [[package]] name = "solana-transaction-status" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5fa023f9a09216e809bf28c1dc16c8dfce726dfa64133f9016e8a1f01267f39" +checksum = "5b5614e42e4d5a8b15e4553b68008788fae3a0dbc1a3672b62e9574252579536" dependencies = [ "Inflector", "base64 0.21.7", @@ -9344,9 +9478,9 @@ dependencies = [ [[package]] name = "solana-udp-client" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e15df3333f480774a47da0d3af3e7b9c78a3417f949bb99ed7a16dd33a906d4" +checksum = "22a37626fc851db74838725fc1034a71f2b2445149d93e45884ae366c6d85d61" dependencies = [ "async-trait", "solana-connection-cache", @@ -9359,9 +9493,9 @@ dependencies = [ [[package]] name = "solana-version" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99147bd36e5ccc2e046bc3ef8af9517da1f34c255536e3aeaf0abc383a9f37ed" +checksum = "7c23651369dd7278308c988078adeb593a37560abd0f728f70e768e12fa4b507" dependencies = [ "log", "rustc_version", @@ -9375,9 +9509,9 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6071a7f57e03c9d1b55ae4a96fbc55b0df0f97c3153df1dc0c9521ea823bb2b" +checksum = "6f0bab220b03482b90aa1781f7c4d4f073c7c9e7eafe6759d07a1b3efee6e315" dependencies = [ "bincode", "log", @@ -9397,9 +9531,9 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.18.9" +version = "1.18.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76cba1f80c9001dc788655f2d7d5671af55c7a0a49b95de819f2fc45d8b803b0" +checksum = "459c27f7b954798677d8243aa53b8080cfb314ecfecbf8889a5a65c91ad11fee" dependencies = [ "aes-gcm-siv", "base64 0.21.7", @@ -9496,7 +9630,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "der 0.7.9", ] [[package]] @@ -9532,9 +9666,9 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" dependencies = [ - "quote 1.0.35", + "quote 1.0.36", "spl-discriminator-syn", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -9543,10 +9677,10 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "sha2 0.10.8", - "syn 2.0.57", + "syn 2.0.60", "thiserror", ] @@ -9591,10 +9725,10 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "sha2 0.10.8", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -9739,9 +9873,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strsim" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -9777,8 +9911,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustversion", "syn 1.0.109", ] @@ -9790,10 +9924,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustversion", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -9803,10 +9937,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "rustversion", - "syn 2.0.57", + "syn 2.0.60", ] [[package]] @@ -9947,10 +10081,10 @@ version = "0.7.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ "msim-macros", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "sui-enum-compat-util", - "syn 2.0.57", + "syn 2.0.60", "workspace-hack", ] @@ -9974,8 +10108,8 @@ name = "sui-protocol-config-macros" version = "0.1.0" source = "git+https://github.com/mystenlabs/sui?tag=mainnet-v1.14.2#299cbeafbb6aa5601e08f00ac24bd647c61a63e2" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "workspace-hack", ] @@ -10091,19 +10225,19 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.57" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "unicode-ident", ] @@ -10114,9 +10248,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -10125,14 +10259,20 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "synstructure" version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", "unicode-xid 0.2.4", ] @@ -10177,8 +10317,8 @@ checksum = "99f688a08b54f4f02f0a3c382aefdb7884d3d69609f785bd253dc033243e3fe4" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -10334,9 +10474,9 @@ dependencies = [ "bytes", "flex-error", "futures", - "getrandom 0.2.12", - "http", - "hyper", + "getrandom 0.2.14", + "http 0.2.12", + "hyper 0.14.28", "hyper-proxy", "hyper-rustls 0.22.1", "peg", @@ -10415,9 +10555,9 @@ version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -10441,9 +10581,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.34" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", @@ -10462,9 +10602,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ "num-conv", "time-core", @@ -10520,7 +10660,7 @@ source = "git+https://github.com/axelarnetwork/tofn.git?branch=update-deps#88285 dependencies = [ "bincode", "crypto-bigint", - "der 0.7.8", + "der 0.7.9", "ecdsa", "ed25519 2.2.3", "ed25519-dalek 2.1.1", @@ -10568,9 +10708,9 @@ name = "tokio-macros" version = "2.1.0" source = "git+https://github.com/mystenmark/tokio-madsim-fork.git?rev=e4693500118d5e79ce098ee6dfc2c48f3ef19e45#e4693500118d5e79ce098ee6dfc2c48f3ef19e45" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -10579,9 +10719,9 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -10601,7 +10741,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.11", "tokio", ] @@ -10625,7 +10765,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.10", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", "tungstenite", @@ -10681,7 +10821,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.12", ] [[package]] @@ -10717,15 +10857,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ "indexmap 2.2.6", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.5", + "winnow 0.6.6", ] [[package]] @@ -10736,15 +10876,15 @@ checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" dependencies = [ "async-stream", "async-trait", - "axum", + "axum 0.6.20", "base64 0.13.1", "bytes", "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-timeout", "percent-encoding", "pin-project", @@ -10768,18 +10908,18 @@ checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" dependencies = [ "async-stream", "async-trait", - "axum", + "axum 0.6.20", "base64 0.21.7", "bytes", "h2", - "http", - "http-body", - "hyper", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.28", "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.12.3", - "rustls 0.21.10", + "prost 0.12.4", + "rustls 0.21.11", "rustls-pemfile", "tokio", "tokio-rustls 0.24.1", @@ -10797,9 +10937,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" dependencies = [ "prettyplease 0.1.25", - "proc-macro2 1.0.79", + "proc-macro2 1.0.81", "prost-build", - "quote 1.0.35", + "quote 1.0.36", "syn 1.0.109", ] @@ -10810,7 +10950,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f80db390246dfb46553481f6024f0082ba00178ea495dbb99e70ba9a4fafb5e1" dependencies = [ "async-stream", - "prost 0.12.3", + "prost 0.12.4", "tokio", "tokio-stream", "tonic 0.10.2", @@ -10849,8 +10989,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.12", + "http-body 0.4.6", "http-range-header", "httpdate", "iri-string", @@ -10897,9 +11037,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -10970,8 +11110,8 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b79e2e9c9ab44c6d7c20d5976961b47e8f49ac199154daa514b77cd1ab536625" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -10996,11 +11136,11 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.12", "httparse", "log", "rand 0.8.5", - "rustls 0.21.10", + "rustls 0.21.11", "sha1", "thiserror", "url", @@ -11206,7 +11346,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", "serde", ] @@ -11216,7 +11356,7 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", "rand 0.8.5", ] @@ -11235,8 +11375,8 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d44690c645190cfce32f91a1582281654b2338c6073fa250b0949fd25c55b32" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", + "proc-macro2 1.0.81", + "quote 1.0.36", "syn 1.0.109", ] @@ -11256,7 +11396,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124" dependencies = [ - "quote 1.0.35", + "quote 1.0.36", "syn 1.0.109", ] @@ -11293,19 +11433,14 @@ dependencies = [ "connection-router-api", "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cw-multi-test", "cw-storage-plus 1.2.0", - "either", "error-stack", "integration-tests", "report 0.1.0", "rewards 0.1.0", - "schemars", - "serde", "serde_json", "service-registry 0.1.0", - "sha3 0.10.8", "thiserror", ] @@ -11398,9 +11533,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -11422,7 +11557,7 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ - "quote 1.0.35", + "quote 1.0.36", "wasm-bindgen-macro-support", ] @@ -11432,9 +11567,9 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11555,7 +11690,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -11573,7 +11708,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.5", ] [[package]] @@ -11593,17 +11728,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -11614,9 +11750,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -11626,9 +11762,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -11638,9 +11774,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -11650,9 +11792,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -11662,9 +11804,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -11674,9 +11816,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -11686,9 +11828,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" @@ -11701,9 +11843,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.6.5" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352" dependencies = [ "memchr", ] @@ -11815,9 +11957,9 @@ version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] @@ -11835,9 +11977,9 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.79", - "quote 1.0.35", - "syn 2.0.57", + "proc-macro2 1.0.81", + "quote 1.0.36", + "syn 2.0.60", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 476599bc5..3dc1acd8e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,9 +7,8 @@ rust-version = "1.75.0" # be sure there is an optimizer release supporting this [workspace.dependencies] connection-router = { version = "^0.1.0", path = "contracts/connection-router" } -cosmwasm-std = "1.5.3" -cosmwasm-schema = "1.3.3" -cosmwasm-storage = "1.3.3" +cosmwasm-std = "1.3.4" +cosmwasm-schema = "1.3.4" cw-storage-plus = "1.1.0" error-stack = { version = "0.4.0", features = ["eyre"] } events = { version = "^0.1.0", path = "packages/events" } @@ -30,6 +29,7 @@ gateway-api = { version = "^0.1.0", path = "packages/gateway-api" } connection-router-api = { version = "^0.1.0", path = "packages/connection-router-api" } report = { version = "^0.1.0", path = "packages/report" } +client = { version = "^0.1.0", path = "packages/client" } rewards = { version = "^0.1.0", path = "contracts/rewards" } thiserror = "1.0.47" serde = { version = "1.0.145", default-features = false, features = ["derive"] } diff --git a/ampd/Cargo.lock b/ampd/Cargo.lock deleted file mode 100644 index aac71e8a7..000000000 --- a/ampd/Cargo.lock +++ /dev/null @@ -1,5672 +0,0 @@ -# This file is automatically @generated by Cargo. -# 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 = "addr2line" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "aes" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "aho-corasick" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" -dependencies = [ - "memchr", -] - -[[package]] -name = "ampd" -version = "0.1.0" -dependencies = [ - "async-trait", - "axelar-wasm-std", - "base64 0.21.2", - "clap", - "config", - "connection-router", - "cosmos-sdk-proto 0.16.0", - "cosmrs", - "cosmwasm-std", - "deref-derive", - "ecdsa 0.16.7", - "enum-display-derive", - "error-stack", - "ethers", - "futures", - "hex", - "humantime-serde", - "k256 0.13.1", - "mockall", - "multisig", - "prost", - "rand", - "random-string", - "serde", - "serde_json", - "serde_with", - "tendermint 0.33.0", - "tendermint-rpc", - "thiserror", - "tokio", - "tokio-stream", - "tokio-util", - "toml 0.5.11", - "tonic", - "tonic-build", - "tracing", - "tracing-core", - "tracing-subscriber", - "url", - "valuable", - "voting-verifier", -] - -[[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.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is-terminal", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" - -[[package]] -name = "anstyle-parse" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "anstyle-wincon" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" -dependencies = [ - "anstyle", - "windows-sys 0.48.0", -] - -[[package]] -name = "anyhow" -version = "1.0.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cb2f989d18dd141ab8ae82f64d1a8cdd37e0840f73a406896cf5e99502fab61" - -[[package]] -name = "arrayvec" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" -dependencies = [ - "async-stream-impl", - "futures-core", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "async-trait" -version = "0.1.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[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", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "auto_impl" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - -[[package]] -name = "axelar-wasm-std" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "flagset", - "num-traits", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "axum" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13d8068b6ccb8b34db9de397c7043f91db8b4c66414952c6db944f238c4d3db3" -dependencies = [ - "async-trait", - "axum-core", - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2f958c80c248b34b9a877a643811be8dbca03ca5ba827f2b63baf3a81e5fc4e" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.68" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" - -[[package]] -name = "base64ct" -version = "1.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" - -[[package]] -name = "bech32" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bip32" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e40748d60a3296653e45e87e64c6989aebfad607bccce59cc4156c5d81b2f70" -dependencies = [ - "bs58", - "hmac", - "k256 0.13.1", - "once_cell", - "pbkdf2 0.12.1", - "rand_core 0.6.4", - "ripemd", - "sha2 0.10.6", - "subtle", - "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 = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitvec" -version = "0.17.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" -dependencies = [ - "either", - "radium 0.3.0", -] - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium 0.7.0", - "tap", - "wyz", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bnum" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" - -[[package]] -name = "bs58" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" -dependencies = [ - "sha2 0.9.9", -] - -[[package]] -name = "bumpalo" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -dependencies = [ - "serde", -] - -[[package]] -name = "bzip2" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfa25e60aea747ec7e1124f238816749faa93759c6ff5b31f1ccdda137f4479" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cc" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -dependencies = [ - "jobserver", -] - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chrono" -version = "0.4.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "serde", - "winapi", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "clap" -version = "4.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" -dependencies = [ - "clap_builder", - "clap_derive", - "once_cell", -] - -[[package]] -name = "clap_builder" -version = "4.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" -dependencies = [ - "anstream", - "anstyle", - "bitflags", - "clap_lex", - "once_cell", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "clap_lex" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" - -[[package]] -name = "coins-bip32" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b30a84aab436fcb256a2ab3c80663d8aec686e6bae12827bb05fef3e1e439c9f" -dependencies = [ - "bincode", - "bs58", - "coins-core", - "digest 0.10.6", - "getrandom", - "hmac", - "k256 0.13.1", - "lazy_static", - "serde", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "coins-bip39" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f4d04ee18e58356accd644896aeb2094ddeafb6a713e056cef0c0a8e468c15" -dependencies = [ - "bitvec 0.17.4", - "coins-bip32", - "getrandom", - "hmac", - "once_cell", - "pbkdf2 0.12.1", - "rand", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "coins-core" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b949a1c63fb7eb591eb7ba438746326aedf0ae843e51ec92ba6bec5bb382c4f" -dependencies = [ - "base64 0.21.2", - "bech32", - "bs58", - "digest 0.10.6", - "generic-array", - "hex", - "ripemd", - "serde", - "serde_derive", - "sha2 0.10.6", - "sha3", - "thiserror", -] - -[[package]] -name = "colorchoice" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" - -[[package]] -name = "config" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" -dependencies = [ - "async-trait", - "json5", - "lazy_static", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml 0.5.11", - "yaml-rust", -] - -[[package]] -name = "connection-router" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2", - "flagset", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "const-oid" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "core-foundation" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - -[[package]] -name = "cosmos-sdk-proto" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4776e787b24d9568dd61d3237eeb4eb321d622fb881b858c7b82806420e87d4" -dependencies = [ - "prost", - "prost-types", - "tendermint-proto 0.27.0", - "tonic", -] - -[[package]] -name = "cosmos-sdk-proto" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73c9d2043a9e617b0d602fbc0a0ecd621568edbf3a9774890a6d562389bd8e1c" -dependencies = [ - "prost", - "prost-types", - "tendermint-proto 0.32.0", -] - -[[package]] -name = "cosmrs" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af13955d6f356272e6def9ff5e2450a7650df536d8934f47052a20c76513d2f6" -dependencies = [ - "bip32", - "cosmos-sdk-proto 0.19.0", - "ecdsa 0.16.7", - "eyre", - "getrandom", - "k256 0.13.1", - "rand_core 0.6.4", - "serde", - "serde_json", - "subtle-encoding", - "tendermint 0.32.0", - "thiserror", -] - -[[package]] -name = "cosmwasm-crypto" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" -dependencies = [ - "digest 0.10.6", - "ed25519-zebra", - "k256 0.11.6", - "rand_core 0.6.4", - "thiserror", -] - -[[package]] -name = "cosmwasm-derive" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" -dependencies = [ - "syn 1.0.107", -] - -[[package]] -name = "cosmwasm-schema" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" -dependencies = [ - "cosmwasm-schema-derive", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "cosmwasm-schema-derive" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "cosmwasm-std" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" -dependencies = [ - "base64 0.13.1", - "bnum", - "cosmwasm-crypto", - "cosmwasm-derive", - "derivative", - "forward_ref", - "hex", - "schemars", - "serde", - "serde-json-wasm", - "sha2 0.10.6", - "thiserror", -] - -[[package]] -name = "cosmwasm-storage" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18b4c99c6479e554ef1516950f1fa3d88bd7d0a8fc2367321c07ca0a33997dfc" -dependencies = [ - "cosmwasm-std", - "serde", -] - -[[package]] -name = "cpufeatures" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4c2f4e1afd912bc40bfd6fed5d9dc1f288e0ba01bfcc835cc5bc3eb13efe15" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct 0.6.1", -] - -[[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 = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - -[[package]] -name = "cw-storage-plus" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6cf70ef7686e2da9ad7b067c5942cd3e88dd9453f7af42f54557f8af300fb0" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw-storage-plus" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", -] - -[[package]] -name = "cw0" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae676b6cced78a3d38ad4b01ab4ed66fc78ac191c3c0d6bfd5372cb2efd473b" -dependencies = [ - "cosmwasm-std", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "cw2" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5abb8ecea72e09afff830252963cb60faf945ce6cef2c20a43814516082653da" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-storage-plus 0.15.1", - "schemars", - "serde", -] - -[[package]] -name = "darling" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.27", -] - -[[package]] -name = "darling_macro" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "der" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "deref-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4255bb7dd538590188bd0aea52e48bd699b19bd90b0d069ec2ced8461fe23273" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[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.107", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - -[[package]] -name = "difflib" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" -dependencies = [ - "block-buffer 0.10.3", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "dlv-list" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - -[[package]] -name = "downcast" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" - -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - -[[package]] -name = "dyn-clone" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9b0705efd4599c15a38151f4721f7bc388306f61084d3bfd50bd07fbca5cb60" - -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - -[[package]] -name = "ecdsa" -version = "0.16.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" -dependencies = [ - "der 0.7.5", - "digest 0.10.6", - "elliptic-curve 0.13.4", - "rfc6979 0.4.0", - "signature 2.1.0", - "spki 0.7.2", -] - -[[package]] -name = "ed25519" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb04eee5d9d907f29e80ee6b0e78f7e2c82342c63e3580d8c4f69d9d5aad963" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.1.0", -] - -[[package]] -name = "ed25519-consensus" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" -dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "ed25519-zebra" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" -dependencies = [ - "curve25519-dalek", - "hashbrown 0.12.3", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.6", - "ff 0.12.1", - "generic-array", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle", - "zeroize", -] - -[[package]] -name = "elliptic-curve" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" -dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.2", - "digest 0.10.6", - "ff 0.13.0", - "generic-array", - "group 0.13.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", - "sec1 0.7.1", - "subtle", - "zeroize", -] - -[[package]] -name = "ena" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1" -dependencies = [ - "log", -] - -[[package]] -name = "encoding_rs" -version = "0.8.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "enr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf56acd72bb22d2824e66ae8e9e5ada4d0de17a69c7fd35569dde2ada8ec9116" -dependencies = [ - "base64 0.13.1", - "bytes", - "hex", - "k256 0.13.1", - "log", - "rand", - "rlp", - "serde", - "sha3", - "zeroize", -] - -[[package]] -name = "enum-display-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ef37b2a9b242295d61a154ee91ae884afff6b8b933b486b12481cc58310ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "equivalent" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" - -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "error-stack" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d224e04b2d93d974c08e375dac9b8d1a513846e44c6666450a57b1ed963f9" -dependencies = [ - "anyhow", - "eyre", - "owo-colors", - "rustc_version", -] - -[[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.6", - "hex", - "hmac", - "pbkdf2 0.11.0", - "rand", - "scrypt", - "serde", - "serde_json", - "sha2 0.10.6", - "sha3", - "thiserror", - "uuid", -] - -[[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 = "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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b4026b97da8281276744741fac7eb385da905f6093c583331fa2953fdd4253" -dependencies = [ - "ethers-addressbook", - "ethers-contract", - "ethers-core", - "ethers-etherscan", - "ethers-middleware", - "ethers-providers", - "ethers-signers", - "ethers-solc", -] - -[[package]] -name = "ethers-addressbook" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcb6ffefc230d8c42874c51b28dc11dbb8de50b27a8fdf92648439d6baa68dc" -dependencies = [ - "ethers-core", - "once_cell", - "serde", - "serde_json", -] - -[[package]] -name = "ethers-contract" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4719a44c3d37ab07c6dea99ab174068d8c35e441b60b6c20ce4e48357273e8" -dependencies = [ - "ethers-contract-abigen", - "ethers-contract-derive", - "ethers-core", - "ethers-providers", - "ethers-signers", - "futures-util", - "hex", - "once_cell", - "pin-project", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "ethers-contract-abigen" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155ea1b84d169d231317ed86e307af6f2bed6b40dd17e5e94bc84da21cadb21c" -dependencies = [ - "Inflector", - "dunce", - "ethers-core", - "ethers-etherscan", - "eyre", - "hex", - "prettyplease 0.2.12", - "proc-macro2", - "quote", - "regex", - "reqwest", - "serde", - "serde_json", - "syn 2.0.27", - "toml 0.7.6", - "walkdir", -] - -[[package]] -name = "ethers-contract-derive" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8567ff196c4a37c1a8c90ec73bda0ad2062e191e4f0a6dc4d943e2ec4830fc88" -dependencies = [ - "Inflector", - "ethers-contract-abigen", - "ethers-core", - "hex", - "proc-macro2", - "quote", - "serde_json", - "syn 2.0.27", -] - -[[package]] -name = "ethers-core" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60ca2514feb98918a0a31de7e1983c29f2267ebf61b2dc5d4294f91e5b866623" -dependencies = [ - "arrayvec", - "bytes", - "cargo_metadata", - "chrono", - "elliptic-curve 0.13.4", - "ethabi", - "generic-array", - "hex", - "k256 0.13.1", - "num_enum", - "once_cell", - "open-fastrlp", - "rand", - "rlp", - "serde", - "serde_json", - "strum", - "syn 2.0.27", - "tempfile", - "thiserror", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "ethers-etherscan" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22b3a8269d3df0ed6364bc05b4735b95f4bf830ce3aef87d5e760fb0e93e5b91" -dependencies = [ - "ethers-core", - "reqwest", - "semver", - "serde", - "serde_json", - "thiserror", - "tracing", -] - -[[package]] -name = "ethers-middleware" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0c339aad74ae5c451d27e0e49c7a3c7d22620b119b4f9291d7aa21f72d7f366" -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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b411b119f1cf0efb69e2190883dee731251882bb21270f893ee9513b3a697c48" -dependencies = [ - "async-trait", - "auto_impl", - "base64 0.21.2", - "bytes", - "enr", - "ethers-core", - "futures-core", - "futures-timer", - "futures-util", - "hashers", - "hex", - "http", - "instant", - "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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4864d387456a9c09a1157fa10e1528b29d90f1d859443acf06a1b23365fb518c" -dependencies = [ - "async-trait", - "coins-bip32", - "coins-bip39", - "elliptic-curve 0.13.4", - "eth-keystore", - "ethers-core", - "hex", - "rand", - "sha2 0.10.6", - "thiserror", - "tracing", -] - -[[package]] -name = "ethers-solc" -version = "2.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6c2b9625a2c639d46625f88acc2092a3cb35786c37f7c2128b3ca20f639b3c" -dependencies = [ - "cfg-if", - "dunce", - "ethers-core", - "glob", - "hex", - "home", - "md-5", - "num_cpus", - "once_cell", - "path-slash", - "rayon", - "regex", - "semver", - "serde", - "serde_json", - "solang-parser", - "svm-rs", - "thiserror", - "tiny-keccak", - "tokio", - "tracing", - "walkdir", - "yansi", -] - -[[package]] -name = "eyre" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" -dependencies = [ - "indenter", - "once_cell", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fixed-hash" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" -dependencies = [ - "byteorder", - "rand", - "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 = "flagset" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda653ca797810c02f7ca4b804b40b8b95ae046eb989d356bce17919a8c25499" -dependencies = [ - "serde", -] - -[[package]] -name = "flate2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flex-error" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" -dependencies = [ - "eyre", - "paste", -] - -[[package]] -name = "float-cmp" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" -dependencies = [ - "num-traits", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "forward_ref" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" - -[[package]] -name = "fragile" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" - -[[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.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" - -[[package]] -name = "futures-executor" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" - -[[package]] -name = "futures-locks" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" -dependencies = [ - "futures-channel", - "futures-task", -] - -[[package]] -name = "futures-macro" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "futures-sink" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" - -[[package]] -name = "futures-task" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" - -[[package]] -name = "futures-timer" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" -dependencies = [ - "gloo-timers", - "send_wrapper 0.4.0", -] - -[[package]] -name = "futures-util" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.27.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" - -[[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.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.0", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "h2" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.2", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" - -[[package]] -name = "hashers" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" -dependencies = [ - "fxhash", -] - -[[package]] -name = "headers" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e372db8e5c0d213e0cd0b9be18be2aca3d44cf2fe30a9d46a65581cd454584" -dependencies = [ - "base64 0.13.1", - "bitflags", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", -] - -[[package]] -name = "headers-core" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - -[[package]] -name = "http" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - -[[package]] -name = "humantime-serde" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" -dependencies = [ - "humantime", - "serde", -] - -[[package]] -name = "hyper" -version = "0.14.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-proxy" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca815a891b24fdfb243fa3239c86154392b0953ee584aa1a2a1f66d20cbe75cc" -dependencies = [ - "bytes", - "futures", - "headers", - "http", - "hyper", - "hyper-rustls 0.22.1", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.22.0", - "tower-service", - "webpki 0.21.4", -] - -[[package]] -name = "hyper-rustls" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" -dependencies = [ - "ct-logs", - "futures-util", - "hyper", - "log", - "rustls 0.19.1", - "rustls-native-certs", - "tokio", - "tokio-rustls 0.22.0", - "webpki 0.21.4", - "webpki-roots 0.21.1", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" -dependencies = [ - "futures-util", - "http", - "hyper", - "rustls 0.21.5", - "tokio", - "tokio-rustls 0.24.1", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows", -] - -[[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 = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" -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-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.107", -] - -[[package]] -name = "indenter" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" - -[[package]] -name = "indexmap" -version = "1.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", -] - -[[package]] -name = "indexmap" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" -dependencies = [ - "equivalent", - "hashbrown 0.14.0", - "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.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e" -dependencies = [ - "libc", - "windows-sys 0.42.0", -] - -[[package]] -name = "ipnet" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" - -[[package]] -name = "is-terminal" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" -dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "is_ci" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" - -[[package]] -name = "jobserver" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "json5" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" -dependencies = [ - "pest", - "pest_derive", - "serde", -] - -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.6", -] - -[[package]] -name = "k256" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" -dependencies = [ - "cfg-if", - "ecdsa 0.16.7", - "elliptic-curve 0.13.4", - "once_cell", - "sha2 0.10.6", - "signature 2.1.0", -] - -[[package]] -name = "keccak" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "lalrpop" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8" -dependencies = [ - "ascii-canvas", - "bit-set", - "diff", - "ena", - "is-terminal", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "string_cache", - "term", - "tiny-keccak", - "unicode-xid", -] - -[[package]] -name = "lalrpop-util" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d" - -[[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.147" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linux-raw-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matchit" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" - -[[package]] -name = "md-5" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" -dependencies = [ - "digest 0.10.6", -] - -[[package]] -name = "memchr" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] - -[[package]] -name = "mockall" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e4a1c770583dac7ab5e2f6c139153b783a53a1bbee9729613f193e59828326" -dependencies = [ - "cfg-if", - "downcast", - "fragile", - "lazy_static", - "mockall_derive", - "predicates", - "predicates-tree", -] - -[[package]] -name = "mockall_derive" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832663583d5fa284ca8810bf7015e46c9fff9622d3cf34bd1eea5003fec06dd0" -dependencies = [ - "cfg-if", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "multimap" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "multisig" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "cosmwasm-crypto", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw2", - "getrandom", - "schemars", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - -[[package]] -name = "normalize-line-endings" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" - -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-derive" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "num-traits" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" -dependencies = [ - "num_enum_derive", -] - -[[package]] -name = "num_enum_derive" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "object" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" - -[[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] -name = "open-fastrlp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", - "ethereum-types", - "open-fastrlp-derive", -] - -[[package]] -name = "open-fastrlp-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" -dependencies = [ - "bytes", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", -] - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[package]] -name = "owo-colors" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" -dependencies = [ - "supports-color", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8e946cc0cc711189c0b0249fb8b599cbeeab9784d83c415719368bb8d4ac64" -dependencies = [ - "arrayvec", - "bitvec 1.0.1", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a296c3079b5fefbc499e1de58dc26c09b1b9a5952d26694ee89f04a43ebbb3e" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "windows-sys 0.42.0", -] - -[[package]] -name = "password-hash" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d01a5bd0424d00070b0098dd17ebca6f961a959dead1dbcbbbc1d1cd8d3deeba" - -[[package]] -name = "path-slash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - -[[package]] -name = "pbkdf2" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" -dependencies = [ - "digest 0.10.6", - "hmac", - "password-hash", - "sha2 0.10.6", -] - -[[package]] -name = "pbkdf2" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31" -dependencies = [ - "digest 0.10.6", - "hmac", -] - -[[package]] -name = "peg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" -dependencies = [ - "peg-macros", - "peg-runtime", -] - -[[package]] -name = "peg-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" -dependencies = [ - "peg-runtime", - "proc-macro2", - "quote", -] - -[[package]] -name = "peg-runtime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" - -[[package]] -name = "percent-encoding" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" - -[[package]] -name = "pest" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ab62d2fa33726dbe6321cc97ef96d8cde531e3eeaf858a058de53a8a6d40d8f" -dependencies = [ - "thiserror", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf026e2d0581559db66d837fe5242320f525d85c76283c61f4d51a1238d65ea" -dependencies = [ - "pest", - "pest_generator", -] - -[[package]] -name = "pest_generator" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b27bd18aa01d91c8ed2b61ea23406a676b42d82609c6e2581fba42f0c15f17f" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "pest_meta" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f02b677c1859756359fc9983c2e56a0237f18624a3789528804406b7e915e5d" -dependencies = [ - "once_cell", - "pest", - "sha2 0.10.6", -] - -[[package]] -name = "petgraph" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" -dependencies = [ - "fixedbitset", - "indexmap 1.9.2", -] - -[[package]] -name = "pharos" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" -dependencies = [ - "futures", - "rustc_version", -] - -[[package]] -name = "phf" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" -dependencies = [ - "phf_macros", - "phf_shared 0.11.2", -] - -[[package]] -name = "phf_generator" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" -dependencies = [ - "phf_shared 0.11.2", - "rand", -] - -[[package]] -name = "phf_macros" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" -dependencies = [ - "phf_generator", - "phf_shared 0.11.2", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher", -] - -[[package]] -name = "phf_shared" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" -dependencies = [ - "siphasher", -] - -[[package]] -name = "pin-project" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030ad2bc4db10a8944cb0d837f158bdfec4d4a4873ab701a95046770d11f8842" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.5", - "spki 0.7.2", -] - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "ppv-lite86" -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 = "predicates" -version = "2.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd" -dependencies = [ - "difflib", - "float-cmp", - "itertools", - "normalize-line-endings", - "predicates-core", - "regex", -] - -[[package]] -name = "predicates-core" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2" - -[[package]] -name = "predicates-tree" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d" -dependencies = [ - "predicates-core", - "termtree", -] - -[[package]] -name = "prettyplease" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" -dependencies = [ - "proc-macro2", - "syn 1.0.107", -] - -[[package]] -name = "prettyplease" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" -dependencies = [ - "proc-macro2", - "syn 2.0.27", -] - -[[package]] -name = "primitive-types" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3486ccba82358b11a77516035647c34ba167dfa53312630de83b12bd4f3d66" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "scale-info", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" -dependencies = [ - "once_cell", - "toml_edit 0.18.1", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.107", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" -dependencies = [ - "bytes", - "heck", - "itertools", - "lazy_static", - "log", - "multimap", - "petgraph", - "prettyplease 0.1.25", - "prost", - "prost-types", - "regex", - "syn 1.0.107", - "tempfile", - "which", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost", -] - -[[package]] -name = "quote" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha", - "rand_core 0.6.4", -] - -[[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" - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "random-string" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e63111ec5292d8af9c220f06fe3bb87991cc78b6f1f7e291d1ae6b8a60817" -dependencies = [ - "fastrand", -] - -[[package]] -name = "rayon" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - -[[package]] -name = "redox_users" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" -dependencies = [ - "getrandom", - "redox_syscall 0.2.16", - "thiserror", -] - -[[package]] -name = "regex" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" - -[[package]] -name = "reqwest" -version = "0.11.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" -dependencies = [ - "base64 0.21.2", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls 0.24.1", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.5", - "rustls-pemfile", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-rustls 0.24.1", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "webpki-roots 0.22.6", - "winreg", -] - -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac", - "zeroize", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "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", - "untrusted", - "web-sys", - "winapi", -] - -[[package]] -name = "ripemd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" -dependencies = [ - "digest 0.10.6", -] - -[[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.107", -] - -[[package]] -name = "ron" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" -dependencies = [ - "base64 0.13.1", - "bitflags", - "serde", -] - -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[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.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.37.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys 0.45.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct 0.6.1", - "webpki 0.21.4", -] - -[[package]] -name = "rustls" -version = "0.21.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79ea77c539259495ce8ca47f53e66ae0330a8819f67e23ac96ca02f50e7b7d36" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.1", - "sct 0.7.0", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls 0.19.1", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" -dependencies = [ - "base64 0.21.2", -] - -[[package]] -name = "rustls-webpki" -version = "0.100.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f36a6828982f422756984e47912a7a51dcbc2a197aa791158f8ca61cd8204e" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" - -[[package]] -name = "ryu" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "scale-info" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0a159d0c45c12b20c5a844feb1fe4bea86e28f17b92a5f0c42193634d3782" -dependencies = [ - "cfg-if", - "derive_more", - "parity-scale-codec", - "scale-info-derive", -] - -[[package]] -name = "scale-info-derive" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "912e55f6d20e0e80d63733872b40e1227c0bce1e1ab81ba67d696339bfd7fd29" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "schannel" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" -dependencies = [ - "windows-sys 0.42.0", -] - -[[package]] -name = "schemars" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" -dependencies = [ - "dyn-clone", - "schemars_derive", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 1.0.107", -] - -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[package]] -name = "scrypt" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" -dependencies = [ - "hmac", - "pbkdf2 0.11.0", - "salsa20", - "sha2 0.10.6", -] - -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array", - "pkcs8 0.9.0", - "subtle", - "zeroize", -] - -[[package]] -name = "sec1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" -dependencies = [ - "base16ct 0.2.0", - "der 0.7.5", - "generic-array", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" -dependencies = [ - "serde", -] - -[[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.174" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b88756493a5bd5e5395d53baa70b194b05764ab85b59e43e4b8f4e1192fa9b1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-json-wasm" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.174" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e5c3a298c7f978e53536f95a63bdc4c4a64550582f31a0359a9afda6aede62e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "serde_derive_internals" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "serde_json" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "serde_spanned" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "serde_with" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" -dependencies = [ - "base64 0.21.2", - "chrono", - "hex", - "indexmap 1.9.2", - "indexmap 2.0.0", - "serde", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9197f1ad0e3c173a0222d3c4404fb04c3afe87e962bcb327af73e8301fa203c7" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "service-registry" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 0.15.1", - "cw2", - "schemars", - "serde", - "thiserror", -] - -[[package]] -name = "sha1" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.6", -] - -[[package]] -name = "sha3" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c2bb1a323307527314a36bfb73f24febb08ce2b8a554bf4ffd6f51ad15198c" -dependencies = [ - "digest 0.10.6", - "keccak", -] - -[[package]] -name = "sharded-slab" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "1.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.6", - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" -dependencies = [ - "digest 0.10.6", - "rand_core 0.6.4", -] - -[[package]] -name = "siphasher" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" - -[[package]] -name = "slab" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" -dependencies = [ - "autocfg", -] - -[[package]] -name = "smallvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "solang-parser" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c792fe9fae2a2f716846f214ca10d5a1e21133e0bf36cef34bcc4a852467b21" -dependencies = [ - "itertools", - "lalrpop", - "lalrpop-util", - "phf", - "thiserror", - "unicode-xid", -] - -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - -[[package]] -name = "spki" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" -dependencies = [ - "base64ct", - "der 0.7.5", -] - -[[package]] -name = "static_assertions" -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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.27", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "subtle-encoding" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" -dependencies = [ - "zeroize", -] - -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - -[[package]] -name = "supports-color" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ba6faf2ca7ee42fdd458f4347ae0a9bd6bcc445ad7cb57ad82b383f18870d6f" -dependencies = [ - "atty", - "is_ci", -] - -[[package]] -name = "svm-rs" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a04fc4f5cd35c700153b233f5575ccb3237e0f941fa5049d9e98254d10bf2fe" -dependencies = [ - "fs2", - "hex", - "home", - "once_cell", - "reqwest", - "semver", - "serde", - "serde_json", - "sha2 0.10.6", - "thiserror", - "url", - "zip", -] - -[[package]] -name = "syn" -version = "1.0.107" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" - -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "unicode-xid", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall 0.3.5", - "rustix", - "windows-sys 0.45.0", -] - -[[package]] -name = "tendermint" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a46ec6b25b028097ab682ffae11d09d64fe1e2535833b902f26a278a0f88a705" -dependencies = [ - "bytes", - "digest 0.10.6", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "k256 0.13.1", - "num-traits", - "once_cell", - "prost", - "prost-types", - "ripemd", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.6", - "signature 2.1.0", - "subtle", - "subtle-encoding", - "tendermint-proto 0.32.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "bytes", - "digest 0.10.6", - "ed25519", - "ed25519-consensus", - "flex-error", - "futures", - "num-traits", - "once_cell", - "prost", - "prost-types", - "serde", - "serde_bytes", - "serde_json", - "serde_repr", - "sha2 0.10.6", - "signature 2.1.0", - "subtle", - "subtle-encoding", - "tendermint-proto 0.33.0", - "time", - "zeroize", -] - -[[package]] -name = "tendermint-config" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "flex-error", - "serde", - "serde_json", - "tendermint 0.33.0", - "toml 0.5.11", - "url", -] - -[[package]] -name = "tendermint-proto" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5895470f28c530f8ae8c4071bf8190304ce00bd131d25e81730453124a3375c" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce23c8ff0e6634eb4c3c4aeed45076dc97dac91aac5501a905a67fa222e165b" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-proto" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "bytes", - "flex-error", - "num-derive", - "num-traits", - "prost", - "prost-types", - "serde", - "serde_bytes", - "subtle-encoding", - "time", -] - -[[package]] -name = "tendermint-rpc" -version = "0.33.0" -source = "git+https://github.com/axelarnetwork/tendermint-rs.git?branch=v0.33.x#e97033e20e660a7e707ea86db174ec047bbba50d" -dependencies = [ - "async-trait", - "bytes", - "flex-error", - "futures", - "getrandom", - "http", - "hyper", - "hyper-proxy", - "hyper-rustls 0.22.1", - "peg", - "pin-project", - "semver", - "serde", - "serde_bytes", - "serde_json", - "subtle", - "subtle-encoding", - "tendermint 0.33.0", - "tendermint-config", - "tendermint-proto 0.33.0", - "thiserror", - "time", - "tokio", - "tracing", - "url", - "uuid", - "walkdir", -] - -[[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 = "termtree" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8" - -[[package]] -name = "thiserror" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "thread_local" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" -dependencies = [ - "once_cell", -] - -[[package]] -name = "time" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" -dependencies = [ - "itoa", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" - -[[package]] -name = "time-macros" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" -dependencies = [ - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - -[[package]] -name = "tokio" -version = "1.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" -dependencies = [ - "autocfg", - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.27", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls 0.19.1", - "tokio", - "webpki 0.21.4", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.5", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec509ac96e9a0c43427c74f003127d953a265737636129424288d27cb5c4b12c" -dependencies = [ - "futures-util", - "log", - "rustls 0.21.5", - "tokio", - "tokio-rustls 0.24.1", - "tungstenite", - "webpki-roots 0.23.1", -] - -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime 0.6.3", - "toml_edit 0.19.14", -] - -[[package]] -name = "toml_datetime" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" - -[[package]] -name = "toml_datetime" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" -dependencies = [ - "indexmap 1.9.2", - "nom8", - "toml_datetime 0.5.1", -] - -[[package]] -name = "toml_edit" -version = "0.19.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" -dependencies = [ - "indexmap 2.0.0", - "serde", - "serde_spanned", - "toml_datetime 0.6.3", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.13.1", - "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "prost-derive", - "tokio", - "tokio-stream", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "tracing-futures", -] - -[[package]] -name = "tonic-build" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" -dependencies = [ - "prettyplease 0.1.25", - "proc-macro2", - "prost-build", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.2", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - -[[package]] -name = "tracing" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" -dependencies = [ - "cfg-if", - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "tracing-core" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" -dependencies = [ - "once_cell", - "valuable", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" -dependencies = [ - "lazy_static", - "log", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" -dependencies = [ - "serde", - "tracing-core", - "valuable", - "valuable-serde", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "nu-ansi-term", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", - "tracing-serde", - "valuable", - "valuable-serde", -] - -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "tungstenite" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67" -dependencies = [ - "byteorder", - "bytes", - "data-encoding", - "http", - "httparse", - "log", - "rand", - "rustls 0.21.5", - "sha1", - "thiserror", - "url", - "utf-8", - "webpki 0.22.0", -] - -[[package]] -name = "typenum" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" - -[[package]] -name = "ucd-trie" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" - -[[package]] -name = "unicode-ident" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" - -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - -[[package]] -name = "url" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8parse" -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", - "serde", -] - -[[package]] -name = "valuable" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -dependencies = [ - "valuable-derive", -] - -[[package]] -name = "valuable-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d44690c645190cfce32f91a1582281654b2338c6073fa250b0949fd25c55b32" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - -[[package]] -name = "valuable-serde" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5285cfff30cdabe26626736a54d989687dd9cab84f51f4048b61d6d0ae8b0907" -dependencies = [ - "serde", - "valuable", -] - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "voting-verifier" -version = "0.1.0" -source = "git+https://github.com/axelarnetwork/axelar-amplifier.git#a314da5d2d40702d5f20ef9ab0e697a3b88f48b3" -dependencies = [ - "axelar-wasm-std", - "connection-router", - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-storage-plus 1.1.0", - "cw0", - "cw2", - "either", - "schemars", - "serde", - "serde_json", - "service-registry", - "thiserror", -] - -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 1.0.107", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.33" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" - -[[package]] -name = "web-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki 0.21.4", -] - -[[package]] -name = "webpki-roots" -version = "0.22.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki 0.22.0", -] - -[[package]] -name = "webpki-roots" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.1", -] - -[[package]] -name = "which" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" -dependencies = [ - "either", - "libc", - "once_cell", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" -dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", -] - -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.1", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.1", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm 0.42.1", - "windows_x86_64_msvc 0.42.1", -] - -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - -[[package]] -name = "winnow" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[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", - "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 = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - -[[package]] -name = "zeroize" -version = "1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", - "synstructure", -] - -[[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", - "crc32fast", - "crossbeam-utils", - "flate2", - "hmac", - "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.8+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" -dependencies = [ - "cc", - "libc", - "pkg-config", -] \ No newline at end of file diff --git a/ampd/Cargo.toml b/ampd/Cargo.toml index e70b1ee4d..3518187b5 100644 --- a/ampd/Cargo.toml +++ b/ampd/Cargo.toml @@ -8,6 +8,7 @@ rust-version = { workspace = true } [dependencies] async-trait = "0.1.59" axelar-wasm-std = { workspace = true } +axum = "0.7.5" base64 = "0.21.2" bcs = "0.1.5" borsh = { version = "1.2.0", features = ["derive"] } @@ -39,7 +40,7 @@ prost = "0.11.9" report = { workspace = true } reqwest = { version = "0.11.24", default-features = false } serde = { version = "1.0.147", features = ["derive"] } -serde_json = "1.0.89" +serde_json = { workspace = true } serde_with = "3.2.0" service-registry = { workspace = true } solana-account-decoder = "1.18.1" @@ -59,7 +60,7 @@ sui-types = { git = "https://github.com/mystenlabs/sui", features = [ # The fix for the issue is at https://github.com/axelarnetwork/tendermint-rs/commit/e97033e20e660a7e707ea86db174ec047bbba50d. tendermint = { git = "https://github.com/axelarnetwork/tendermint-rs.git", branch = "v0.33.x" } tendermint-rpc = { git = "https://github.com/axelarnetwork/tendermint-rs.git", branch = "v0.33.x", features = [ - "http-client", + "http-client", ] } thiserror = { workspace = true } tokio = { version = "1.22.0", features = ["signal"] } diff --git a/ampd/README.md b/ampd/README.md index 87861cb68..14435e178 100644 --- a/ampd/README.md +++ b/ampd/README.md @@ -11,6 +11,7 @@ Below is the config file format, with explanations for each entry: tm_jsonrpc=[JSON-RPC URL of Axelar node] tm_grpc=[gRPC URL of Axelar node] event_buffer_cap=[max blockchain events to queue. Will error if set too low] +health_check_bind_addr=[the /status endpoint bind address i.e "0.0.0.0:3000"] [service_registry] cosmwasm_contract=[address of service registry] @@ -52,6 +53,7 @@ type=[handler type. Could be EvmMsgWorkerSetVerifier | SuiWorkerSetVerifier] Below is an example config for connecting to a local axelard node and local tofnd process, and verifying transactions from Avalanche testnet and Sui testnet. ``` +health_check_bind_addr="0.0.0.0:3000" tm_jsonrpc="http://localhost:26657" tm_grpc="tcp://localhost:9090" event_buffer_cap=10000 diff --git a/ampd/src/broadcaster.rs b/ampd/src/broadcaster.rs index f2eaa4cb4..d83acd592 100644 --- a/ampd/src/broadcaster.rs +++ b/ampd/src/broadcaster.rs @@ -272,6 +272,7 @@ mod tests { use cosmrs::{bank::MsgSend, tx::Msg, AccountId}; use ecdsa::SigningKey; use rand::rngs::OsRng; + use std::time::Duration; use tokio::test; use tonic::Status; @@ -449,7 +450,11 @@ mod tests { acc_number: 0, acc_sequence: 0, pub_key: (key_id.to_string(), pub_key), - config: Config::default(), + config: Config { + broadcast_interval: Duration::from_secs(0), + tx_fetch_interval: Duration::from_secs(0), + ..Config::default() + }, }; let msgs = vec![dummy_msg()]; diff --git a/ampd/src/config.rs b/ampd/src/config.rs index b9b625562..08f7a65d6 100644 --- a/ampd/src/config.rs +++ b/ampd/src/config.rs @@ -1,3 +1,4 @@ +use std::net::{Ipv4Addr, SocketAddrV4}; use std::time::Duration; use serde::{Deserialize, Serialize}; @@ -11,6 +12,7 @@ use crate::url::Url; #[derive(Deserialize, Serialize, Debug, PartialEq)] #[serde(default)] pub struct Config { + pub health_check_bind_addr: SocketAddrV4, pub tm_jsonrpc: Url, pub tm_grpc: Url, pub event_buffer_cap: usize, @@ -34,6 +36,7 @@ impl Default for Config { event_buffer_cap: 100000, event_stream_timeout: Duration::from_secs(15), service_registry: ServiceRegistryConfig::default(), + health_check_bind_addr: SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 3000), } } } diff --git a/ampd/src/event_sub.rs b/ampd/src/event_sub.rs index 9a3f161ee..95fa511b4 100644 --- a/ampd/src/event_sub.rs +++ b/ampd/src/event_sub.rs @@ -411,7 +411,7 @@ mod tests { let event_publisher = EventPublisher::new(mock_client, block_count * event_count_per_block); let mut client = event_publisher .start_from(block_height) - .poll_interval(Duration::new(0, 1e8 as u32)); + .poll_interval(Duration::new(0, 1e7 as u32)); let mut stream = client.subscribe(); let child_token = token.child_token(); diff --git a/ampd/src/health_check.rs b/ampd/src/health_check.rs new file mode 100644 index 000000000..ffd366fc6 --- /dev/null +++ b/ampd/src/health_check.rs @@ -0,0 +1,101 @@ +use error_stack::{Result, ResultExt}; +use std::net::SocketAddrV4; +use thiserror::Error; +use tracing::info; + +use axum::{http::StatusCode, routing::get, Json, Router}; +use serde::{Deserialize, Serialize}; +use tokio_util::sync::CancellationToken; + +#[derive(Error, Debug)] +pub enum Error { + #[error("failed to start the health check server")] + Start, + #[error("health check server failed unexpectedly")] + WhileRunning, +} + +pub struct Server { + bind_address: SocketAddrV4, +} + +impl Server { + pub fn new(bind_address: SocketAddrV4) -> Self { + Self { bind_address } + } + + pub async fn run(self, cancel: CancellationToken) -> Result<(), Error> { + let listener = tokio::net::TcpListener::bind(self.bind_address) + .await + .change_context(Error::Start)?; + + info!( + address = self.bind_address.to_string(), + "starting health check server" + ); + + let app = Router::new().route("/status", get(status)); + axum::serve(listener, app) + .with_graceful_shutdown(async move { cancel.cancelled().await }) + .await + .change_context(Error::WhileRunning) + } +} + +// basic handler that responds with a static string +async fn status() -> (StatusCode, Json) { + (StatusCode::OK, Json(Status { ok: true })) +} + +#[derive(Serialize, Deserialize)] +struct Status { + ok: bool, +} + +#[cfg(test)] +mod tests { + + use super::*; + use std::net::{SocketAddr, TcpListener}; + use std::time::Duration; + use tokio::test as async_test; + + #[async_test] + async fn server_lifecycle() { + let bind_address = test_bind_addr(); + + let server = Server::new(bind_address); + + let cancel = CancellationToken::new(); + + tokio::spawn(server.run(cancel.clone())); + + let url = format!("http://{}/status", bind_address); + + tokio::time::sleep(Duration::from_millis(100)).await; + + let response = reqwest::get(&url).await.unwrap(); + assert_eq!(reqwest::StatusCode::OK, response.status()); + + let status = response.json::().await.unwrap(); + assert!(status.ok); + + cancel.cancel(); + + tokio::time::sleep(Duration::from_millis(100)).await; + + match reqwest::get(&url).await { + Ok(_) => panic!("health check server should be closed by now"), + Err(error) => assert!(error.is_connect()), + }; + } + + fn test_bind_addr() -> SocketAddrV4 { + let listener = TcpListener::bind("127.0.0.1:0").unwrap(); + + match listener.local_addr().unwrap() { + SocketAddr::V4(addr) => addr, + SocketAddr::V6(_) => panic!("unexpected address"), + } + } +} diff --git a/ampd/src/lib.rs b/ampd/src/lib.rs index 7d15166c1..33aa7be93 100644 --- a/ampd/src/lib.rs +++ b/ampd/src/lib.rs @@ -3,6 +3,7 @@ use std::pin::Pin; use std::time::Duration; use block_height_monitor::BlockHeightMonitor; +use connection_router_api::ChainName; use cosmos_sdk_proto::cosmos::{ auth::v1beta1::query_client::QueryClient, tx::v1beta1::service_client::ServiceClient, }; @@ -10,6 +11,8 @@ use error_stack::{report, FutureExt, Result, ResultExt}; use solana::rpc::RpcCacheWrapper; use solana_client::nonblocking::rpc_client::RpcClient; use solana_sdk::commitment_config::CommitmentConfig; +use evm::finalizer::{pick, Finalization}; +use evm::json_rpc::EthereumClient; use thiserror::Error; use tokio::signal::unix::{signal, SignalKind}; use tokio::sync::oneshot; @@ -39,6 +42,7 @@ mod event_processor; mod event_sub; mod evm; mod handlers; +mod health_check; mod json_rpc; mod queue; mod solana; @@ -73,6 +77,7 @@ async fn prepare_app(cfg: Config, state: State) -> Result, event_buffer_cap, event_stream_timeout, service_registry: _service_registry, + health_check_bind_addr, } = cfg; let tm_client = tendermint_rpc::HttpClient::new(tm_jsonrpc.to_string().as_str()) @@ -124,6 +129,8 @@ async fn prepare_app(cfg: Config, state: State) -> Result, .build() .change_context(Error::Broadcaster)?; + let health_check_server = health_check::Server::new(health_check_bind_addr); + App::new( tm_client, broadcaster, @@ -132,8 +139,26 @@ async fn prepare_app(cfg: Config, state: State) -> Result, broadcast, event_buffer_cap, block_height_monitor, + health_check_server, ) .configure_handlers(worker, handlers, event_stream_timeout) + .await +} + +async fn check_finalizer<'a, C>( + chain_name: &ChainName, + finalization: &Finalization, + rpc_client: &'a C, +) -> Result<(), Error> +where + C: EthereumClient + Send + Sync, +{ + let _ = pick(finalization, rpc_client, 0) + .latest_finalized_block_height() + .await + .change_context_lazy(|| Error::InvalidFinalizerType(chain_name.to_owned()))?; + + Ok(()) } struct App @@ -148,6 +173,7 @@ where state_updater: StateUpdater, ecdsa_client: SharableEcdsaClient, block_height_monitor: BlockHeightMonitor, + health_check_server: health_check::Server, token: CancellationToken, } @@ -155,6 +181,7 @@ impl App where T: Broadcaster + Send + Sync + 'static, { + #[allow(clippy::too_many_arguments)] fn new( tm_client: tendermint_rpc::HttpClient, broadcaster: T, @@ -163,6 +190,7 @@ where broadcast_cfg: broadcaster::Config, event_buffer_cap: usize, block_height_monitor: BlockHeightMonitor, + health_check_server: health_check::Server, ) -> Self { let token = CancellationToken::new(); @@ -188,11 +216,12 @@ where state_updater, ecdsa_client, block_height_monitor, + health_check_server, token, } } - fn configure_handlers( + async fn configure_handlers( mut self, worker: TMAddress, handler_configs: Vec, @@ -204,50 +233,62 @@ where chain, cosmwasm_contract, rpc_timeout, - } => self.create_handler_task( - format!("{}-msg-verifier", chain.name), - handlers::evm_verify_msg::Handler::new( - worker.clone(), - cosmwasm_contract, - chain.name, - chain.finalization, - json_rpc::Client::new_http( - &chain.rpc_url, - reqwest::ClientBuilder::new() - .connect_timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) - .timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) - .build() - .change_context(Error::Connection)?, + } => { + let rpc_client = json_rpc::Client::new_http( + &chain.rpc_url, + reqwest::ClientBuilder::new() + .connect_timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) + .timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) + .build() + .change_context(Error::Connection)?, + ); + + check_finalizer(&chain.name, &chain.finalization, &rpc_client).await?; + + self.create_handler_task( + format!("{}-msg-verifier", chain.name), + handlers::evm_verify_msg::Handler::new( + worker.clone(), + cosmwasm_contract, + chain.name, + chain.finalization, + rpc_client, + self.broadcaster.client(), + self.block_height_monitor.latest_block_height(), ), - self.broadcaster.client(), - self.block_height_monitor.latest_block_height(), - ), - stream_timeout, - ), + stream_timeout, + ) + } handlers::config::Config::EvmWorkerSetVerifier { chain, cosmwasm_contract, rpc_timeout, - } => self.create_handler_task( - format!("{}-worker-set-verifier", chain.name), - handlers::evm_verify_worker_set::Handler::new( - worker.clone(), - cosmwasm_contract, - chain.name, - chain.finalization, - json_rpc::Client::new_http( - &chain.rpc_url, - reqwest::ClientBuilder::new() - .connect_timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) - .timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) - .build() - .change_context(Error::Connection)?, + } => { + let rpc_client = json_rpc::Client::new_http( + &chain.rpc_url, + reqwest::ClientBuilder::new() + .connect_timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) + .timeout(rpc_timeout.unwrap_or(DEFAULT_RPC_TIMEOUT)) + .build() + .change_context(Error::Connection)?, + ); + + check_finalizer(&chain.name, &chain.finalization, &rpc_client).await?; + + self.create_handler_task( + format!("{}-worker-set-verifier", chain.name), + handlers::evm_verify_worker_set::Handler::new( + worker.clone(), + cosmwasm_contract, + chain.name, + chain.finalization, + rpc_client, + self.broadcaster.client(), + self.block_height_monitor.latest_block_height(), ), - self.broadcaster.client(), - self.block_height_monitor.latest_block_height(), - ), - stream_timeout, - ), + stream_timeout, + ) + } handlers::config::Config::MultisigSigner { cosmwasm_contract } => self .create_handler_task( "multisig-signer", @@ -389,6 +430,7 @@ where broadcaster, state_updater, block_height_monitor, + health_check_server, token, .. } = self; @@ -421,6 +463,11 @@ where .run(token) .change_context(Error::EventPublisher) })) + .add_task(CancellableTask::create(|token| { + health_check_server + .run(token) + .change_context(Error::HealthCheck) + })) .add_task(CancellableTask::create(|token| { event_processor .run(token) @@ -469,4 +516,8 @@ pub enum Error { InvalidInput, #[error("block height monitor failed")] BlockHeightMonitor, + #[error("invalid finalizer type for chain {0}")] + InvalidFinalizerType(ChainName), + #[error("health check is not working")] + HealthCheck, } diff --git a/ampd/src/queue/queued_broadcaster.rs b/ampd/src/queue/queued_broadcaster.rs index 0f7db30d7..1ec493610 100644 --- a/ampd/src/queue/queued_broadcaster.rs +++ b/ampd/src/queue/queued_broadcaster.rs @@ -239,7 +239,7 @@ mod test { async fn should_broadcast_when_broadcast_interval_has_been_reached() { let tx_count = 9; let batch_gas_limit = 100; - let broadcast_interval = Duration::from_secs(1); + let broadcast_interval = Duration::from_millis(100); let gas_limit = 10; let mut broadcaster = MockBroadcaster::new(); @@ -372,7 +372,7 @@ mod test { assert!(client.run().await.is_ok()); }); - sleep(Duration::from_secs(1)).await; + sleep(Duration::from_millis(100)).await; driver.force_broadcast().await.unwrap(); drop(tx); diff --git a/ampd/src/tests/config_template.toml b/ampd/src/tests/config_template.toml index 33ecfb8f0..952ec1f66 100644 --- a/ampd/src/tests/config_template.toml +++ b/ampd/src/tests/config_template.toml @@ -1,3 +1,4 @@ +health_check_bind_addr = '0.0.0.0:3000' tm_jsonrpc = 'http://localhost:26657/' tm_grpc = 'tcp://localhost:9090' event_buffer_cap = 100000 diff --git a/contracts/aggregate-verifier/Cargo.toml b/contracts/aggregate-verifier/Cargo.toml index 37509ad12..e46534689 100644 --- a/contracts/aggregate-verifier/Cargo.toml +++ b/contracts/aggregate-verifier/Cargo.toml @@ -35,18 +35,15 @@ optimize = """docker run --rm -v "$(pwd)":/code \ [dependencies] axelar-wasm-std = { workspace = true } axelar-wasm-std-derive = { workspace = true } +client = { workspace = true } connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = "1.0.1" error-stack = { workspace = true } -itertools = { workspace = true } report = { workspace = true } -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -serde_json = "1.0.89" +serde = { workspace = true } thiserror = { workspace = true } voting-verifier = { workspace = true, features = ["library"] } diff --git a/contracts/aggregate-verifier/src/client.rs b/contracts/aggregate-verifier/src/client.rs index d06fb662f..e8f3bae6b 100644 --- a/contracts/aggregate-verifier/src/client.rs +++ b/contracts/aggregate-verifier/src/client.rs @@ -1,61 +1,60 @@ use axelar_wasm_std::utils::TryMapExt; use axelar_wasm_std::{FnExt, VerificationStatus}; use connection_router_api::{CrossChainId, Message}; -use cosmwasm_std::{to_json_binary, Addr, QuerierWrapper, QueryRequest, WasmMsg, WasmQuery}; +use cosmwasm_std::WasmMsg; use error_stack::{Result, ResultExt}; -use serde::de::DeserializeOwned; use std::collections::HashMap; -pub struct Verifier<'a> { - pub querier: QuerierWrapper<'a>, - pub address: Addr, +use crate::msg::{ExecuteMsg, QueryMsg}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("could not query the verifier contract")] + QueryVerifier, } -impl Verifier<'_> { - fn execute(&self, msg: &crate::msg::ExecuteMsg) -> WasmMsg { - WasmMsg::Execute { - contract_addr: self.address.to_string(), - msg: to_json_binary(msg).expect("msg should always be serializable"), - funds: vec![], - } +impl<'a> From> for Client<'a> { + fn from(client: client::Client<'a, ExecuteMsg, QueryMsg>) -> Self { + Client { client } } +} - fn query(&self, msg: &crate::msg::QueryMsg) -> Result { - self.querier - .query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: self.address.to_string(), - msg: to_json_binary(&msg).expect("msg should always be serializable"), - })) - .change_context(Error::QueryVerifier) - } +pub struct Client<'a> { + client: client::Client<'a, ExecuteMsg, QueryMsg>, +} - pub fn verify(&self, msgs: Vec) -> Option { - ignore_empty(msgs) - .map(|msgs| self.execute(&crate::msg::ExecuteMsg::VerifyMessages { messages: msgs })) +impl<'a> Client<'a> { + pub fn verify_messages(&self, msgs: Vec) -> Option { + ignore_empty(msgs).map(|msgs| { + self.client + .execute(&ExecuteMsg::VerifyMessages { messages: msgs }) + }) } - pub fn messages_with_status( + pub fn messages_status( &self, msgs: Vec, ) -> Result, Error> { ignore_empty(msgs.clone()) - .try_map(|msgs| self.query_message_status(msgs))? + .try_map(|msgs| self.query_messages_status(msgs))? .map(|status_by_id| ids_to_msgs(status_by_id, msgs)) .into_iter() .flatten() .then(Ok) } - fn query_message_status( + fn query_messages_status( &self, msgs: Vec, ) -> Result, Error> { - self.query::>( - &crate::msg::QueryMsg::GetMessagesStatus { messages: msgs }, - )? - .into_iter() - .collect::>() - .then(Ok) + self.client + .query::>(&QueryMsg::GetMessagesStatus { + messages: msgs, + }) + .change_context(Error::QueryVerifier)? + .into_iter() + .collect::>() + .then(Ok) } } @@ -81,65 +80,118 @@ fn ids_to_msgs( }) } -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("could not query the verifier contract")] - QueryVerifier, -} - #[cfg(test)] mod tests { + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier}; + use cosmwasm_std::{from_binary, to_binary, Addr, DepsMut, QuerierWrapper, WasmQuery}; + use std::str::FromStr; + use axelar_wasm_std::VerificationStatus; use connection_router_api::{CrossChainId, CHAIN_NAME_DELIMITER}; - use cosmwasm_std::testing::MockQuerier; - use std::str::FromStr; + + use crate::contract::{instantiate, query}; + use crate::msg::InstantiateMsg; use super::*; #[test] - fn verifier_returns_error_when_query_fails() { - let querier = MockQuerier::default(); - let verifier = Verifier { - address: Addr::unchecked("not a contract"), - querier: QuerierWrapper::new(&querier), - }; + fn query_messages_status_returns_empty_statuses() { + let addr = "aggregate-verifier"; - let result = verifier.query::>( - &crate::msg::QueryMsg::GetMessagesStatus { messages: vec![] }, - ); + let mut querier = MockQuerier::default(); + querier.update_wasm(move |msg| match msg { + WasmQuery::Smart { contract_addr, msg } if contract_addr == addr => { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut(), Addr::unchecked("verifier")); + + deps.querier.update_wasm(|_| { + let res: Vec<(CrossChainId, VerificationStatus)> = vec![]; + Ok(to_binary(&res).into()).into() + }); + + let msg = from_binary::(msg).unwrap(); + Ok(query(deps.as_ref(), mock_env(), msg).into()).into() + } + _ => panic!("unexpected query: {:?}", msg), + }); - assert!(matches!( - result.unwrap_err().current_context(), - Error::QueryVerifier - )) + let client: Client = + client::Client::new(QuerierWrapper::new(&querier), Addr::unchecked(addr)).into(); + + assert!(client.query_messages_status(vec![]).unwrap().is_empty()); } - // due to contract updates or misconfigured verifier contract address the verifier might respond, - // but deliver an unexpected data type. This tests that the client returns an error in such cases. #[test] - fn verifier_returns_error_on_return_type_mismatch() { + fn query_messages_status_returns_some_statuses() { + let addr = "aggregate-verifier"; + let msg_1 = Message { + cc_id: CrossChainId::from_str(format!("eth{}0x1234", CHAIN_NAME_DELIMITER).as_str()) + .unwrap(), + source_address: "0x1234".parse().unwrap(), + destination_address: "0x5678".parse().unwrap(), + destination_chain: "eth".parse().unwrap(), + payload_hash: [0; 32], + }; + let msg_2 = Message { + cc_id: CrossChainId::from_str(format!("eth{}0x4321", CHAIN_NAME_DELIMITER).as_str()) + .unwrap(), + source_address: "0x4321".parse().unwrap(), + destination_address: "0x8765".parse().unwrap(), + destination_chain: "eth".parse().unwrap(), + payload_hash: [0; 32], + }; + let mut querier = MockQuerier::default(); - querier.update_wasm(|_| { - Ok(to_json_binary( - &CrossChainId::from_str(format!("eth{}0x1234", CHAIN_NAME_DELIMITER).as_str()) - .unwrap(), - ) - .into()) - .into() + querier.update_wasm(move |msg| match msg { + WasmQuery::Smart { contract_addr, msg } if contract_addr == addr => { + let mut deps = mock_dependencies(); + instantiate_contract(deps.as_mut(), Addr::unchecked("verifier")); + + deps.querier.update_wasm(|_| { + let res: Vec<(CrossChainId, VerificationStatus)> = vec![ + ( + CrossChainId::from_str( + format!("eth{}0x1234", CHAIN_NAME_DELIMITER).as_str(), + ) + .unwrap(), + VerificationStatus::SucceededOnChain, + ), + ( + CrossChainId::from_str( + format!("eth{}0x4321", CHAIN_NAME_DELIMITER).as_str(), + ) + .unwrap(), + VerificationStatus::FailedOnChain, + ), + ]; + Ok(to_binary(&res).into()).into() + }); + + let msg = from_binary::(msg).unwrap(); + Ok(query(deps.as_ref(), mock_env(), msg).into()).into() + } + _ => panic!("unexpected query: {:?}", msg), }); - let verifier = Verifier { - address: Addr::unchecked("not a contract"), - querier: QuerierWrapper::new(&querier), - }; + let client: Client = + client::Client::new(QuerierWrapper::new(&querier), Addr::unchecked(addr)).into(); - let result = verifier.query::>( - &crate::msg::QueryMsg::GetMessagesStatus { messages: vec![] }, + assert!( + client + .query_messages_status(vec![msg_1, msg_2]) + .unwrap() + .len() + == 2 ); + } + + fn instantiate_contract(deps: DepsMut, verifier: Addr) { + let env = mock_env(); + let info = mock_info("deployer", &[]); + let msg = InstantiateMsg { + verifier_address: verifier.into_string(), + }; - assert!(matches!( - result.unwrap_err().current_context(), - Error::QueryVerifier - )) + instantiate(deps, env, info, msg).unwrap(); } } diff --git a/contracts/aggregate-verifier/src/contract.rs b/contracts/aggregate-verifier/src/contract.rs index 6b5c303c9..b9ba09db0 100644 --- a/contracts/aggregate-verifier/src/contract.rs +++ b/contracts/aggregate-verifier/src/contract.rs @@ -3,8 +3,8 @@ use connection_router_api::CrossChainId; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - from_json, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, QueryRequest, Reply, - Response, StdResult, WasmQuery, + from_binary, to_binary, Binary, Deps, DepsMut, Env, MessageInfo, QueryRequest, Reply, Response, + StdResult, WasmQuery, }; use cw_utils::{parse_reply_execute_data, MsgExecuteContractResponse}; @@ -45,7 +45,7 @@ pub fn execute( } pub mod execute { - use cosmwasm_std::{to_json_binary, SubMsg, WasmMsg}; + use cosmwasm_std::{to_binary, SubMsg, WasmMsg}; use connection_router_api::Message; @@ -59,7 +59,7 @@ pub mod execute { Ok(Response::new().add_submessage(SubMsg::reply_on_success( WasmMsg::Execute { contract_addr: verifier.to_string(), - msg: to_json_binary(&voting_msg::ExecuteMsg::VerifyMessages { messages: msgs })?, + msg: to_binary(&voting_msg::ExecuteMsg::VerifyMessages { messages: msgs })?, funds: vec![], }, VERIFY_REPLY, @@ -79,7 +79,7 @@ pub fn reply( match parse_reply_execute_data(reply) { Ok(MsgExecuteContractResponse { data: Some(data) }) => { // check format of data - let _: Vec<(CrossChainId, VerificationStatus)> = from_json(&data)?; + let _: Vec<(CrossChainId, VerificationStatus)> = from_binary(&data)?; // only one verifier, so just return the response as is Ok(Response::new().set_data(data)) @@ -99,11 +99,13 @@ pub fn reply( pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::GetMessagesStatus { messages } => { - let verifier = CONFIG.load(deps.storage)?.verifier; - deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { - contract_addr: verifier.to_string(), - msg: to_json_binary(&voting_msg::QueryMsg::GetMessagesStatus { messages })?, - })) + let res: Vec<(CrossChainId, VerificationStatus)> = + deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: CONFIG.load(deps.storage)?.verifier.to_string(), + msg: to_binary(&voting_msg::QueryMsg::GetMessagesStatus { messages })?, + }))?; + + to_binary(&res) } } } diff --git a/contracts/aggregate-verifier/src/lib.rs b/contracts/aggregate-verifier/src/lib.rs index 1a0902c26..a720f6db9 100644 --- a/contracts/aggregate-verifier/src/lib.rs +++ b/contracts/aggregate-verifier/src/lib.rs @@ -1,4 +1,7 @@ -pub mod client; +mod client; + +pub use client::Client; + pub mod contract; pub mod error; pub mod msg; diff --git a/contracts/aggregate-verifier/tests/mock.rs b/contracts/aggregate-verifier/tests/mock.rs index 3aea3f03f..89376f1b6 100644 --- a/contracts/aggregate-verifier/tests/mock.rs +++ b/contracts/aggregate-verifier/tests/mock.rs @@ -2,7 +2,7 @@ use aggregate_verifier::error::ContractError; use axelar_wasm_std::VerificationStatus; use connection_router_api::{CrossChainId, Message}; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_json_binary, Addr, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{to_binary, Addr, DepsMut, Env, MessageInfo, Response}; use cw_multi_test::{App, ContractWrapper, Executor}; use cw_storage_plus::Map; @@ -33,7 +33,7 @@ pub fn mock_verifier_execute( None => res.push((m.cc_id, VerificationStatus::None)), } } - Ok(Response::new().set_data(to_json_binary(&res)?)) + Ok(Response::new().set_data(to_binary(&res)?)) } MockVotingVerifierExecuteMsg::MessagesVerified { messages } => { for m in messages { @@ -64,7 +64,7 @@ pub fn make_mock_voting_verifier(app: &mut App) -> Addr { |_, _, _, _: MockVotingVerifierInstantiateMsg| { Ok::(Response::new()) }, - |_, _, _: aggregate_verifier::msg::QueryMsg| to_json_binary(&()), + |_, _, _: aggregate_verifier::msg::QueryMsg| to_binary(&()), ); let code_id = app.store_code(Box::new(code)); diff --git a/contracts/aggregate-verifier/tests/test.rs b/contracts/aggregate-verifier/tests/test.rs index ffa6a2131..398739add 100644 --- a/contracts/aggregate-verifier/tests/test.rs +++ b/contracts/aggregate-verifier/tests/test.rs @@ -1,7 +1,7 @@ use aggregate_verifier::msg::ExecuteMsg; use axelar_wasm_std::VerificationStatus; use connection_router_api::{CrossChainId, Message}; -use cosmwasm_std::from_json; +use cosmwasm_std::from_binary; use cosmwasm_std::Addr; use cw_multi_test::App; @@ -48,7 +48,7 @@ fn verify_messages_empty() { &ExecuteMsg::VerifyMessages { messages: vec![] }, ) .unwrap(); - let ret: Vec<(CrossChainId, VerificationStatus)> = from_json(res.data.unwrap()).unwrap(); + let ret: Vec<(CrossChainId, VerificationStatus)> = from_binary(&res.data.unwrap()).unwrap(); assert_eq!(ret, vec![]); } @@ -72,7 +72,7 @@ fn verify_messages_not_verified() { }, ) .unwrap(); - let ret: Vec<(CrossChainId, VerificationStatus)> = from_json(res.data.unwrap()).unwrap(); + let ret: Vec<(CrossChainId, VerificationStatus)> = from_binary(&res.data.unwrap()).unwrap(); assert_eq!( ret, messages @@ -104,7 +104,7 @@ fn verify_messages_verified() { }, ) .unwrap(); - let ret: Vec<(CrossChainId, VerificationStatus)> = from_json(res.data.unwrap()).unwrap(); + let ret: Vec<(CrossChainId, VerificationStatus)> = from_binary(&res.data.unwrap()).unwrap(); assert_eq!( ret, messages @@ -137,7 +137,7 @@ fn verify_messages_mixed_status() { }, ) .unwrap(); - let ret: Vec<(CrossChainId, VerificationStatus)> = from_json(res.data.unwrap()).unwrap(); + let ret: Vec<(CrossChainId, VerificationStatus)> = from_binary(&res.data.unwrap()).unwrap(); assert_eq!( ret, messages diff --git a/contracts/connection-router/Cargo.toml b/contracts/connection-router/Cargo.toml index ef9eae1cc..3f9471ddd 100644 --- a/contracts/connection-router/Cargo.toml +++ b/contracts/connection-router/Cargo.toml @@ -38,7 +38,6 @@ axelar-wasm-std-derive = { workspace = true } connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } @@ -46,12 +45,6 @@ gateway-api = { workspace = true } itertools = { workspace = true } mockall = "0.11.4" report = { workspace = true } -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -serde_json = "1.0.89" -sha3 = { workspace = true } -thiserror = { workspace = true } -valuable = { version = "0.1.0", features = ["derive"] } [dev-dependencies] cw-multi-test = "0.15.1" diff --git a/contracts/connection-router/src/contract.rs b/contracts/connection-router/src/contract.rs index 0d1b44504..7818ae16c 100644 --- a/contracts/connection-router/src/contract.rs +++ b/contracts/connection-router/src/contract.rs @@ -1,6 +1,6 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; use connection_router_api::msg::{ExecuteMsg, QueryMsg}; @@ -108,7 +108,1268 @@ pub fn query( msg: QueryMsg, ) -> Result { match msg { - QueryMsg::GetChainInfo(chain) => to_json_binary(&query::get_chain_info(deps, chain)?), + QueryMsg::GetChainInfo(chain) => to_binary(&query::get_chain_info(deps, chain)?), + QueryMsg::Chains { start_after, limit } => { + to_binary(&query::chains(deps, start_after, limit)?) + } } .map_err(axelar_wasm_std::ContractError::from) } + +#[cfg(test)] +mod test { + use std::{collections::HashMap, str::FromStr}; + + use crate::state::CONFIG; + + use super::*; + + use connection_router_api::{ + error::Error, ChainName, CrossChainId, GatewayDirection, Message, CHAIN_NAME_DELIMITER, + }; + use cosmwasm_std::{ + testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, + Addr, CosmosMsg, Empty, OwnedDeps, WasmMsg, + }; + + const ADMIN_ADDRESS: &str = "admin"; + const GOVERNANCE_ADDRESS: &str = "governance"; + const NEXUS_GATEWAY_ADDRESS: &str = "nexus_gateway"; + const UNAUTHORIZED_ADDRESS: &str = "unauthorized"; + + fn setup() -> OwnedDeps { + let mut deps = mock_dependencies(); + + let config = Config { + admin: Addr::unchecked(ADMIN_ADDRESS), + governance: Addr::unchecked(GOVERNANCE_ADDRESS), + nexus_gateway: Addr::unchecked(NEXUS_GATEWAY_ADDRESS), + }; + CONFIG.save(deps.as_mut().storage, &config).unwrap(); + + deps + } + + struct Chain { + chain_name: ChainName, + gateway: Addr, + } + + fn make_chain(name: &str) -> Chain { + Chain { + chain_name: name.parse().unwrap(), + gateway: Addr::unchecked(name), + } + } + + fn register_chain(deps: DepsMut, chain: &Chain) { + execute( + deps, + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: chain.chain_name.clone(), + gateway_address: chain.gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap(); + } + + #[allow(clippy::arithmetic_side_effects)] + fn generate_messages( + src_chain: &Chain, + dest_chain: &Chain, + nonce: &mut usize, + count: usize, + ) -> Vec { + let mut msgs = vec![]; + for x in 0..count { + *nonce += 1; + let id = format!("tx_id:{}", nonce); + msgs.push(Message { + cc_id: CrossChainId { + id: id.parse().unwrap(), + chain: src_chain.chain_name.clone(), + }, + destination_address: "idc".parse().unwrap(), + destination_chain: dest_chain.chain_name.clone(), + source_address: "idc".parse().unwrap(), + payload_hash: [x as u8; 32], + }) + } + msgs + } + + pub fn assert_contract_err_strings_equal( + actual: impl Into, + expected: impl Into, + ) { + assert_eq!(actual.into().to_string(), expected.into().to_string()); + } + + pub fn assert_messages_in_cosmos_msg( + contract_addr: String, + messages: Vec, + cosmos_msg: CosmosMsg, + ) { + assert_eq!( + CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr, + msg: to_binary(&gateway_api::msg::ExecuteMsg::RouteMessages(messages,)).unwrap(), + funds: vec![], + }), + cosmos_msg + ); + } + + #[test] + fn successful_routing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let nonce: &mut usize = &mut 0; + let messages = generate_messages(ð, &polygon, nonce, 255); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap(); + + assert_eq!(res.messages.len(), 1); + assert_messages_in_cosmos_msg( + polygon.gateway.to_string(), + messages.clone(), + res.messages[0].msg.clone(), + ); + + // try to route twice + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ); + + assert!(res.is_ok(), "{:?}", res); + } + + #[test] + fn wrong_source_chain() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let messages = generate_messages(ð, &polygon, &mut 0, 1); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages), + ) + .unwrap_err(); + + assert_contract_err_strings_equal(err, Error::WrongSourceChain); + } + + #[test] + fn multi_chain_route() { + let mut deps = setup(); + let chains = vec![ + make_chain("ethereum"), + make_chain("polygon"), + make_chain("osmosis"), + make_chain("avalanche"), + make_chain("moonbeam"), + ]; + for c in &chains { + register_chain(deps.as_mut(), c); + } + + let nonce = &mut 0; + let mut all_msgs_by_dest = HashMap::new(); + let mut all_msgs_by_src = HashMap::new(); + for d in &chains { + let mut msgs = vec![]; + for s in &chains { + let sending = generate_messages(s, d, nonce, 50); + + all_msgs_by_src + .entry(s.chain_name.to_string()) + .or_insert(vec![]) + .append(&mut sending.clone()); + + msgs.append(&mut sending.clone()); + } + all_msgs_by_dest.insert(d.chain_name.to_string(), msgs); + } + + for s in &chains { + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(s.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages( + all_msgs_by_src + .get(&s.chain_name.to_string()) + .unwrap() + .clone(), + ), + ) + .unwrap(); + + assert_eq!(res.messages.len(), chains.len()); + + for (i, d) in chains.iter().enumerate() { + assert_messages_in_cosmos_msg( + d.chain_name.to_string(), + all_msgs_by_dest + .get(&d.chain_name.to_string()) + .unwrap() + .clone() + .into_iter() + .filter(|m| m.cc_id.chain == s.chain_name) + .collect::>(), + res.messages[i].msg.clone(), + ); + } + } + } + + #[test] + fn authorization() { + let mut deps = setup(); + let chain = make_chain("ethereum"); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(UNAUTHORIZED_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: chain.chain_name.clone(), + gateway_address: chain.gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: chain.chain_name.clone(), + gateway_address: chain.gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: chain.chain_name.clone(), + gateway_address: chain.gateway.to_string().try_into().unwrap(), + }, + ); + assert!(res.is_ok()); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(UNAUTHORIZED_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: chain.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: chain.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: chain.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(UNAUTHORIZED_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: chain.chain_name.clone(), + direction: GatewayDirection::None, + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: chain.chain_name.clone(), + direction: GatewayDirection::None, + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: chain.chain_name.clone(), + direction: GatewayDirection::None, + }, + ); + assert!(res.is_ok()); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(UNAUTHORIZED_ADDRESS, &[]), + ExecuteMsg::UpgradeGateway { + chain: chain.chain_name.clone(), + contract_address: Addr::unchecked("new gateway") + .to_string() + .try_into() + .unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UpgradeGateway { + chain: chain.chain_name.clone(), + contract_address: Addr::unchecked("new gateway") + .to_string() + .try_into() + .unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::Unauthorized); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::UpgradeGateway { + chain: chain.chain_name.clone(), + contract_address: Addr::unchecked("new gateway") + .to_string() + .try_into() + .unwrap(), + }, + ); + assert!(res.is_ok()); + } + + #[test] + fn upgrade_gateway_outgoing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + let new_gateway = Addr::unchecked("new_gateway"); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::UpgradeGateway { + chain: polygon.chain_name.clone(), + contract_address: new_gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap(); + + let messages = &generate_messages(ð, &polygon, &mut 0, 1); + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap(); + + assert_eq!(res.messages.len(), 1); + assert_messages_in_cosmos_msg( + new_gateway.to_string(), + messages.clone(), + res.messages[0].msg.clone(), + ); + } + + #[test] + fn upgrade_gateway_incoming() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + let new_gateway = Addr::unchecked("new_gateway"); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::UpgradeGateway { + chain: polygon.chain_name.clone(), + contract_address: new_gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap(); + + let messages = &generate_messages(&polygon, ð, &mut 0, 1); + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::GatewayNotRegistered); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(new_gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap(); + + assert_eq!(res.messages.len(), 1); + assert_messages_in_cosmos_msg( + eth.gateway.to_string(), + messages.clone(), + res.messages[0].msg.clone(), + ); + } + + #[test] + fn register_chain_test() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + + let message = &generate_messages(ð, &polygon, &mut 0, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::GatewayNotRegistered); + + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + } + + #[test] + fn chain_already_registered() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + register_chain(deps.as_mut(), ð); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: eth.chain_name, + gateway_address: Addr::unchecked("new gateway") + .to_string() + .try_into() + .unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::ChainAlreadyExists); + + // case insensitive + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: ChainName::from_str("ETHEREUM").unwrap(), + gateway_address: Addr::unchecked("new gateway") + .to_string() + .try_into() + .unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::ChainAlreadyExists); + } + + #[test] + fn invalid_chain_name() { + assert_contract_err_strings_equal( + ChainName::from_str(format!("bad{}", CHAIN_NAME_DELIMITER).as_str()).unwrap_err(), + Error::InvalidChainName, + ); + + assert_contract_err_strings_equal( + ChainName::from_str("").unwrap_err(), + Error::InvalidChainName, + ); + } + + #[test] + fn gateway_already_registered() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::RegisterChain { + chain: polygon.chain_name.clone(), + gateway_address: eth.gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap_err(); + assert_contract_err_strings_equal(err, Error::GatewayAlreadyRegistered); + + register_chain(deps.as_mut(), &polygon); + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE_ADDRESS, &[]), + ExecuteMsg::UpgradeGateway { + chain: eth.chain_name, + contract_address: polygon.gateway.to_string().try_into().unwrap(), + }, + ) + .unwrap_err(); + + assert_contract_err_strings_equal(err, Error::GatewayAlreadyRegistered); + } + + #[test] + fn freeze_incoming() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ) + .unwrap(); + + // can't route from frozen incoming gateway + let message = &generate_messages(&polygon, ð, &mut 0, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + let messages = &generate_messages(ð, &polygon, &mut 0, 1); + // can still route to chain + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap(); + + assert_eq!(res.messages.len(), 1); + assert_messages_in_cosmos_msg( + polygon.gateway.to_string(), + messages.clone(), + res.messages[0].msg.clone(), + ); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ); + assert!(res.is_ok()); + + let message = &generate_messages(&polygon, ð, &mut 0, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + } + + #[test] + fn freeze_outgoing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + // freeze outgoing + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ); + assert!(res.is_ok()); + + // can still send to the chain, messages will queue up + let messages = &generate_messages(ð, &polygon, &mut 0, 1); + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ); + assert!(res.is_ok()); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(messages.clone()), + ) + .unwrap(); + + assert_eq!(res.messages.len(), 1); + assert_messages_in_cosmos_msg( + polygon.gateway.to_string(), + messages.clone(), + res.messages[0].msg.clone(), + ); + } + + #[test] + fn freeze_chain() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let nonce = &mut 0; + + // route a message first + let routed_msg = &generate_messages(ð, &polygon, nonce, 1)[0]; + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![routed_msg.clone()]), + ) + .unwrap(); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + let msg = &generate_messages(ð, &polygon, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![msg.clone()]), + ) + .unwrap_err(); + // can't route to frozen chain + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + // can't route from frozen chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + // unfreeze and test that everything works correctly + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ) + .unwrap(); + + // can route to the chain now + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + + // can route from the chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + } + + #[test] + fn unfreeze_incoming() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + let nonce = &mut 0; + + // unfreeze incoming + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ) + .unwrap(); + + // can route from the chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + // can't route to the chain + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + } + + #[test] + fn unfreeze_outgoing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + let nonce = &mut 0; + + // unfreeze outgoing + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ) + .unwrap(); + + // can't route from frozen chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + // can route to the chain now + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + } + + #[test] + fn freeze_incoming_then_outgoing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ) + .unwrap(); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ) + .unwrap(); + + let nonce = &mut 0; + // can't route to frozen chain + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + // can't route from frozen chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + } + + #[test] + fn freeze_outgoing_then_incoming() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ) + .unwrap(); + + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ) + .unwrap(); + + let nonce = &mut 0; + // can't route to frozen chain + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + // can't route from frozen chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + } + + #[test] + fn unfreeze_incoming_then_outgoing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + // unfreeze incoming + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ) + .unwrap(); + + // unfreeze outgoing + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ) + .unwrap(); + + // can route to the chain now + let nonce = &mut 0; + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + + // can route from the chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + } + + #[test] + fn unfreeze_outgoing_then_incoming() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + // unfreeze outgoing + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Outgoing, + }, + ) + .unwrap(); + + // unfreeze incoming + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Incoming, + }, + ) + .unwrap(); + + // can route to the chain now + let nonce = &mut 0; + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + + // can route from the chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ); + assert!(res.is_ok()); + } + + #[test] + fn unfreeze_nothing() { + let mut deps = setup(); + let eth = make_chain("ethereum"); + let polygon = make_chain("polygon"); + register_chain(deps.as_mut(), ð); + register_chain(deps.as_mut(), &polygon); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::FreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::Bidirectional, + }, + ); + assert!(res.is_ok()); + + // unfreeze nothing + let _ = execute( + deps.as_mut(), + mock_env(), + mock_info(ADMIN_ADDRESS, &[]), + ExecuteMsg::UnfreezeChain { + chain: polygon.chain_name.clone(), + direction: GatewayDirection::None, + }, + ) + .unwrap(); + + let nonce = &mut 0; + let message = &generate_messages(ð, &polygon, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(eth.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + + // can't route from frozen chain + let message = &generate_messages(&polygon, ð, nonce, 1)[0]; + let err = execute( + deps.as_mut(), + mock_env(), + mock_info(polygon.gateway.as_str(), &[]), + ExecuteMsg::RouteMessages(vec![message.clone()]), + ) + .unwrap_err(); + assert_contract_err_strings_equal( + err, + Error::ChainFrozen { + chain: polygon.chain_name.clone(), + }, + ); + } +} diff --git a/contracts/connection-router/src/contract/execute.rs b/contracts/connection-router/src/contract/execute.rs index 861a98e70..c867ef987 100644 --- a/contracts/connection-router/src/contract/execute.rs +++ b/contracts/connection-router/src/contract/execute.rs @@ -1,6 +1,6 @@ use std::vec; -use cosmwasm_std::{to_json_binary, Addr, DepsMut, MessageInfo, Response, StdResult, WasmMsg}; +use cosmwasm_std::{to_binary, Addr, DepsMut, MessageInfo, Response, StdResult, WasmMsg}; use error_stack::report; use itertools::Itertools; @@ -190,7 +190,7 @@ where Ok(WasmMsg::Execute { contract_addr: gateway.to_string(), - msg: to_json_binary(&gateway_api::msg::ExecuteMsg::RouteMessages( + msg: to_binary(&gateway_api::msg::ExecuteMsg::RouteMessages( msgs.cloned().collect(), )) .expect("must serialize message"), diff --git a/contracts/connection-router/src/contract/query.rs b/contracts/connection-router/src/contract/query.rs index d2274faa0..e7e29bc40 100644 --- a/contracts/connection-router/src/contract/query.rs +++ b/contracts/connection-router/src/contract/query.rs @@ -1,10 +1,15 @@ +use cosmwasm_std::{Deps, Order}; +use cw_storage_plus::Bound; + use connection_router_api::error::Error; use connection_router_api::{ChainEndpoint, ChainName}; -use cosmwasm_std::Deps; use error_stack::{Result, ResultExt}; use crate::state::chain_endpoints; +// Pagination limits +const DEFAULT_LIMIT: u32 = u32::MAX; + pub fn get_chain_info(deps: Deps, chain: ChainName) -> Result { chain_endpoints() .may_load(deps.storage, chain) @@ -12,6 +17,24 @@ pub fn get_chain_info(deps: Deps, chain: ChainName) -> Result, + limit: Option, +) -> Result, Error> { + let limit = limit.unwrap_or(DEFAULT_LIMIT) as usize; + let start = start_after.map(Bound::exclusive); + + chain_endpoints() + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|item| { + item.map(|(_, endpoint)| endpoint) + .change_context(Error::StoreFailure) + }) + .collect() +} + #[cfg(test)] mod test { use axelar_wasm_std::flagset::FlagSet; @@ -51,4 +74,59 @@ mod test { assert!(result.is_err()); assert_eq!(result.unwrap_err().current_context(), &Error::ChainNotFound); } + + #[test] + fn paginated_chains() { + let mut deps = mock_dependencies(); + let chains: Vec = vec![ + "a-chain".parse().unwrap(), + "b-chain".parse().unwrap(), + "c-chain".parse().unwrap(), + "d-chain".parse().unwrap(), + ]; + + let endpoints: Vec = chains + .iter() + .map(|chain| ChainEndpoint { + name: chain.clone(), + gateway: Gateway { + address: Addr::unchecked(format!("{} gateway", chain)), + }, + frozen_status: FlagSet::from(GatewayDirection::None), + }) + .collect(); + + // save end points to storage + for chain_info in endpoints.iter() { + assert!(chain_endpoints() + .save(deps.as_mut().storage, chain_info.name.clone(), chain_info) + .is_ok()); + } + + // no pagination + let result = super::chains(deps.as_ref(), None, None).unwrap(); + assert_eq!(result.len(), 4); + assert_eq!(result, endpoints); + + // with limit + let result = super::chains(deps.as_ref(), None, Some(2)).unwrap(); + assert_eq!(result.len(), 2); + assert_eq!(result, vec![endpoints[0].clone(), endpoints[1].clone()]); + + // with page + let result = + super::chains(deps.as_ref(), Some("c-chain".parse().unwrap()), Some(2)).unwrap(); + assert_eq!(result.len(), 1); + assert_eq!(result, vec![endpoints[3].clone()]); + + // start after the last chain + let result = + super::chains(deps.as_ref(), Some("d-chain".parse().unwrap()), Some(2)).unwrap(); + assert_eq!(result.len(), 0); + + // with a key out of the scope + let result = + super::chains(deps.as_ref(), Some("e-chain".parse().unwrap()), Some(2)).unwrap(); + assert_eq!(result.len(), 0); + } } diff --git a/contracts/connection-router/tests/mock.rs b/contracts/connection-router/tests/mock.rs deleted file mode 100644 index 18fbcb472..000000000 --- a/contracts/connection-router/tests/mock.rs +++ /dev/null @@ -1,88 +0,0 @@ -use connection_router_api::error::Error; -use connection_router_api::{CrossChainId, Message}; -use cosmwasm_schema::cw_serde; -use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult, -}; -use cw_multi_test::{App, ContractWrapper, Executor}; -use cw_storage_plus::Map; - -const MOCK_GATEWAY_MESSAGES: Map = Map::new("gateway_messages"); - -#[cw_serde] -pub enum MockGatewayExecuteMsg { - RouteMessages(Vec), -} - -pub fn mock_gateway_execute( - deps: DepsMut, - _env: Env, - _info: MessageInfo, - msg: MockGatewayExecuteMsg, -) -> Result { - match msg { - MockGatewayExecuteMsg::RouteMessages(messages) => { - for m in messages { - MOCK_GATEWAY_MESSAGES.save(deps.storage, m.cc_id.clone(), &m)?; - } - Ok(Response::new()) - } - } -} - -#[cw_serde] -pub enum MockGatewayQueryMsg { - GetOutgoingMessages { ids: Vec }, -} -pub fn mock_gateway_query(deps: Deps, _env: Env, msg: MockGatewayQueryMsg) -> StdResult { - let mut msgs = vec![]; - - match msg { - MockGatewayQueryMsg::GetOutgoingMessages { ids } => { - for id in ids { - if let Some(m) = MOCK_GATEWAY_MESSAGES.may_load(deps.storage, id)? { - msgs.push(m) - } - } - } - } - to_json_binary(&msgs) -} - -pub fn get_gateway_messages( - app: &mut App, - gateway_address: Addr, - msgs: &[Message], -) -> Vec { - app.wrap() - .query_wasm_smart( - gateway_address, - &MockGatewayQueryMsg::GetOutgoingMessages { - ids: msgs.iter().map(|msg| msg.cc_id.clone()).collect(), - }, - ) - .unwrap() -} - -pub fn make_mock_gateway(app: &mut App) -> Addr { - let code = ContractWrapper::new( - mock_gateway_execute, - |_, _, _, _: connection_router::msg::InstantiateMsg| Ok::(Response::new()), - mock_gateway_query, - ); - let code_id = app.store_code(Box::new(code)); - - app.instantiate_contract( - code_id, - Addr::unchecked("sender"), - &connection_router::msg::InstantiateMsg { - admin_address: Addr::unchecked("admin").to_string(), - governance_address: Addr::unchecked("governance").to_string(), - nexus_gateway: Addr::unchecked("nexus_gateway").to_string(), - }, - &[], - "Contract", - None, - ) - .unwrap() -} diff --git a/contracts/connection-router/tests/test.rs b/contracts/connection-router/tests/test.rs deleted file mode 100644 index abb24c110..000000000 --- a/contracts/connection-router/tests/test.rs +++ /dev/null @@ -1,1290 +0,0 @@ -pub mod mock; -mod test_utils; - -use std::str::FromStr; -use std::{collections::HashMap, vec}; - -use connection_router_api::error::Error; -use connection_router_api::msg::ExecuteMsg; -use connection_router_api::{ - ChainName, CrossChainId, GatewayDirection, Message, CHAIN_NAME_DELIMITER, -}; -use cosmwasm_std::Addr; -use cw_multi_test::App; -use integration_tests::contract::Contract; - -use crate::test_utils::ConnectionRouterContract; - -struct TestConfig { - app: App, - admin_address: Addr, - governance_address: Addr, - connection_router: ConnectionRouterContract, -} - -struct Chain { - chain_name: ChainName, - gateway: Addr, -} - -fn setup() -> TestConfig { - let mut app = App::default(); - - let admin_address = Addr::unchecked("admin"); - let governance_address = Addr::unchecked("governance"); - let nexus_gateway = Addr::unchecked("nexus_gateway"); - - let connection_router = ConnectionRouterContract::instantiate_contract( - &mut app, - admin_address.clone(), - governance_address.clone(), - nexus_gateway.clone(), - ); - - TestConfig { - app, - admin_address, - governance_address, - connection_router, - } -} - -fn make_chain(name: &str, config: &mut TestConfig) -> Chain { - let gateway = mock::make_mock_gateway(&mut config.app); - Chain { - chain_name: name.parse().unwrap(), - gateway, - } -} - -fn register_chain(config: &mut TestConfig, chain: &Chain) { - let _ = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::RegisterChain { - chain: chain.chain_name.clone(), - gateway_address: chain.gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap(); -} - -#[allow(clippy::arithmetic_side_effects)] -fn generate_messages( - src_chain: &Chain, - dest_chain: &Chain, - nonce: &mut usize, - count: usize, -) -> Vec { - let mut msgs = vec![]; - for x in 0..count { - *nonce += 1; - let id = format!("tx_id:{}", nonce); - msgs.push(Message { - cc_id: CrossChainId { - id: id.parse().unwrap(), - chain: src_chain.chain_name.clone(), - }, - destination_address: "idc".parse().unwrap(), - destination_chain: dest_chain.chain_name.clone(), - source_address: "idc".parse().unwrap(), - payload_hash: [x as u8; 32], - }) - } - msgs -} - -// tests that each message is properly delivered -#[test] -fn route() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let nonce: &mut usize = &mut 0; - let messages = generate_messages(ð, &polygon, nonce, 255); - - let _ = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(messages.clone()), - ) - .unwrap(); - - let outgoing_messages = mock::get_gateway_messages(&mut config.app, polygon.gateway, &messages); - - assert_eq!(messages.len(), outgoing_messages.len()); - assert_eq!(messages, outgoing_messages); - - // try to route twice - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(messages.clone()), - ); - - assert!(res.is_ok()); -} - -#[test] -fn wrong_source_chain() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let messages = &generate_messages(ð, &polygon, &mut 0, 1)[0]; - - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![messages.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::WrongSourceChain); -} - -#[test] -fn multi_chain_route() { - let mut config = setup(); - let chains = vec![ - make_chain("ethereum", &mut config), - make_chain("polygon", &mut config), - make_chain("osmosis", &mut config), - make_chain("avalanche", &mut config), - make_chain("moonbeam", &mut config), - ]; - for c in &chains { - register_chain(&mut config, c); - } - - let nonce = &mut 0; - let mut all_msgs_by_dest = HashMap::new(); - let mut all_msgs_by_src = HashMap::new(); - for d in &chains { - let mut msgs = vec![]; - for s in &chains { - let mut sending = generate_messages(s, d, nonce, 50); - - all_msgs_by_src - .entry(s.chain_name.to_string()) - .or_insert(vec![]) - .append(&mut sending); - - msgs.append(&mut sending); - } - all_msgs_by_dest.insert(d.chain_name.to_string(), msgs); - } - - for chain in &chains { - let res = config.connection_router.execute( - &mut config.app, - chain.gateway.clone(), - &ExecuteMsg::RouteMessages( - all_msgs_by_src - .get_mut(&chain.chain_name.to_string()) - .unwrap() - .clone(), - ), - ); - assert!(res.is_ok()); - } - - for chain in &chains { - let expected = all_msgs_by_dest.get(&chain.chain_name.to_string()).unwrap(); - let actual = mock::get_gateway_messages(&mut config.app, chain.gateway.clone(), expected); - - assert_eq!(expected.len(), actual.len()); - assert_eq!(expected, &actual); - } -} - -#[test] -fn authorization() { - let mut config = setup(); - let chain = make_chain("ethereum", &mut config); - - let err = config - .connection_router - .execute( - &mut config.app, - Addr::unchecked("random"), - &ExecuteMsg::RegisterChain { - chain: chain.chain_name.clone(), - gateway_address: chain.gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let err = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::RegisterChain { - chain: chain.chain_name.clone(), - gateway_address: chain.gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let res = config.connection_router.execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::RegisterChain { - chain: chain.chain_name.clone(), - gateway_address: chain.gateway.to_string().try_into().unwrap(), - }, - ); - assert!(res.is_ok()); - - let err = config - .connection_router - .execute( - &mut config.app, - Addr::unchecked("random"), - &ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let err = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - let err = config - .connection_router - .execute( - &mut config.app, - Addr::unchecked("random"), - &ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::None, - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let err = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::None, - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: chain.chain_name.clone(), - direction: GatewayDirection::None, - }, - ); - assert!(res.is_ok()); - - let err = config - .connection_router - .execute( - &mut config.app, - Addr::unchecked("random"), - &ExecuteMsg::UpgradeGateway { - chain: chain.chain_name.clone(), - contract_address: Addr::unchecked("new gateway") - .to_string() - .try_into() - .unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let err = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UpgradeGateway { - chain: chain.chain_name.clone(), - contract_address: Addr::unchecked("new gateway") - .to_string() - .try_into() - .unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::Unauthorized); - - let res = config.connection_router.execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::UpgradeGateway { - chain: chain.chain_name.clone(), - contract_address: Addr::unchecked("new gateway") - .to_string() - .try_into() - .unwrap(), - }, - ); - assert!(res.is_ok()); -} - -#[test] -fn upgrade_gateway_outgoing() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - let new_gateway = mock::make_mock_gateway(&mut config.app); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::UpgradeGateway { - chain: polygon.chain_name.clone(), - contract_address: new_gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap(); - - let message = &generate_messages(ð, &polygon, &mut 0, 1)[0]; - let _ = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap(); - - let outgoing_messages = - mock::get_gateway_messages(&mut config.app, new_gateway, &[message.clone()]); - assert_eq!(outgoing_messages.len(), 1); - assert_eq!(message.clone(), outgoing_messages[0]); - - let outgoing_messages = - mock::get_gateway_messages(&mut config.app, polygon.gateway, &[message.clone()]); - assert_eq!(outgoing_messages.len(), 0); -} - -#[test] -fn upgrade_gateway_incoming() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - let new_gateway = mock::make_mock_gateway(&mut config.app); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::UpgradeGateway { - chain: polygon.chain_name.clone(), - contract_address: new_gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap(); - - let message = &generate_messages(&polygon, ð, &mut 0, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::GatewayNotRegistered); - - let res = config.connection_router.execute( - &mut config.app, - new_gateway, - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - - let messages = mock::get_gateway_messages(&mut config.app, eth.gateway, &[message.clone()]); - assert_eq!(messages.len(), 1); - assert_eq!(messages[0], message.clone()); -} - -#[test] -fn register_chain_test() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - - let message = &generate_messages(ð, &polygon, &mut 0, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::GatewayNotRegistered); - - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); -} - -#[test] -fn chain_already_registered() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - register_chain(&mut config, ð); - - let err = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::RegisterChain { - chain: eth.chain_name, - gateway_address: Addr::unchecked("new gateway") - .to_string() - .try_into() - .unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::ChainAlreadyExists); - - // case insensitive - let err = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::RegisterChain { - chain: ChainName::from_str("ETHEREUM").unwrap(), - gateway_address: Addr::unchecked("new gateway") - .to_string() - .try_into() - .unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::ChainAlreadyExists); -} - -#[test] -fn invalid_chain_name() { - test_utils::are_contract_err_strings_equal( - ChainName::from_str(format!("bad{}", CHAIN_NAME_DELIMITER).as_str()).unwrap_err(), - Error::InvalidChainName, - ); - - test_utils::are_contract_err_strings_equal( - ChainName::from_str("").unwrap_err(), - Error::InvalidChainName, - ); -} - -#[test] -fn gateway_already_registered() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - - let err = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::RegisterChain { - chain: polygon.chain_name.clone(), - gateway_address: eth.gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal(err, Error::GatewayAlreadyRegistered); - - register_chain(&mut config, &polygon); - let err = config - .connection_router - .execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::UpgradeGateway { - chain: eth.chain_name, - contract_address: polygon.gateway.to_string().try_into().unwrap(), - }, - ) - .unwrap_err(); - - test_utils::are_contract_err_strings_equal(err, Error::GatewayAlreadyRegistered); -} - -#[test] -fn freeze_incoming() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ) - .unwrap(); - - // can't route from frozen incoming gateway - let message = &generate_messages(&polygon, ð, &mut 0, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - let message = &generate_messages(ð, &polygon, &mut 0, 1)[0]; - // can still route to chain - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - - let messages = - mock::get_gateway_messages(&mut config.app, polygon.gateway.clone(), &[message.clone()]); - assert_eq!(&messages[0], message); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ); - assert!(res.is_ok()); - - let message = &generate_messages(&polygon, ð, &mut 0, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); -} - -#[test] -fn freeze_outgoing() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - // freeze outgoing - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ); - assert!(res.is_ok()); - - // can still send to the chain, messages will queue up - let message = &generate_messages(ð, &polygon, &mut 0, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ); - assert!(res.is_ok()); - - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - let messages = mock::get_gateway_messages(&mut config.app, polygon.gateway, &[message.clone()]); - assert_eq!(messages.len(), 1); - assert_eq!(messages[0], message.clone()); -} - -#[test] -fn freeze_chain() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let nonce = &mut 0; - - // route a message first - let routed_msg = &generate_messages(ð, &polygon, nonce, 1)[0]; - let _ = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![routed_msg.clone()]), - ) - .unwrap(); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - let msg = &generate_messages(ð, &polygon, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![msg.clone()]), - ) - .unwrap_err(); - // can't route to frozen chain - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - // can't route from frozen chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - // unfreeze and test that everything works correctly - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ) - .unwrap(); - - // routed message should have been preserved - let outgoing_messages = mock::get_gateway_messages( - &mut config.app, - polygon.gateway.clone(), - &[routed_msg.clone()], - ); - assert_eq!(1, outgoing_messages.len()); - assert_eq!(routed_msg.clone(), outgoing_messages[0]); - - // can route to the chain now - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - - // can route from the chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); -} - -#[test] -fn unfreeze_incoming() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - let nonce = &mut 0; - - // unfreeze incoming - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ) - .unwrap(); - - // can route from the chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - // can't route to the chain - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); -} - -#[test] -fn unfreeze_outgoing() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - let nonce = &mut 0; - - // unfreeze outgoing - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ) - .unwrap(); - - // can't route from frozen chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - // can route to the chain now - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); -} - -#[test] -fn freeze_incoming_then_outgoing() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ) - .unwrap(); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ) - .unwrap(); - - let nonce = &mut 0; - // can't route to frozen chain - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - // can't route from frozen chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); -} - -#[test] -fn freeze_outgoing_then_incoming() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ) - .unwrap(); - - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ) - .unwrap(); - - let nonce = &mut 0; - // can't route to frozen chain - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - // can't route from frozen chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); -} - -#[test] -fn unfreeze_incoming_then_outgoing() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - // unfreeze incoming - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ) - .unwrap(); - - // unfreeze outgoing - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ) - .unwrap(); - - // can route to the chain now - let nonce = &mut 0; - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - - // can route from the chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); -} - -#[test] -fn unfreeze_outgoing_then_incoming() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - // unfreeze outgoing - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Outgoing, - }, - ) - .unwrap(); - - // unfreeze incoming - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Incoming, - }, - ) - .unwrap(); - - // can route to the chain now - let nonce = &mut 0; - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); - - // can route from the chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let res = config.connection_router.execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_ok()); -} - -#[test] -fn unfreeze_nothing() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::FreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::Bidirectional, - }, - ); - assert!(res.is_ok()); - - // unfreeze nothing - let _ = config - .connection_router - .execute( - &mut config.app, - config.admin_address.clone(), - &ExecuteMsg::UnfreezeChain { - chain: polygon.chain_name.clone(), - direction: GatewayDirection::None, - }, - ) - .unwrap(); - - let nonce = &mut 0; - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); - - // can't route from frozen chain - let message = &generate_messages(&polygon, ð, nonce, 1)[0]; - let err = config - .connection_router - .execute( - &mut config.app, - polygon.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ) - .unwrap_err(); - test_utils::are_contract_err_strings_equal( - err, - Error::ChainFrozen { - chain: polygon.chain_name.clone(), - }, - ); -} - -#[test] -fn bad_gateway() { - let mut config = setup(); - let eth = make_chain("ethereum", &mut config); - let polygon = make_chain("polygon", &mut config); - - register_chain(&mut config, ð); - register_chain(&mut config, &polygon); - - let res = config.connection_router.execute( - &mut config.app, - config.governance_address.clone(), - &ExecuteMsg::UpgradeGateway { - chain: polygon.chain_name.clone(), - contract_address: Addr::unchecked("some random address") - .to_string() - .try_into() - .unwrap(), // gateway address does not implement required interface - }, - ); - - assert!(res.is_ok()); - - let nonce: &mut usize = &mut 0; - let message = &generate_messages(ð, &polygon, nonce, 1)[0]; - - let res = config.connection_router.execute( - &mut config.app, - eth.gateway.clone(), - &ExecuteMsg::RouteMessages(vec![message.clone()]), - ); - assert!(res.is_err()); -} diff --git a/contracts/connection-router/tests/test_utils/mod.rs b/contracts/connection-router/tests/test_utils/mod.rs deleted file mode 100644 index 96b93932d..000000000 --- a/contracts/connection-router/tests/test_utils/mod.rs +++ /dev/null @@ -1,53 +0,0 @@ -use connection_router::{ - contract::{execute, instantiate, query}, - msg::InstantiateMsg, -}; -use connection_router_api::msg::{ExecuteMsg, QueryMsg}; -use cosmwasm_std::Addr; -use cw_multi_test::{App, ContractWrapper, Executor}; -use integration_tests::contract::Contract; - -#[derive(Clone)] -pub struct ConnectionRouterContract { - pub contract_addr: Addr, -} - -impl ConnectionRouterContract { - pub fn instantiate_contract(app: &mut App, admin: Addr, governance: Addr, nexus: Addr) -> Self { - let code = ContractWrapper::new(execute, instantiate, query); - let code_id = app.store_code(Box::new(code)); - - let contract_addr = app - .instantiate_contract( - code_id, - Addr::unchecked("router"), - &InstantiateMsg { - admin_address: admin.to_string(), - governance_address: governance.to_string(), - nexus_gateway: nexus.to_string(), - }, - &[], - "Contract", - None, - ) - .unwrap(); - - ConnectionRouterContract { contract_addr } - } -} - -impl Contract for ConnectionRouterContract { - type QMsg = QueryMsg; - type ExMsg = ExecuteMsg; - - fn contract_address(&self) -> Addr { - self.contract_addr.clone() - } -} - -pub fn are_contract_err_strings_equal( - actual: impl Into, - expected: impl Into, -) { - assert_eq!(actual.into().to_string(), expected.into().to_string()); -} diff --git a/contracts/gateway/Cargo.toml b/contracts/gateway/Cargo.toml index 05ef0210e..e5586ac5b 100644 --- a/contracts/gateway/Cargo.toml +++ b/contracts/gateway/Cargo.toml @@ -38,19 +38,17 @@ optimize = """docker run --rm -v "$(pwd)":/code \ aggregate-verifier = { workspace = true, features = ["library"] } axelar-wasm-std = { workspace = true } axelar-wasm-std-derive = { workspace = true } +client = { workspace = true } connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } gateway-api = { workspace = true } itertools = { workspace = true } -mockall = "0.11.3" report = { workspace = true } -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -serde_json = "1.0.89" +serde = { workspace = true } +serde_json = { workspace = true } thiserror = { workspace = true } [dev-dependencies] diff --git a/contracts/gateway/src/contract.rs b/contracts/gateway/src/contract.rs index 1f5a907c7..f275c6157 100644 --- a/contracts/gateway/src/contract.rs +++ b/contracts/gateway/src/contract.rs @@ -1,3 +1,4 @@ +use connection_router_api::CrossChainId; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response}; @@ -52,12 +53,14 @@ pub enum Error { InvalidAddress, #[error("failed to query message status")] MessageStatus, + #[error("message with ID {0} not found")] + MessageNotFound(CrossChainId), } mod internal { - use aggregate_verifier::client::Verifier; + use client::Client; use connection_router_api::client::Router; - use cosmwasm_std::{to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; + use cosmwasm_std::{to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response}; use error_stack::{Result, ResultExt}; use gateway_api::msg::{ExecuteMsg, QueryMsg}; @@ -97,10 +100,7 @@ mod internal { msg: ExecuteMsg, ) -> Result { let config = state::load_config(deps.storage).change_context(Error::ConfigMissing)?; - let verifier = Verifier { - address: config.verifier, - querier: deps.querier, - }; + let verifier = Client::new(deps.querier, config.verifier).into(); let router = Router { address: config.router, @@ -122,7 +122,7 @@ mod internal { match msg { QueryMsg::GetOutgoingMessages { message_ids } => { let msgs = contract::query::get_outgoing_messages(deps.storage, message_ids)?; - to_json_binary(&msgs).change_context(Error::SerializeResponse) + to_binary(&msgs).change_context(Error::SerializeResponse) } } } diff --git a/contracts/gateway/src/contract/execute.rs b/contracts/gateway/src/contract/execute.rs index 198696d7c..0c81508d0 100644 --- a/contracts/gateway/src/contract/execute.rs +++ b/contracts/gateway/src/contract/execute.rs @@ -1,4 +1,3 @@ -use aggregate_verifier::client::Verifier; use axelar_wasm_std::{FnExt, VerificationStatus}; use connection_router_api::client::Router; use connection_router_api::Message; @@ -10,14 +9,17 @@ use crate::contract::Error; use crate::events::GatewayEvent; use crate::state; -pub fn verify_messages(verifier: &Verifier, msgs: Vec) -> Result { +pub fn verify_messages( + verifier: &aggregate_verifier::Client, + msgs: Vec, +) -> Result { apply(verifier, msgs, |msgs_by_status| { verify(verifier, msgs_by_status) }) } pub(crate) fn route_incoming_messages( - verifier: &Verifier, + verifier: &aggregate_verifier::Client, router: &Router, msgs: Vec, ) -> Result { @@ -45,12 +47,12 @@ pub(crate) fn route_outgoing_messages( } fn apply( - verifier: &Verifier, + verifier: &aggregate_verifier::Client, msgs: Vec, action: impl Fn(Vec<(VerificationStatus, Vec)>) -> (Option, Vec), ) -> Result { check_for_duplicates(msgs)? - .then(|msgs| verifier.messages_with_status(msgs)) + .then(|msgs| verifier.messages_status(msgs)) .change_context(Error::MessageStatus)? .then(group_by_status) .then(action) @@ -86,7 +88,7 @@ fn group_by_status( } fn verify( - verifier: &Verifier, + verifier: &aggregate_verifier::Client, msgs_by_status: Vec<(VerificationStatus, Vec)>, ) -> (Option, Vec) { msgs_by_status @@ -98,7 +100,7 @@ fn verify( ) }) .then(flat_unzip) - .then(|(msgs, events)| (verifier.verify(msgs), events)) + .then(|(msgs, events)| (verifier.verify_messages(msgs), events)) } fn route( diff --git a/contracts/gateway/src/contract/query.rs b/contracts/gateway/src/contract/query.rs index 3a173f13f..ccace2dae 100644 --- a/contracts/gateway/src/contract/query.rs +++ b/contracts/gateway/src/contract/query.rs @@ -1,9 +1,9 @@ +use crate::contract::Error; +use axelar_wasm_std::error::extend_err; use connection_router_api::{CrossChainId, Message}; use cosmwasm_std::Storage; -use error_stack::{Result, ResultExt}; -use itertools::Itertools; +use error_stack::{report, Result, ResultExt}; -use crate::contract::Error; use crate::state; pub fn get_outgoing_messages( @@ -12,7 +12,120 @@ pub fn get_outgoing_messages( ) -> Result, Error> { cross_chain_ids .into_iter() - .filter_map(|id| state::may_load_outgoing_msg(storage, id).transpose()) - .try_collect() + .map(|id| try_load_msg(storage, id)) + .fold(Ok(vec![]), accumulate_errs) +} + +fn try_load_msg(storage: &dyn Storage, id: CrossChainId) -> Result { + state::may_load_outgoing_msg(storage, id.clone()) .change_context(Error::InvalidStoreAccess) + .transpose() + .unwrap_or(Err(report!(Error::MessageNotFound(id)))) +} + +fn accumulate_errs( + acc: Result, Error>, + msg: Result, +) -> Result, Error> { + match (acc, msg) { + (Ok(mut acc), Ok(msg)) => { + acc.push(msg); + Ok(acc) + } + (Err(acc), Ok(_)) => Err(acc), + (acc, Err(msg_err)) => extend_err(acc, msg_err), + } +} + +#[cfg(test)] +mod test { + use crate::state; + use connection_router_api::{CrossChainId, Message}; + use cosmwasm_std::testing::mock_dependencies; + + #[test] + fn get_outgoing_messages_all_messages_present_returns_all() { + let mut deps = mock_dependencies(); + + let messages = generate_messages(); + + for message in messages.iter() { + state::save_outgoing_msg(deps.as_mut().storage, message.cc_id.clone(), message) + .unwrap(); + } + + let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); + + let res = super::get_outgoing_messages(&deps.storage, ids).unwrap(); + assert_eq!(res, messages); + } + + #[test] + fn get_outgoing_messages_nothing_stored_returns_not_found_error() { + let deps = mock_dependencies(); + + let messages = generate_messages(); + let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); + + let res = super::get_outgoing_messages(&deps.storage, ids); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().current_frames().len(), messages.len()); + } + + #[test] + fn get_outgoing_messages_only_partially_found_returns_not_found_error() { + let mut deps = mock_dependencies(); + + let messages = generate_messages(); + + state::save_outgoing_msg( + deps.as_mut().storage, + messages[1].cc_id.clone(), + &messages[1], + ) + .unwrap(); + + let ids = messages.iter().map(|msg| msg.cc_id.clone()).collect(); + + let res = super::get_outgoing_messages(&deps.storage, ids); + + assert!(res.is_err()); + assert_eq!(res.unwrap_err().current_frames().len(), messages.len() - 1); + } + + fn generate_messages() -> Vec { + vec![ + Message { + cc_id: CrossChainId { + chain: "chain1".parse().unwrap(), + id: "id1".parse().unwrap(), + }, + destination_address: "addr1".parse().unwrap(), + destination_chain: "chain2".parse().unwrap(), + source_address: "addr2".parse().unwrap(), + payload_hash: [0; 32], + }, + Message { + cc_id: CrossChainId { + chain: "chain2".parse().unwrap(), + id: "id2".parse().unwrap(), + }, + destination_address: "addr3".parse().unwrap(), + destination_chain: "chain3".parse().unwrap(), + source_address: "addr4".parse().unwrap(), + payload_hash: [1; 32], + }, + Message { + cc_id: CrossChainId { + chain: "chain3".parse().unwrap(), + id: "id3".parse().unwrap(), + }, + destination_address: "addr5".parse().unwrap(), + destination_chain: "chain4".parse().unwrap(), + source_address: "addr6".parse().unwrap(), + payload_hash: [2; 32], + }, + ] + } } diff --git a/contracts/gateway/tests/contract.rs b/contracts/gateway/tests/contract.rs index a20ba1663..de4355157 100644 --- a/contracts/gateway/tests/contract.rs +++ b/contracts/gateway/tests/contract.rs @@ -9,7 +9,7 @@ use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockQuerier} #[cfg(not(feature = "generate_golden_files"))] use cosmwasm_std::Response; use cosmwasm_std::{ - from_json, to_json_binary, Addr, ContractResult, DepsMut, QuerierResult, WasmQuery, + from_binary, to_binary, Addr, ContractResult, DepsMut, QuerierResult, WasmQuery, }; use itertools::Itertools; use serde::Serialize; @@ -142,14 +142,15 @@ fn successful_route_outgoing() { }; // check no messages are outgoing - iter::repeat(query(deps.as_ref(), mock_env(), query_msg.clone()).unwrap()) - .take(2) - .for_each(|response| { - assert_eq!( - response, - to_json_binary::>(&vec![]).unwrap() - ) - }); + let query_response = query(deps.as_ref(), mock_env(), query_msg.clone()); + if msgs.is_empty() { + assert_eq!( + query_response.unwrap(), + to_binary::>(&vec![]).unwrap() + ) + } else { + assert!(query_response.is_err()); + } // check routing of outgoing messages is idempotent let response = iter::repeat( @@ -172,7 +173,7 @@ fn successful_route_outgoing() { // check all outgoing messages are stored because the router (sender) is implicitly trusted iter::repeat(query(deps.as_ref(), mock_env().clone(), query_msg).unwrap()) .take(2) - .for_each(|response| assert_eq!(response, to_json_binary(&msgs).unwrap())); + .for_each(|response| assert_eq!(response, to_binary(&msgs).unwrap())); } let golden_file = "tests/test_route_outgoing.json"; @@ -422,8 +423,8 @@ fn update_query_handler( ) { let handler = move |msg: &WasmQuery| match msg { WasmQuery::Smart { msg, .. } => { - let result = handler(from_json(msg).expect("should not fail to deserialize")) - .map(|response| to_json_binary(&response).expect("should not fail to serialize")); + let result = handler(from_binary(msg).expect("should not fail to deserialize")) + .map(|response| to_binary(&response).expect("should not fail to serialize")); QuerierResult::Ok(ContractResult::from(result)) } diff --git a/contracts/monitoring/Cargo.toml b/contracts/monitoring/Cargo.toml index e27833fd7..a00ab0e67 100644 --- a/contracts/monitoring/Cargo.toml +++ b/contracts/monitoring/Cargo.toml @@ -38,11 +38,11 @@ axelar-wasm-std-derive = { workspace = true } connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } +thiserror = { workspace = true } [dev-dependencies] cw-multi-test = "0.15.1" diff --git a/contracts/monitoring/src/contract.rs b/contracts/monitoring/src/contract.rs index fce2ae13f..45244baf0 100644 --- a/contracts/monitoring/src/contract.rs +++ b/contracts/monitoring/src/contract.rs @@ -4,6 +4,8 @@ use crate::state::{Config, CONFIG}; use cosmwasm_std::entry_point; use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo, Response, StdResult}; +use crate::execute; + #[cfg_attr(not(feature = "library"), entry_point)] pub fn instantiate( deps: DepsMut, @@ -21,14 +23,22 @@ pub fn instantiate( } #[cfg_attr(not(feature = "library"), entry_point)] -#[allow(dead_code)] pub fn execute( - _deps: DepsMut, + deps: DepsMut, _env: Env, - _info: MessageInfo, - _msg: ExecuteMsg, + info: MessageInfo, + msg: ExecuteMsg, ) -> Result { - Ok(Response::new()) + match msg { + ExecuteMsg::RegisterProverContract { + chain_name, + new_prover_addr, + } => { + execute::check_governance(&deps, info)?; + execute::register_prover(deps, chain_name, new_prover_addr) + } + } + .map_err(axelar_wasm_std::ContractError::from) } #[cfg_attr(not(feature = "library"), entry_point)] @@ -40,3 +50,97 @@ pub fn query(_deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } } } + +#[cfg(test)] +mod tests { + use crate::error::ContractError; + use crate::query; + use connection_router_api::ChainName; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + use cosmwasm_std::Addr; + + use super::*; + + #[test] + #[allow(clippy::arithmetic_side_effects)] + fn test_instantiation() { + let governance = "governance_for_monitoring"; + let mut deps = mock_dependencies(); + let info = mock_info("instantiator", &[]); + let env = mock_env(); + + let res = instantiate( + deps.as_mut(), + env, + info, + InstantiateMsg { + governance_address: governance.to_string(), + }, + ); + assert!(res.is_ok()); + + let config = CONFIG.load(deps.as_ref().storage).unwrap(); + assert_eq!(config.governance, governance); + } + + #[test] + fn add_prover_from_goverance_succeeds() { + let governance = "governance_for_monitoring"; + let mut deps = mock_dependencies(); + let info = mock_info("instantiator", &[]); + let env = mock_env(); + + let _ = instantiate( + deps.as_mut(), + env.clone(), + info, + InstantiateMsg { + governance_address: governance.to_string(), + }, + ); + + let eth_prover = Addr::unchecked("eth_prover"); + let eth: ChainName = "Ethereum".to_string().try_into().unwrap(); + let msg = ExecuteMsg::RegisterProverContract { + chain_name: eth.clone(), + new_prover_addr: eth_prover.clone(), + }; + let _res = execute(deps.as_mut(), mock_env(), mock_info(governance, &[]), msg).unwrap(); + let chain_provers = query::provers(deps.as_ref(), eth.clone()).unwrap(); + assert_eq!(chain_provers, vec![eth_prover]); + } + + #[test] + fn add_prover_from_random_address_fails() { + let governance = "governance_for_monitoring"; + let mut deps = mock_dependencies(); + let info = mock_info("instantiator", &[]); + let env = mock_env(); + + let _ = instantiate( + deps.as_mut(), + env.clone(), + info, + InstantiateMsg { + governance_address: governance.to_string(), + }, + ); + + let eth_prover = Addr::unchecked("eth_prover"); + let eth: ChainName = "Ethereum".to_string().try_into().unwrap(); + let msg = ExecuteMsg::RegisterProverContract { + chain_name: eth.clone(), + new_prover_addr: eth_prover.clone(), + }; + let res = execute( + deps.as_mut(), + env.clone(), + mock_info("random_address", &[]), + msg, + ); + assert_eq!( + res.unwrap_err().to_string(), + axelar_wasm_std::ContractError::from(ContractError::Unauthorized).to_string() + ); + } +} diff --git a/contracts/monitoring/src/error.rs b/contracts/monitoring/src/error.rs new file mode 100644 index 000000000..5f76464aa --- /dev/null +++ b/contracts/monitoring/src/error.rs @@ -0,0 +1,16 @@ +use axelar_wasm_std_derive::IntoContractError; +use connection_router_api::ChainName; +use cosmwasm_std::StdError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq, IntoContractError)] +pub enum ContractError { + #[error(transparent)] + Std(#[from] StdError), + + #[error("caller not unauthorized to perform this action")] + Unauthorized, + + #[error("no provers registered for chain {0}")] + NoProversRegisteredForChain(ChainName), +} diff --git a/contracts/monitoring/src/execute.rs b/contracts/monitoring/src/execute.rs new file mode 100644 index 000000000..9232f8594 --- /dev/null +++ b/contracts/monitoring/src/execute.rs @@ -0,0 +1,28 @@ +use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response}; + +use connection_router_api::ChainName; + +use crate::error::ContractError; +use crate::state::{CONFIG, PROVERS_PER_CHAIN}; + +pub fn check_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { + let config = CONFIG.load(deps.storage)?; + if config.governance != info.sender { + return Err(ContractError::Unauthorized); + } + Ok(()) +} + +pub fn register_prover( + deps: DepsMut, + chain_name: ChainName, + new_prover_addr: Addr, +) -> Result { + let existing_provers = PROVERS_PER_CHAIN.may_load(deps.storage, chain_name.clone())?; + let mut provers = existing_provers.unwrap_or_else(Vec::new); + + provers.push(new_prover_addr.clone()); + + PROVERS_PER_CHAIN.save(deps.storage, chain_name.clone(), &(provers))?; + Ok(Response::new()) +} diff --git a/contracts/monitoring/src/lib.rs b/contracts/monitoring/src/lib.rs index 03a7fc2be..b1acd54e1 100644 --- a/contracts/monitoring/src/lib.rs +++ b/contracts/monitoring/src/lib.rs @@ -1,4 +1,6 @@ pub mod contract; +pub mod error; +pub mod execute; pub mod msg; pub mod query; pub mod state; diff --git a/contracts/monitoring/src/msg.rs b/contracts/monitoring/src/msg.rs index 34fbce28b..01da95554 100644 --- a/contracts/monitoring/src/msg.rs +++ b/contracts/monitoring/src/msg.rs @@ -1,5 +1,6 @@ use connection_router_api::ChainName; use cosmwasm_schema::{cw_serde, QueryResponses}; +use cosmwasm_std::Addr; use multisig::worker_set::WorkerSet; #[cw_serde] @@ -8,7 +9,13 @@ pub struct InstantiateMsg { } #[cw_serde] -pub enum ExecuteMsg {} +pub enum ExecuteMsg { + // Can only be called by governance + RegisterProverContract { + chain_name: ChainName, + new_prover_addr: Addr, + }, +} #[cw_serde] #[derive(QueryResponses)] diff --git a/contracts/monitoring/src/query.rs b/contracts/monitoring/src/query.rs index 0f712b602..a498650f1 100644 --- a/contracts/monitoring/src/query.rs +++ b/contracts/monitoring/src/query.rs @@ -1,5 +1,7 @@ +use crate::error::ContractError; +use crate::state::PROVERS_PER_CHAIN; use connection_router_api::ChainName; -use cosmwasm_std::Deps; +use cosmwasm_std::{Addr, Deps}; use multisig::worker_set::WorkerSet; pub fn chains_active_worker_sets( @@ -8,3 +10,9 @@ pub fn chains_active_worker_sets( ) -> Vec<(ChainName, WorkerSet)> { todo!() } + +pub fn provers(deps: Deps, chain_name: ChainName) -> Result, ContractError> { + PROVERS_PER_CHAIN + .may_load(deps.storage, chain_name.clone())? + .ok_or(ContractError::NoProversRegisteredForChain(chain_name)) +} diff --git a/contracts/monitoring/src/state.rs b/contracts/monitoring/src/state.rs index 38a06b742..c8b9bd584 100644 --- a/contracts/monitoring/src/state.rs +++ b/contracts/monitoring/src/state.rs @@ -1,9 +1,15 @@ +use connection_router_api::ChainName; use cosmwasm_schema::cw_serde; use cosmwasm_std::Addr; -use cw_storage_plus::Item; +use cw_storage_plus::{Item, Map}; #[cw_serde] pub struct Config { pub governance: Addr, } + pub const CONFIG: Item = Item::new("config"); + +type ProverAddresses = Vec; +// maps chain name to prover addresses +pub const PROVERS_PER_CHAIN: Map = Map::new("provers_per_chain"); diff --git a/contracts/multisig-prover/Cargo.toml b/contracts/multisig-prover/Cargo.toml index 7646e6789..ef859c7d2 100644 --- a/contracts/multisig-prover/Cargo.toml +++ b/contracts/multisig-prover/Cargo.toml @@ -39,10 +39,8 @@ bcs = "0.1.5" connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } cw-utils = "1.0.1" -either = "1.8.1" error-stack = { workspace = true } ethabi = { version = "18.0.0", default-features = false, features = [] } gateway = { workspace = true } @@ -50,10 +48,9 @@ gateway-api = { workspace = true } hex = { version = "0.4.3", default-features = false, features = [] } itertools = "0.11.0" k256 = { version = "0.13.1", features = ["ecdsa"] } +monitoring = { workspace = true } multisig = { workspace = true, features = ["library"] } report = { workspace = true } -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" service-registry = { workspace = true } sha3 = { workspace = true } diff --git a/contracts/multisig-prover/src/contract.rs b/contracts/multisig-prover/src/contract.rs index f142b37ab..9ca278a94 100644 --- a/contracts/multisig-prover/src/contract.rs +++ b/contracts/multisig-prover/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, + to_binary, Binary, Deps, DepsMut, Env, MessageInfo, Reply, Response, StdResult, }; use crate::{ @@ -35,6 +35,7 @@ fn make_config( let governance = deps.api.addr_validate(&msg.governance_address)?; let gateway = deps.api.addr_validate(&msg.gateway_address)?; let multisig = deps.api.addr_validate(&msg.multisig_address)?; + let monitoring = deps.api.addr_validate(&msg.monitoring_address)?; let service_registry = deps.api.addr_validate(&msg.service_registry_address)?; let voting_verifier = deps.api.addr_validate(&msg.voting_verifier_address)?; @@ -43,6 +44,7 @@ fn make_config( governance, gateway, multisig, + monitoring, service_registry, voting_verifier, destination_chain_id: msg.destination_chain_id, @@ -68,10 +70,17 @@ pub fn execute( match msg { ExecuteMsg::ConstructProof { message_ids } => execute::construct_proof(deps, message_ids), ExecuteMsg::UpdateWorkerSet {} => { - execute::require_admin(&deps, info)?; + execute::require_admin(&deps, info.clone()) + .or_else(|_| execute::require_governance(&deps, info))?; execute::update_worker_set(deps, env) } ExecuteMsg::ConfirmWorkerSet {} => execute::confirm_worker_set(deps, info.sender), + ExecuteMsg::UpdateSigningThreshold { + new_signing_threshold, + } => { + execute::require_governance(&deps, info)?; + execute::update_signing_threshold(deps, new_signing_threshold) + } } .map_err(axelar_wasm_std::ContractError::from) } @@ -94,12 +103,12 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { QueryMsg::GetProof { multisig_session_id, - } => to_json_binary(&query::get_proof(deps, multisig_session_id)?), - QueryMsg::GetWorkerSet {} => to_json_binary(&query::get_worker_set(deps)?), + } => to_binary(&query::get_proof(deps, multisig_session_id)?), + QueryMsg::GetWorkerSet {} => to_binary(&query::get_worker_set(deps)?), } } -#[cfg_attr(not(feature = "libary"), entry_point)] +#[cfg_attr(not(feature = "library"), entry_point)] pub fn migrate( deps: DepsMut, _env: Env, @@ -121,11 +130,11 @@ mod tests { use anyhow::Error; use cosmwasm_std::{ testing::{mock_dependencies, mock_env, mock_info}, - Addr, Fraction, Uint256, Uint64, + Addr, Fraction, Uint128, Uint256, Uint64, }; use cw_multi_test::{AppResponse, Executor}; - use axelar_wasm_std::Threshold; + use axelar_wasm_std::{MajorityThreshold, Threshold}; use connection_router_api::CrossChainId; use multisig::{msg::Signer, worker_set::WorkerSet}; @@ -165,6 +174,19 @@ mod tests { .execute_contract(sender, test_case.prover_address.clone(), &msg, &[]) } + fn execute_update_signing_threshold( + test_case: &mut TestCaseConfig, + sender: Addr, + new_signing_threshold: MajorityThreshold, + ) -> Result { + let msg = ExecuteMsg::UpdateSigningThreshold { + new_signing_threshold, + }; + test_case + .app + .execute_contract(sender, test_case.prover_address.clone(), &msg, &[]) + } + fn execute_construct_proof( test_case: &mut TestCaseConfig, message_ids: Option>, @@ -218,6 +240,7 @@ mod tests { let governance = "governance"; let gateway_address = "gateway_address"; let multisig_address = "multisig_address"; + let monitoring_address = "monitoring_address"; let service_registry_address = "service_registry_address"; let voting_verifier_address = "voting_verifier"; let destination_chain_id = Uint256::one(); @@ -239,6 +262,7 @@ mod tests { governance_address: governance.to_string(), gateway_address: gateway_address.to_string(), multisig_address: multisig_address.to_string(), + monitoring_address: monitoring_address.to_string(), voting_verifier_address: voting_verifier_address.to_string(), service_registry_address: service_registry_address.to_string(), destination_chain_id, @@ -315,7 +339,7 @@ mod tests { } #[test] - fn test_update_worker_set_from_non_admin_should_fail() { + fn test_update_worker_set_from_non_admin_or_governance_should_fail() { let mut test_case = setup_test_case(); let res = test_case.app.execute_contract( Addr::unchecked("some random address"), @@ -333,6 +357,30 @@ mod tests { ); } + #[test] + fn test_update_worker_set_from_governance_should_succeed() { + let mut test_case = setup_test_case(); + let res = test_case.app.execute_contract( + test_case.governance.clone(), + test_case.prover_address.clone(), + &ExecuteMsg::UpdateWorkerSet {}, + &[], + ); + assert!(res.is_ok()); + } + + #[test] + fn test_update_worker_set_from_admin_should_succeed() { + let mut test_case = setup_test_case(); + let res = test_case.app.execute_contract( + test_case.governance.clone(), + test_case.prover_address.clone(), + &ExecuteMsg::UpdateWorkerSet {}, + &[], + ); + assert!(res.is_ok()); + } + #[test] fn test_update_worker_set_remove_one() { let mut test_case = setup_test_case(); @@ -641,54 +689,126 @@ mod tests { } #[test] - fn test_construct_proof_updates_worker_set() { + fn test_construct_proof_no_worker_set() { let mut test_case = setup_test_case(); - let res = execute_update_worker_set(&mut test_case); - - assert!(res.is_ok()); + let res = execute_construct_proof(&mut test_case, None); + assert!(res.is_err()); + assert_eq!( + res.unwrap_err() + .downcast::() + .unwrap() + .to_string(), + axelar_wasm_std::ContractError::from(ContractError::NoWorkerSet).to_string() + ); + } - let mut new_worker_set = test_data::operators(); - new_worker_set.pop(); - mocks::service_registry::set_active_workers( - &mut test_case.app, - test_case.service_registry_address.clone(), - new_worker_set, + #[test] + fn non_governance_should_not_be_able_to_call_update_signing_threshold() { + let mut test_case = setup_test_case(); + let res = execute_update_signing_threshold( + &mut test_case, + Addr::unchecked("random"), + Threshold::try_from((6, 10)).unwrap().try_into().unwrap(), ); + assert!(res.is_err()); + } - // worker set will update in construct proof. - let res = execute_construct_proof(&mut test_case, None).unwrap(); + #[test] + fn governance_should_be_able_to_call_update_signing_threshold() { + let mut test_case = setup_test_case(); + let governance = test_case.governance.clone(); + let res = execute_update_signing_threshold( + &mut test_case, + governance, + Threshold::try_from((6, 10)).unwrap().try_into().unwrap(), + ); + assert!(res.is_ok()); + } - let event = res - .events + /// Calls update_signing_threshold, increasing the threshold by one. + /// Returns (initial threshold, new threshold) + fn update_signing_threshold_increase_by_one( + test_case: &mut TestCaseConfig, + ) -> (Uint256, Uint256) { + let worker_set = query_get_worker_set(test_case).unwrap(); + let initial_threshold = worker_set.threshold; + let total_weight = worker_set + .signers .iter() - .find(|event| event.ty == "wasm-proof_under_construction"); + .fold(Uint256::zero(), |acc, signer| { + acc.checked_add(signer.1.weight).unwrap() + }); + let new_threshold = initial_threshold.checked_add(Uint256::one()).unwrap(); - assert!(event.is_some()); + let governance = test_case.governance.clone(); + execute_update_signing_threshold( + test_case, + governance.clone(), + Threshold::try_from(( + Uint64::try_from(Uint128::try_from(new_threshold).unwrap()).unwrap(), + Uint64::try_from(Uint128::try_from(total_weight).unwrap()).unwrap(), + )) + .unwrap() + .try_into() + .unwrap(), + ) + .unwrap(); + (initial_threshold, new_threshold) + } - // check that worker set is updated. - let worker_set = query_get_worker_set(&mut test_case); - assert!(worker_set.is_ok()); + #[test] + fn update_signing_threshold_should_not_change_current_threshold() { + let mut test_case = setup_test_case(); + execute_update_worker_set(&mut test_case).unwrap(); - let worker_set = worker_set.unwrap(); + let (initial_threshold, new_threshold) = + update_signing_threshold_increase_by_one(&mut test_case); + assert_ne!(initial_threshold, new_threshold); - let expected_worker_set = - test_operators_to_worker_set(test_data::operators(), test_case.app.block_info().height); + let worker_set = query_get_worker_set(&mut test_case).unwrap(); + assert_eq!(worker_set.threshold, initial_threshold); + } - assert_eq!(worker_set, expected_worker_set); + #[test] + fn update_signing_threshold_should_change_future_threshold() { + let mut test_case = setup_test_case(); + execute_update_worker_set(&mut test_case).unwrap(); + + let (initial_threshold, new_threshold) = + update_signing_threshold_increase_by_one(&mut test_case); + assert_ne!(initial_threshold, new_threshold); + + execute_update_worker_set(&mut test_case).unwrap(); + + let governance = test_case.governance.clone(); + confirm_worker_set(&mut test_case, governance).unwrap(); + + let worker_set = query_get_worker_set(&mut test_case).unwrap(); + assert_eq!(worker_set.threshold, new_threshold); } #[test] - fn test_construct_proof_no_worker_set() { + fn should_confirm_new_threshold_via_voting_verifier() { let mut test_case = setup_test_case(); - let res = execute_construct_proof(&mut test_case, None); - assert!(res.is_err()); - assert_eq!( - res.unwrap_err() - .downcast::() - .unwrap() - .to_string(), - axelar_wasm_std::ContractError::from(ContractError::NoWorkerSet).to_string() + execute_update_worker_set(&mut test_case).unwrap(); + + let (initial_threshold, new_threshold) = + update_signing_threshold_increase_by_one(&mut test_case); + assert_ne!(initial_threshold, new_threshold); + + execute_update_worker_set(&mut test_case).unwrap(); + + mocks::voting_verifier::confirm_worker_set( + &mut test_case.app, + test_case.voting_verifier_address.clone(), + test_data::operators(), + new_threshold, ); + let res = confirm_worker_set(&mut test_case, Addr::unchecked("relayer")); + assert!(res.is_ok()); + + let worker_set = query_get_worker_set(&mut test_case).unwrap(); + assert_eq!(worker_set.threshold, new_threshold); } #[test] diff --git a/contracts/multisig-prover/src/execute.rs b/contracts/multisig-prover/src/execute.rs index f017afb23..1d80d25ff 100644 --- a/contracts/multisig-prover/src/execute.rs +++ b/contracts/multisig-prover/src/execute.rs @@ -1,14 +1,14 @@ use std::collections::BTreeMap; use cosmwasm_std::{ - to_json_binary, wasm_execute, Addr, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, + to_binary, wasm_execute, Addr, DepsMut, Env, MessageInfo, QuerierWrapper, QueryRequest, Response, Storage, SubMsg, WasmQuery, }; use itertools::Itertools; use multisig::{key::PublicKey, msg::Signer, worker_set::WorkerSet}; -use axelar_wasm_std::{snapshot, VerificationStatus}; +use axelar_wasm_std::{snapshot, MajorityThreshold, VerificationStatus}; use connection_router_api::{ChainName, CrossChainId, Message}; use service_registry::state::WeightedWorker; @@ -27,6 +27,13 @@ pub fn require_admin(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractEr } } +pub fn require_governance(deps: &DepsMut, info: MessageInfo) -> Result<(), ContractError> { + match CONFIG.load(deps.storage)?.governance { + governance if governance == info.sender => Ok(()), + _ => Err(ContractError::Unauthorized), + } +} + pub fn construct_proof( deps: DepsMut, message_ids: Vec, @@ -89,7 +96,7 @@ fn get_messages( let query = gateway_api::msg::QueryMsg::GetOutgoingMessages { message_ids }; let messages: Vec = querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: gateway.into(), - msg: to_json_binary(&query)?, + msg: to_binary(&query)?, }))?; assert!( @@ -116,7 +123,7 @@ fn get_workers_info(deps: &DepsMut, config: &Config) -> Result = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.service_registry.to_string(), - msg: to_json_binary(&active_workers_query)?, + msg: to_binary(&active_workers_query)?, }))?; let participants = workers @@ -136,7 +143,7 @@ fn get_workers_info(deps: &DepsMut, config: &Config) -> Result Result, ContractError> { + // if there's already a pending worker set update, just return it + if let Some(pending_worker_set) = NEXT_WORKER_SET.may_load(deps.storage)? { + return Ok(Some(pending_worker_set)); + } let cur_worker_set = CURRENT_WORKER_SET.may_load(deps.storage)?; let new_worker_set = make_worker_set(deps, env, config)?; @@ -250,7 +261,7 @@ fn ensure_worker_set_verification( let status: VerificationStatus = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.voting_verifier.to_string(), - msg: to_json_binary(&query)?, + msg: to_binary(&query)?, }))?; if status != VerificationStatus::SucceededOnChain { @@ -284,7 +295,8 @@ pub fn should_update_worker_set( cur_workers: &WorkerSet, max_diff: usize, ) -> bool { - signers_symetric_difference_count(&new_workers.signers, &cur_workers.signers) > max_diff + new_workers.threshold != cur_workers.threshold + || signers_symetric_difference_count(&new_workers.signers, &cur_workers.signers) > max_diff } fn signers_symetric_difference_count( @@ -299,25 +311,46 @@ fn signers_difference_count(s1: &BTreeMap, s2: &BTreeMap bool { if let Ok(Some(next_worker_set)) = NEXT_WORKER_SET.may_load(storage) { - return next_worker_set.signers != new_worker_set.signers - || next_worker_set.threshold != new_worker_set.threshold; + return next_worker_set != *new_worker_set; } false } +pub fn update_signing_threshold( + deps: DepsMut, + new_signing_threshold: MajorityThreshold, +) -> Result { + CONFIG.update( + deps.storage, + |mut config| -> Result { + config.signing_threshold = new_signing_threshold; + Ok(config) + }, + )?; + Ok(Response::new()) +} + #[cfg(test)] mod tests { - use cosmwasm_std::testing::mock_dependencies; + use axelar_wasm_std::Threshold; + use connection_router_api::ChainName; + use cosmwasm_std::{ + testing::{mock_dependencies, mock_env}, + Addr, Uint256, + }; - use crate::{execute::should_update_worker_set, state::NEXT_WORKER_SET, test::test_data}; + use crate::{ + execute::should_update_worker_set, + state::{Config, NEXT_WORKER_SET}, + test::test_data, + }; use std::collections::BTreeMap; - use super::different_set_in_progress; + use super::{different_set_in_progress, get_next_worker_set}; #[test] fn should_update_worker_set_no_change() { @@ -373,7 +406,7 @@ mod tests { } #[test] - fn test_same_set_pending_confirmation() { + fn test_same_set_different_nonce() { let mut deps = mock_dependencies(); let mut new_worker_set = test_data::new_worker_set(); @@ -383,7 +416,7 @@ mod tests { new_worker_set.created_at += 1; - assert!(!different_set_in_progress( + assert!(different_set_in_progress( deps.as_ref().storage, &new_worker_set )); @@ -405,4 +438,35 @@ mod tests { &new_worker_set )); } + + #[test] + fn get_next_worker_set_should_return_pending() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let new_worker_set = test_data::new_worker_set(); + NEXT_WORKER_SET + .save(deps.as_mut().storage, &new_worker_set) + .unwrap(); + let ret_worker_set = get_next_worker_set(&deps.as_mut(), &env, &mock_config()); + assert_eq!(ret_worker_set.unwrap().unwrap(), new_worker_set); + } + + fn mock_config() -> Config { + Config { + admin: Addr::unchecked("doesn't matter"), + governance: Addr::unchecked("doesn't matter"), + gateway: Addr::unchecked("doesn't matter"), + multisig: Addr::unchecked("doesn't matter"), + monitoring: Addr::unchecked("doesn't matter"), + service_registry: Addr::unchecked("doesn't matter"), + voting_verifier: Addr::unchecked("doesn't matter"), + destination_chain_id: Uint256::one(), + signing_threshold: Threshold::try_from((2, 3)).unwrap().try_into().unwrap(), + service_name: "validators".to_string(), + chain_name: ChainName::try_from("ethereum".to_owned()).unwrap(), + worker_set_diff_threshold: 0, + encoder: crate::encoding::Encoder::Abi, + key_type: multisig::key::KeyType::Ecdsa, + } + } } diff --git a/contracts/multisig-prover/src/msg.rs b/contracts/multisig-prover/src/msg.rs index 18c83be66..b0be86af0 100644 --- a/contracts/multisig-prover/src/msg.rs +++ b/contracts/multisig-prover/src/msg.rs @@ -8,18 +8,46 @@ use crate::encoding::{Data, Encoder}; #[cw_serde] pub struct InstantiateMsg { + /// Address that can execute all messages that either have unrestricted or admin permission level, such as UpdateWorkerSet. + /// Should be set to a trusted address that can react to unexpected interruptions to the contract's operation. pub admin_address: String, + /// Address that can call all messages of unrestricted, admin and governance permission level, such as UpdateSigningThreshold. + /// This address can execute messages that bypasses verification checks to rescue the contract if it got into an otherwise unrecoverable state due to external forces. + /// On mainnet, it should match the address of the Cosmos governance module. pub governance_address: String, + /// Address of the gateway on axelar associated with the destination chain. For example, if this prover is creating proofs to + /// be relayed to Ethereum, this is the address of the gateway on Axelar for Ethereum. pub gateway_address: String, + /// Address of the multisig contract on axelar. pub multisig_address: String, + /// Address of the monitoring contract on axelar. + pub monitoring_address: String, + /// Address of the service registry contract on axelar. pub service_registry_address: String, + /// Address of the voting verifier contract on axelar associated with the destination chain. For example, if this prover is creating + /// proofs to be relayed to Ethereum, this is the address of the voting verifier for Ethereum. pub voting_verifier_address: String, + /// Chain id of the chain for which this prover contract creates proofs. For example, if the destination chain is Ethereum, the chain id is 1. pub destination_chain_id: Uint256, + /// Threshold of weighted signatures required for signing to be considered complete pub signing_threshold: MajorityThreshold, + /// Name of service in the service registry for which verifiers are registered. pub service_name: String, + /// Name of chain for which this prover contract creates proofs. pub chain_name: String, + /// Maximum tolerable difference between currently active workerset and registered workerset. + /// The workerset registered in the service registry must be different by more than this number + /// of workers before calling UpdateWorkerSet. For example, if this is set to 1, UpdateWorkerSet + /// will fail unless the registered workerset and active workerset differ by more than 1. pub worker_set_diff_threshold: u32, + /// Type of encoding to use for signed batches. Blockchains can encode their execution payloads in various ways (ABI, BCS, etc). + /// This defines the specific encoding type to use for this prover, which should correspond to the encoding type used by the gateway + /// deployed on the destination chain. pub encoder: Encoder, + /// Public key type verifiers use for signing batches. Different blockchains support different cryptographic signature algorithms (ECDSA, Ed25519, etc). + /// This defines the specific signature algorithm to use for this prover, which should correspond to the signature algorithm used by the gateway + /// deployed on the destination chain. The multisig contract supports multiple public keys per verifier (each a different type of key), and this + /// parameter controls which registered public key to use for signing for each verifier registered to the destination chain. pub key_type: KeyType, } @@ -27,9 +55,17 @@ pub struct InstantiateMsg { pub enum ExecuteMsg { // Start building a proof that includes specified messages // Queries the gateway for actual message contents - ConstructProof { message_ids: Vec }, + ConstructProof { + message_ids: Vec, + }, UpdateWorkerSet, ConfirmWorkerSet, + // Updates the signing threshold. The threshold currently in use does not change. + // The worker set must be updated and confirmed for the change to take effect. + // Callable only by governance. + UpdateSigningThreshold { + new_signing_threshold: MajorityThreshold, + }, } #[cw_serde] diff --git a/contracts/multisig-prover/src/query.rs b/contracts/multisig-prover/src/query.rs index adfb1e2fa..0f5da3f90 100644 --- a/contracts/multisig-prover/src/query.rs +++ b/contracts/multisig-prover/src/query.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_json_binary, Deps, QueryRequest, StdError, StdResult, Uint256, Uint64, WasmQuery, + to_binary, Deps, QueryRequest, StdError, StdResult, Uint256, Uint64, WasmQuery, }; use itertools::Itertools; @@ -29,7 +29,7 @@ pub fn get_proof(deps: Deps, multisig_session_id: Uint64) -> StdResult Result StdResult { match msg { QueryMsg::GetOutgoingMessages { message_ids: _ } => { let res = test_data::messages(); - to_json_binary(&res) + to_binary(&res) } } } diff --git a/contracts/multisig-prover/src/test/mocks/multisig.rs b/contracts/multisig-prover/src/test/mocks/multisig.rs index a9e337781..3d1db1eee 100644 --- a/contracts/multisig-prover/src/test/mocks/multisig.rs +++ b/contracts/multisig-prover/src/test/mocks/multisig.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdError, + to_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdError, StdResult, Uint64, }; use cw_multi_test::{App, Executor}; @@ -37,7 +37,7 @@ pub fn execute( msg: _, sig_verifier: _, chain_name: _, - } => Ok(Response::new().set_data(to_json_binary(&Uint64::one())?)), + } => Ok(Response::new().set_data(to_binary(&Uint64::one())?)), ExecuteMsg::SubmitSignature { session_id: _, signature: _, @@ -80,12 +80,12 @@ pub fn register_pub_keys(app: &mut App, multisig_address: Addr, workers: Vec StdResult { match msg { - QueryMsg::GetMultisig { session_id: _ } => to_json_binary(&query::query_success()), + QueryMsg::GetMultisig { session_id: _ } => to_binary(&query::query_success()), QueryMsg::GetWorkerSet { worker_set_id: _ } => unimplemented!(), QueryMsg::GetPublicKey { worker_address, key_type, - } => to_json_binary(&get_public_key_query_success( + } => to_binary(&get_public_key_query_success( deps, worker_address, key_type, diff --git a/contracts/multisig-prover/src/test/mocks/service_registry.rs b/contracts/multisig-prover/src/test/mocks/service_registry.rs index 3134cbc6d..7a23eb8c1 100644 --- a/contracts/multisig-prover/src/test/mocks/service_registry.rs +++ b/contracts/multisig-prover/src/test/mocks/service_registry.rs @@ -1,6 +1,6 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, + to_binary, Addr, Binary, Deps, DepsMut, Env, MessageInfo, Response, StdError, StdResult, }; use cw_multi_test::{App, Executor}; use cw_storage_plus::Map; @@ -95,7 +95,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { }) .collect::>(); - to_json_binary(&workers) + to_binary(&workers) } QueryMsg::GetService { .. } => todo!(), QueryMsg::GetWorker { .. } => todo!(), diff --git a/contracts/multisig-prover/src/test/mocks/voting_verifier.rs b/contracts/multisig-prover/src/test/mocks/voting_verifier.rs index fa9d254ff..85eeced73 100644 --- a/contracts/multisig-prover/src/test/mocks/voting_verifier.rs +++ b/contracts/multisig-prover/src/test/mocks/voting_verifier.rs @@ -1,7 +1,7 @@ use axelar_wasm_std::{hash::Hash, operators::Operators, VerificationStatus}; use cosmwasm_schema::cw_serde; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdError, + to_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdError, StdResult, Uint256, }; use cw_multi_test::{App, Executor}; @@ -65,7 +65,7 @@ pub fn confirm_worker_set( pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetWorkerSetStatus { new_operators } => to_json_binary( + QueryMsg::GetWorkerSetStatus { new_operators } => to_binary( &CONFIRMED_WORKER_SETS .may_load(deps.storage, &new_operators.hash())? .map_or(VerificationStatus::None, |_| { diff --git a/contracts/multisig-prover/src/test/multicontract.rs b/contracts/multisig-prover/src/test/multicontract.rs index b27d804a6..f2df1c3f0 100644 --- a/contracts/multisig-prover/src/test/multicontract.rs +++ b/contracts/multisig-prover/src/test/multicontract.rs @@ -163,6 +163,7 @@ fn instantiate_prover( governance_address: GOVERNANCE.to_string(), gateway_address, multisig_address, + monitoring_address: Addr::unchecked("monitoring").to_string(), service_registry_address, voting_verifier_address, destination_chain_id: test_data::destination_chain_id(), diff --git a/contracts/multisig-prover/src/types.rs b/contracts/multisig-prover/src/types.rs index 638004c9c..2e94db66f 100644 --- a/contracts/multisig-prover/src/types.rs +++ b/contracts/multisig-prover/src/types.rs @@ -3,7 +3,7 @@ use std::fmt::Display; use axelar_wasm_std::{Participant, Snapshot}; use connection_router_api::CrossChainId; use cosmwasm_schema::cw_serde; -use cosmwasm_std::{from_json, HexBinary, StdResult, Uint256}; +use cosmwasm_std::{from_binary, HexBinary, StdResult, Uint256}; use cw_storage_plus::{Key, KeyDeserialize, PrimaryKey}; use multisig::{ key::{PublicKey, Signature}, @@ -65,7 +65,7 @@ impl KeyDeserialize for BatchId { type Output = BatchId; fn from_vec(value: Vec) -> StdResult { - Ok(from_json(value).expect("violated invariant: BatchID is not deserializable")) + Ok(from_binary(&value.into()).expect("violated invariant: BatchID is not deserializable")) } } diff --git a/contracts/multisig/Cargo.toml b/contracts/multisig/Cargo.toml index 0dda4b076..c5da65905 100644 --- a/contracts/multisig/Cargo.toml +++ b/contracts/multisig/Cargo.toml @@ -44,7 +44,6 @@ connection-router-api = { workspace = true } cosmwasm-crypto = "1.2.7" cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } ed25519-dalek = { version = "2.1.1", default-features = false } enum-display-derive = "0.1.1" @@ -53,7 +52,6 @@ getrandom = { version = "0.2", default-features = false, features = ["custom"] } k256 = { version = "0.13.1", features = ["ecdsa"] } report = { workspace = true } rewards = { workspace = true, features = ["library"] } -schemars = "0.8.10" serde = { version = "1.0.145", default-features = false, features = ["derive"] } serde_json = "1.0.89" sha3 = { workspace = true } @@ -61,6 +59,7 @@ signature-verifier-api = { workspace = true } thiserror = { workspace = true } [dev-dependencies] +curve25519-dalek = "4.1.1" cw-multi-test = "0.15.1" [lints] diff --git a/contracts/multisig/src/contract.rs b/contracts/multisig/src/contract.rs index 82980ace7..55e3cbe3b 100644 --- a/contracts/multisig/src/contract.rs +++ b/contracts/multisig/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, + to_binary, Addr, Binary, Deps, DepsMut, Env, HexBinary, MessageInfo, Response, StdResult, Uint64, }; @@ -92,16 +92,14 @@ pub fn execute( #[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::GetMultisig { session_id } => { - to_json_binary(&query::get_multisig(deps, session_id)?) - } + QueryMsg::GetMultisig { session_id } => to_binary(&query::get_multisig(deps, session_id)?), QueryMsg::GetWorkerSet { worker_set_id } => { - to_json_binary(&query::get_worker_set(deps, worker_set_id)?) + to_binary(&query::get_worker_set(deps, worker_set_id)?) } QueryMsg::GetPublicKey { worker_address, key_type, - } => to_json_binary(&query::get_public_key( + } => to_binary(&query::get_public_key( deps, deps.api.addr_validate(&worker_address)?, key_type, @@ -114,7 +112,7 @@ mod tests { use std::vec; use cosmwasm_std::{ - from_json, + from_binary, testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, Addr, Empty, OwnedDeps, WasmMsg, }; @@ -351,11 +349,11 @@ mod tests { let res = query_worker_set(&worker_set_1.id(), deps.as_ref()); assert!(res.is_ok()); - assert_eq!(worker_set_1, from_json(res.unwrap()).unwrap()); + assert_eq!(worker_set_1, from_binary(&res.unwrap()).unwrap()); let res = query_worker_set(&worker_set_2.id(), deps.as_ref()); assert!(res.is_ok()); - assert_eq!(worker_set_2, from_json(res.unwrap()).unwrap()); + assert_eq!(worker_set_2, from_binary(&res.unwrap()).unwrap()); for (key_type, _) in [ (KeyType::Ecdsa, worker_set_1_id), @@ -405,7 +403,7 @@ mod tests { assert_eq!(session.state, MultisigState::Pending); let res = res.unwrap(); - assert_eq!(res.data, Some(to_json_binary(&session.id).unwrap())); + assert_eq!(res.data, Some(to_binary(&session.id).unwrap())); assert_eq!(res.events.len(), 1); let event = res.events.first().unwrap(); @@ -466,7 +464,7 @@ mod tests { let expected_rewards_msg = WasmMsg::Execute { contract_addr: REWARDS_CONTRACT.to_string(), - msg: to_json_binary(&rewards::msg::ExecuteMsg::RecordParticipation { + msg: to_binary(&rewards::msg::ExecuteMsg::RecordParticipation { chain_name: chain_name.clone(), event_id: session_id.to_string().try_into().unwrap(), worker_address: signer.address.clone().into(), @@ -594,7 +592,7 @@ mod tests { let expected_rewards_msg = WasmMsg::Execute { contract_addr: REWARDS_CONTRACT.to_string(), - msg: to_json_binary(&rewards::msg::ExecuteMsg::RecordParticipation { + msg: to_binary(&rewards::msg::ExecuteMsg::RecordParticipation { chain_name: chain_name.clone(), event_id: session_id.to_string().try_into().unwrap(), worker_address: signer.address.clone().into(), @@ -703,7 +701,7 @@ mod tests { let res = query(deps.as_ref(), mock_env(), msg); assert!(res.is_ok()); - let query_res: Multisig = from_json(&res.unwrap()).unwrap(); + let query_res: Multisig = from_binary(&res.unwrap()).unwrap(); let session = SIGNING_SESSIONS .load(deps.as_ref().storage, session_id.into()) .unwrap(); @@ -801,7 +799,7 @@ mod tests { for (addr, _, _) in &expected_pub_keys { let res = query_registered_public_key(deps.as_ref(), addr.clone(), key_type); assert!(res.is_ok()); - ret_pub_keys.push(from_json(&res.unwrap()).unwrap()); + ret_pub_keys.push(from_binary(&res.unwrap()).unwrap()); } assert_eq!( expected_pub_keys @@ -856,7 +854,7 @@ mod tests { assert!(res.is_ok()); assert_eq!( PublicKey::try_from((KeyType::Ecdsa, new_pub_key.clone())).unwrap(), - from_json::(&res.unwrap()).unwrap() + from_binary::(&res.unwrap()).unwrap() ); // Register an ED25519 key, it should not affect our ECDSA key @@ -877,14 +875,14 @@ mod tests { assert!(res.is_ok()); assert_eq!( PublicKey::try_from((KeyType::Ed25519, ed25519_pub_key)).unwrap(), - from_json::(&res.unwrap()).unwrap() + from_binary::(&res.unwrap()).unwrap() ); let res = query_registered_public_key(deps.as_ref(), pub_keys[0].0.clone(), KeyType::Ecdsa); assert!(res.is_ok()); assert_eq!( PublicKey::try_from((KeyType::Ecdsa, new_pub_key)).unwrap(), - from_json::(&res.unwrap()).unwrap() + from_binary::(&res.unwrap()).unwrap() ); } diff --git a/contracts/multisig/src/contract/execute.rs b/contracts/multisig/src/contract/execute.rs index c36cbe612..ec1d4bb93 100644 --- a/contracts/multisig/src/contract/execute.rs +++ b/contracts/multisig/src/contract/execute.rs @@ -69,7 +69,7 @@ pub fn start_signing_session( }; Ok(Response::new() - .set_data(to_json_binary(&session_id)?) + .set_data(to_binary(&session_id)?) .add_event(event.into())) } @@ -211,7 +211,7 @@ fn signing_response( ) -> Result { let rewards_msg = WasmMsg::Execute { contract_addr: rewards_contract, - msg: to_json_binary(&rewards::msg::ExecuteMsg::RecordParticipation { + msg: to_binary(&rewards::msg::ExecuteMsg::RecordParticipation { chain_name: session.chain_name, event_id: session .id diff --git a/contracts/multisig/src/key.rs b/contracts/multisig/src/key.rs index 9804f13f2..f2793e0b9 100644 --- a/contracts/multisig/src/key.rs +++ b/contracts/multisig/src/key.rs @@ -235,7 +235,6 @@ fn validate_and_normalize_public_key( key_type: KeyType, pub_key: HexBinary, ) -> Result { - // TODO: ensure proper validation, since external crates may only check format. match key_type { KeyType::Ecdsa => Ok(k256::PublicKey::from_sec1_bytes( check_ecdsa_format(pub_key)?.as_slice(), @@ -245,6 +244,8 @@ fn validate_and_normalize_public_key( .as_ref() .into()), // TODO: verify encoding scheme is standard + // Function `from_bytes()` will internally decompress into an EdwardsPoint which can only represent a valid point on the curve + // See https://docs.rs/curve25519-dalek/latest/curve25519_dalek/edwards/index.html#validity-checking KeyType::Ed25519 => Ok(ed25519_dalek::VerifyingKey::from_bytes( pub_key .as_slice() @@ -320,8 +321,14 @@ impl From for HexBinary { #[cfg(test)] mod ecdsa_tests { use cosmwasm_std::HexBinary; + use k256::{AffinePoint, EncodedPoint}; - use crate::{key::Signature, test::common::ecdsa_test_data, types::MsgToSign, ContractError}; + use crate::{ + key::{validate_and_normalize_public_key, Signature}, + test::common::ecdsa_test_data, + types::MsgToSign, + ContractError, + }; use super::{KeyType, PublicKey}; @@ -368,6 +375,26 @@ mod ecdsa_tests { ); } + #[test] + fn validate_ecdsa_public_key_not_on_curve() { + // the compressed format is not validated and should produce an invalid point when decompressed + let invalid_compressed_point = EncodedPoint::from_bytes([ + 3, 132, 180, 161, 194, 115, 211, 43, 90, 122, 205, 26, 76, 14, 117, 209, 243, 206, 192, + 34, 107, 93, 142, 13, 50, 95, 115, 188, 140, 82, 194, 140, 235, + ]) + .unwrap(); + + // Assert that the point is invalid according to the crate we are using for ed25519. Both assert statements must match, + // otherwise `validate_and_normalize_public_key` is not doing the same internally as the crate + assert!(AffinePoint::try_from(&invalid_compressed_point).is_err()); + + let result = validate_and_normalize_public_key( + KeyType::Ecdsa, + HexBinary::from(invalid_compressed_point.as_bytes()), + ); + assert_eq!(result.unwrap_err(), ContractError::InvalidPublicKey); + } + #[test] fn test_try_from_hexbinary_to_signature() { let hex = ecdsa_test_data::signature(); @@ -462,8 +489,14 @@ mod ecdsa_tests { #[cfg(test)] mod ed25519_tests { use cosmwasm_std::HexBinary; + use curve25519_dalek::edwards::CompressedEdwardsY; - use crate::{key::Signature, test::common::ed25519_test_data, types::MsgToSign, ContractError}; + use crate::{ + key::{validate_and_normalize_public_key, Signature}, + test::common::ed25519_test_data, + types::MsgToSign, + ContractError, + }; use super::{KeyType, PublicKey}; @@ -499,7 +532,7 @@ mod ed25519_tests { } #[test] - fn test_try_from_hexbinary_to_eccdsa_public_key_fails() { + fn test_try_from_hexbinary_to_ed25519_public_key_fails() { let hex = HexBinary::from_hex("049b").unwrap(); assert_eq!( PublicKey::try_from((KeyType::Ed25519, hex.clone())).unwrap_err(), @@ -507,6 +540,23 @@ mod ed25519_tests { ); } + #[test] + fn validate_ed25519_public_key_not_in_curve() { + // the compressed format is not validated and should produce an invalid point when decompressed + let invalid_compressed_point = CompressedEdwardsY([ + 42, 20, 146, 53, 38, 178, 23, 135, 135, 22, 77, 119, 129, 45, 141, 139, 212, 122, 180, + 97, 171, 0, 127, 226, 248, 13, 108, 227, 223, 188, 26, 121, + ]); + + assert!(invalid_compressed_point.decompress().is_none()); + + let result = validate_and_normalize_public_key( + KeyType::Ed25519, + HexBinary::from(invalid_compressed_point.as_bytes()), + ); + assert_eq!(result.unwrap_err(), ContractError::InvalidPublicKey); + } + #[test] fn test_try_from_hexbinary_to_signature() { let hex = ed25519_test_data::signature(); diff --git a/contracts/multisig/src/signing.rs b/contracts/multisig/src/signing.rs index 67c6126e3..888d67c7d 100644 --- a/contracts/multisig/src/signing.rs +++ b/contracts/multisig/src/signing.rs @@ -135,7 +135,7 @@ fn signers_weight(signatures: &HashMap, worker_set: &WorkerSe mod tests { use cosmwasm_std::{ testing::{MockQuerier, MockStorage}, - to_json_binary, Addr, HexBinary, QuerierWrapper, + to_binary, Addr, HexBinary, QuerierWrapper, }; use crate::{ @@ -279,7 +279,7 @@ mod tests { for verification in [true, false] { let mut querier = MockQuerier::default(); - querier.update_wasm(move |_| Ok(to_json_binary(&verification).into()).into()); + querier.update_wasm(move |_| Ok(to_binary(&verification).into()).into()); let sig_verifier = Some(SignatureVerifier { address: Addr::unchecked("verifier".to_string()), querier: QuerierWrapper::new(&querier), diff --git a/contracts/nexus-gateway/src/contract/execute.rs b/contracts/nexus-gateway/src/contract/execute.rs index 2fa86565c..04d306ca6 100644 --- a/contracts/nexus-gateway/src/contract/execute.rs +++ b/contracts/nexus-gateway/src/contract/execute.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_json_binary, Addr, Response, WasmMsg}; +use cosmwasm_std::{to_binary, Addr, Response, WasmMsg}; use error_stack::report; use crate::error::ContractError; @@ -24,15 +24,15 @@ where let msgs: Vec<_> = msgs .into_iter() - .map(connection_router_api::Message::from) - .collect(); + .map(connection_router_api::Message::try_from) + .collect::>>()?; if msgs.is_empty() { return Ok(Response::default()); } Ok(Response::new().add_message(WasmMsg::Execute { contract_addr: self.config.router.to_string(), - msg: to_json_binary(&connection_router_api::msg::ExecuteMsg::RouteMessages(msgs)) + msg: to_binary(&connection_router_api::msg::ExecuteMsg::RouteMessages(msgs)) .expect("must serialize route-messages message"), funds: vec![], })) @@ -67,7 +67,7 @@ where #[cfg(test)] mod test { - use cosmwasm_std::{from_json, CosmosMsg}; + use cosmwasm_std::{from_binary, CosmosMsg}; use hex::decode; use connection_router_api::CrossChainId; @@ -134,7 +134,7 @@ mod test { .unwrap() .try_into() .unwrap(), - source_tx_id: vec![0x2f, 0xe4].try_into().unwrap(), + source_tx_id: vec![0x2f; 32].try_into().unwrap(), source_tx_index: 100, }, nexus::Message { @@ -148,7 +148,7 @@ mod test { .unwrap() .try_into() .unwrap(), - source_tx_id: vec![0x23, 0xf4].try_into().unwrap(), + source_tx_id: vec![0x23; 32].try_into().unwrap(), source_tx_index: 1000, }, ]; @@ -166,7 +166,7 @@ mod test { funds, }) => { if let Ok(connection_router_api::msg::ExecuteMsg::RouteMessages(msgs)) = - from_json(msg) + from_binary(msg) { return *contract_addr == Addr::unchecked("router") && msgs.len() == 2 diff --git a/contracts/nexus-gateway/src/error.rs b/contracts/nexus-gateway/src/error.rs index f5966bc6f..385d2d5b4 100644 --- a/contracts/nexus-gateway/src/error.rs +++ b/contracts/nexus-gateway/src/error.rs @@ -14,6 +14,12 @@ pub enum ContractError { #[error("invalid message id {0}")] InvalidMessageId(String), + #[error("invalid source tx id {0}")] + InvalidSourceTxId(String), + + #[error("invalid event index {0}")] + InvalidEventIndex(u64), + #[error("invalid payload hash {0}")] InvalidMessagePayloadHash(HexBinary), diff --git a/contracts/nexus-gateway/src/nexus.rs b/contracts/nexus-gateway/src/nexus.rs index 86b7846da..b1176aa80 100644 --- a/contracts/nexus-gateway/src/nexus.rs +++ b/contracts/nexus-gateway/src/nexus.rs @@ -1,7 +1,7 @@ -use axelar_wasm_std::nonempty; +use axelar_wasm_std::{msg_id::tx_hash_event_index::HexTxHashAndEventIndex, nonempty}; use connection_router_api::{Address, ChainName, CrossChainId}; use cosmwasm_std::{CosmosMsg, CustomMsg}; -use error_stack::{Result, ResultExt}; +use error_stack::{Report, Result, ResultExt}; use hex::{FromHex, ToHex}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -68,24 +68,29 @@ impl From for Message { } } -impl From for connection_router_api::Message { - fn from(msg: Message) -> Self { - Self { +impl TryFrom for connection_router_api::Message { + type Error = Report; + + fn try_from(msg: Message) -> Result { + let msg_id = HexTxHashAndEventIndex { + tx_hash: <[u8; 32]>::try_from(msg.source_tx_id.as_ref().as_slice()).map_err(|_| { + ContractError::InvalidSourceTxId(msg.source_tx_id.as_ref().encode_hex::()) + })?, + event_index: u32::try_from(msg.source_tx_index) + .map_err(|_| ContractError::InvalidEventIndex(msg.source_tx_index))?, + }; + + Ok(Self { cc_id: CrossChainId { chain: msg.source_chain, - id: format!( - "{}:{}", - msg.source_tx_id.as_ref().encode_hex::(), - msg.source_tx_index - ) - .try_into() - .expect("cannot be empty"), + id: nonempty::String::try_from(msg_id.to_string()) + .change_context(ContractError::InvalidMessageId(msg_id.to_string()))?, }, source_address: msg.source_address, destination_chain: msg.destination_chain, destination_address: msg.destination_address, payload_hash: msg.payload_hash, - } + }) } } @@ -94,3 +99,38 @@ impl From for CosmosMsg { CosmosMsg::Custom(msg) } } + +#[cfg(test)] +mod test { + use std::vec; + + use cosmwasm_std::HexBinary; + + use super::Message; + + #[test] + fn should_convert_nexus_message_to_router_message() { + let msg = Message { + source_chain: "ethereum".parse().unwrap(), + source_address: "something".parse().unwrap(), + destination_chain: "polygon".parse().unwrap(), + destination_address: "something else".parse().unwrap(), + payload_hash: [1; 32], + source_tx_id: vec![2; 32].try_into().unwrap(), + source_tx_index: 1, + }; + + let router_msg = connection_router_api::Message::try_from(msg.clone()); + assert!(router_msg.is_ok()); + let router_msg = router_msg.unwrap(); + assert_eq!(router_msg.cc_id.chain, msg.source_chain); + assert_eq!( + router_msg.cc_id.id.to_string(), + format!( + "0x{}-{}", + HexBinary::from(msg.source_tx_id.as_ref().clone()).to_hex(), + msg.source_tx_index + ) + ); + } +} diff --git a/contracts/rewards/Cargo.toml b/contracts/rewards/Cargo.toml index 23aac0b85..821d833d1 100644 --- a/contracts/rewards/Cargo.toml +++ b/contracts/rewards/Cargo.toml @@ -41,9 +41,7 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } itertools = "0.11.0" -mockall = "0.11.3" report = { workspace = true } -serde = { version = "1.0.145", default-features = false, features = ["derive"] } thiserror = { workspace = true } [dev-dependencies] diff --git a/contracts/rewards/src/contract.rs b/contracts/rewards/src/contract.rs index 7c8883575..45c2ca45e 100644 --- a/contracts/rewards/src/contract.rs +++ b/contracts/rewards/src/contract.rs @@ -1,9 +1,7 @@ use axelar_wasm_std::nonempty; #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; -use cosmwasm_std::{ - to_json_binary, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response, -}; +use cosmwasm_std::{to_binary, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Response}; use error_stack::ResultExt; use itertools::Itertools; @@ -135,7 +133,7 @@ pub fn query( match msg { QueryMsg::RewardsPool { pool_id } => { let pool = query::rewards_pool(deps.storage, pool_id, env.block.height)?; - to_json_binary(&pool) + to_binary(&pool) .change_context(ContractError::SerializeResponse) .map_err(axelar_wasm_std::ContractError::from) } diff --git a/contracts/service-registry/Cargo.toml b/contracts/service-registry/Cargo.toml index d5154e6c8..46c9f7d55 100644 --- a/contracts/service-registry/Cargo.toml +++ b/contracts/service-registry/Cargo.toml @@ -38,13 +38,11 @@ axelar-wasm-std-derive = { workspace = true } connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } report = { workspace = true } schemars = "0.8.10" serde = { version = "1.0.145", default-features = false, features = ["derive"] } -serde_json = "1.0.107" thiserror = { workspace = true } [dev-dependencies] diff --git a/contracts/service-registry/src/contract.rs b/contracts/service-registry/src/contract.rs index 19a3d0747..209f64b35 100644 --- a/contracts/service-registry/src/contract.rs +++ b/contracts/service-registry/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Order, Response, + to_binary, Addr, BankMsg, Binary, Coin, Deps, DepsMut, Env, MessageInfo, Order, Response, Uint128, }; @@ -94,6 +94,22 @@ pub fn execute( AuthorizationState::NotAuthorized, ) } + ExecuteMsg::JailWorkers { + workers, + service_name, + } => { + execute::require_governance(&deps, info)?; + let workers = workers + .into_iter() + .map(|worker| deps.api.addr_validate(&worker)) + .collect::, _>>()?; + execute::update_worker_authorization_status( + deps, + workers, + service_name, + AuthorizationState::Jailed, + ) + } ExecuteMsg::RegisterChainSupport { service_name, chains, @@ -114,9 +130,9 @@ pub fn execute( } pub mod execute { - use connection_router_api::ChainName; - + use crate::state; use crate::state::{AuthorizationState, WORKERS, WORKERS_PER_CHAIN}; + use connection_router_api::ChainName; use super::*; @@ -224,10 +240,7 @@ pub mod execute { (&service_name.clone(), &info.sender.clone()), |sw| -> Result { match sw { - Some(worker) => Ok(Worker { - bonding_state: worker.bonding_state.add_bond(bond)?, - ..worker - }), + Some(worker) => Ok(worker.add_bond(bond)?), None => Ok(Worker { address: info.sender, bonding_state: BondingState::Bonded { amount: bond }, @@ -255,9 +268,8 @@ pub mod execute { .may_load(deps.storage, (&service_name, &info.sender))? .ok_or(ContractError::WorkerNotFound)?; - for chain in chains { - WORKERS_PER_CHAIN.save(deps.storage, (&service_name, &chain, &info.sender), &())?; - } + let _res = + state::register_chains_support(deps.storage, service_name.clone(), chains, info.sender); Ok(Response::new()) } @@ -299,16 +311,9 @@ pub mod execute { let can_unbond = true; // TODO: actually query the service to determine this value - let bonding_state = worker.bonding_state.unbond(can_unbond, env.block.time)?; + let worker = worker.unbond(can_unbond, env.block.time)?; - WORKERS.save( - deps.storage, - (&service_name, &info.sender), - &Worker { - bonding_state, - ..worker - }, - )?; + WORKERS.save(deps.storage, (&service_name, &info.sender), &worker)?; Ok(Response::new()) } @@ -327,18 +332,10 @@ pub mod execute { .may_load(deps.storage, (&service_name, &info.sender))? .ok_or(ContractError::WorkerNotFound)?; - let (bonding_state, released_bond) = worker - .bonding_state - .claim_stake(env.block.time, service.unbonding_period_days as u64)?; + let (worker, released_bond) = + worker.claim_stake(env.block.time, service.unbonding_period_days as u64)?; - WORKERS.save( - deps.storage, - (&service_name, &info.sender), - &Worker { - bonding_state, - ..worker - }, - )?; + WORKERS.save(deps.storage, (&service_name, &info.sender), &worker)?; Ok(Response::new().add_message(BankMsg::Send { to_address: info.sender.into(), @@ -357,15 +354,14 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> Result to_json_binary(&query::get_active_workers(deps, service_name, chain_name)?) + } => to_binary(&query::get_active_workers(deps, service_name, chain_name)?) .map_err(|err| err.into()), QueryMsg::GetWorker { service_name, worker, - } => to_json_binary(&query::get_worker(deps, worker, service_name)?) - .map_err(|err| err.into()), + } => to_binary(&query::get_worker(deps, service_name, worker)?).map_err(|err| err.into()), QueryMsg::GetService { service_name } => { - to_json_binary(&query::get_service(deps, service_name)?).map_err(|err| err.into()) + to_binary(&query::get_service(deps, service_name)?).map_err(|err| err.into()) } } } diff --git a/contracts/service-registry/src/error.rs b/contracts/service-registry/src/error.rs index daed547dd..1194735db 100644 --- a/contracts/service-registry/src/error.rs +++ b/contracts/service-registry/src/error.rs @@ -32,4 +32,6 @@ pub enum ContractError { InvalidBondingState(BondingState), #[error("not enough workers")] NotEnoughWorkers, + #[error("worker is jailed")] + WorkerJailed, } diff --git a/contracts/service-registry/src/helpers.rs b/contracts/service-registry/src/helpers.rs index 7247c3fdf..b5fce9b31 100644 --- a/contracts/service-registry/src/helpers.rs +++ b/contracts/service-registry/src/helpers.rs @@ -1,7 +1,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{to_json_binary, Addr, CosmosMsg, StdResult, WasmMsg}; +use cosmwasm_std::{to_binary, Addr, CosmosMsg, StdResult, WasmMsg}; use crate::msg::ExecuteMsg; @@ -16,7 +16,7 @@ impl ServiceRegistry { } pub fn call>(&self, msg: T) -> StdResult { - let msg = to_json_binary(&msg.into())?; + let msg = to_binary(&msg.into())?; Ok(WasmMsg::Execute { contract_addr: self.addr().into(), msg, diff --git a/contracts/service-registry/src/msg.rs b/contracts/service-registry/src/msg.rs index c95a1f2e0..3b17cb439 100644 --- a/contracts/service-registry/src/msg.rs +++ b/contracts/service-registry/src/msg.rs @@ -30,6 +30,11 @@ pub enum ExecuteMsg { workers: Vec, service_name: String, }, + // Jail workers. Can only be called by governance account. Jailed workers are not allowed to unbond or claim stake. + JailWorkers { + workers: Vec, + service_name: String, + }, // Register support for the specified chains. Called by the worker. RegisterChainSupport { diff --git a/contracts/service-registry/src/state.rs b/contracts/service-registry/src/state.rs index abf101796..15609aca8 100644 --- a/contracts/service-registry/src/state.rs +++ b/contracts/service-registry/src/state.rs @@ -2,8 +2,9 @@ use connection_router_api::ChainName; use cosmwasm_schema::cw_serde; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use std::collections::HashSet; -use cosmwasm_std::{Addr, Timestamp, Uint128}; +use cosmwasm_std::{Addr, Storage, Timestamp, Uint128}; use cw_storage_plus::{Item, Map}; #[cw_serde] @@ -25,6 +26,8 @@ pub struct Service { pub max_num_workers: Option, pub min_worker_bond: Uint128, pub bond_denom: String, + // should be set to a duration longer than the voting period for governance proposals, + // otherwise a verifier could bail before they get penalized pub unbonding_period_days: u16, pub description: String, } @@ -37,42 +40,9 @@ pub struct Worker { pub service_name: String, } -#[cw_serde] -pub struct WeightedWorker { - pub worker_info: Worker, - pub weight: nonempty::Uint256, -} - -/// For now, all workers have equal weight, regardless of amount bonded -pub const WORKER_WEIGHT: nonempty::Uint256 = nonempty::Uint256::one(); - -impl From for Participant { - fn from(worker: WeightedWorker) -> Participant { - Self { - weight: worker.weight, - address: worker.worker_info.address, - } - } -} - -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -pub enum BondingState { - Bonded { - amount: Uint128, - }, - RequestedUnbonding { - amount: Uint128, - }, - Unbonding { - amount: Uint128, - unbonded_at: Timestamp, - }, - Unbonded, -} - -impl BondingState { +impl Worker { pub fn add_bond(self, to_add: Uint128) -> Result { - let amount = match self { + let amount = match self.bonding_state { BondingState::Bonded { amount } | BondingState::RequestedUnbonding { amount } | BondingState::Unbonding { @@ -83,71 +53,258 @@ impl BondingState { .map_err(ContractError::Overflow)?, BondingState::Unbonded => to_add, }; + if amount.is_zero() { - Err(ContractError::InvalidBondingState(self)) + Err(ContractError::InvalidBondingState(self.bonding_state)) } else { - Ok(BondingState::Bonded { amount }) + Ok(Self { + bonding_state: BondingState::Bonded { amount }, + ..self + }) } } pub fn unbond(self, can_unbond: bool, time: Timestamp) -> Result { - match self { + if self.authorization_state == AuthorizationState::Jailed { + return Err(ContractError::WorkerJailed); + } + + let bonding_state = match self.bonding_state { BondingState::Bonded { amount } | BondingState::RequestedUnbonding { amount } => { if can_unbond { - Ok(BondingState::Unbonding { + BondingState::Unbonding { unbonded_at: time, amount, - }) + } } else { - Ok(BondingState::RequestedUnbonding { amount }) + BondingState::RequestedUnbonding { amount } } } - _ => Err(ContractError::InvalidBondingState(self)), - } + _ => return Err(ContractError::InvalidBondingState(self.bonding_state)), + }; + + Ok(Self { + bonding_state, + ..self + }) } + pub fn claim_stake( self, time: Timestamp, unbonding_period_days: u64, ) -> Result<(Self, Uint128), ContractError> { - match self { + if self.authorization_state == AuthorizationState::Jailed { + return Err(ContractError::WorkerJailed); + } + + match self.bonding_state { BondingState::Unbonding { amount, unbonded_at, - } if unbonded_at.plus_days(unbonding_period_days) <= time => { - Ok((BondingState::Unbonded, amount)) - } - _ => Err(ContractError::InvalidBondingState(self)), + } if unbonded_at.plus_days(unbonding_period_days) <= time => Ok(( + Self { + bonding_state: BondingState::Unbonded, + ..self + }, + amount, + )), + _ => Err(ContractError::InvalidBondingState(self.bonding_state)), + } + } +} + +#[cw_serde] +pub struct WeightedWorker { + pub worker_info: Worker, + pub weight: nonempty::Uint256, +} + +/// For now, all workers have equal weight, regardless of amount bonded +pub const WORKER_WEIGHT: nonempty::Uint256 = nonempty::Uint256::one(); + +impl From for Participant { + fn from(worker: WeightedWorker) -> Participant { + Self { + weight: worker.weight, + address: worker.worker_info.address, } } } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub enum BondingState { + Bonded { + amount: Uint128, + }, + RequestedUnbonding { + amount: Uint128, + }, + Unbonding { + amount: Uint128, + unbonded_at: Timestamp, + }, + Unbonded, +} + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub enum AuthorizationState { NotAuthorized, Authorized, + Jailed, +} + +type ChainNames = HashSet; +type ServiceName = str; +type WorkerAddress = Addr; + +pub const SERVICES: Map<&ServiceName, Service> = Map::new("services"); +pub const WORKERS_PER_CHAIN: Map<(&ServiceName, &ChainName, &WorkerAddress), ()> = + Map::new("workers_per_chain"); +pub const CHAINS_PER_WORKER: Map<(&ServiceName, &WorkerAddress), ChainNames> = + Map::new("chains_per_worker"); +pub const WORKERS: Map<(&ServiceName, &WorkerAddress), Worker> = Map::new("workers"); + +pub fn register_chains_support( + storage: &mut dyn Storage, + service_name: String, + chains: Vec, + worker: WorkerAddress, +) -> Result<(), ContractError> { + CHAINS_PER_WORKER.update(storage, (&service_name, &worker), |current_chains| { + let mut current_chains = current_chains.unwrap_or_default(); + current_chains.extend(chains.iter().cloned()); + Ok::, ContractError>(current_chains) + })?; + + for chain in chains.iter() { + WORKERS_PER_CHAIN.save(storage, (&service_name, chain, &worker), &())?; + } + + Ok(()) } -// maps service_name -> Service -pub const SERVICES: Map<&str, Service> = Map::new("services"); -// maps (service_name, chain_name, worker_address) -> () -pub const WORKERS_PER_CHAIN: Map<(&str, &ChainName, &Addr), ()> = Map::new("workers_per_chain"); -// maps (service_name, worker_address) -> Worker -pub const WORKERS: Map<(&str, &Addr), Worker> = Map::new("workers"); +pub fn may_load_chains_per_worker( + storage: &dyn Storage, + service_name: String, + worker_address: WorkerAddress, +) -> Result, ContractError> { + CHAINS_PER_WORKER + .may_load(storage, (&service_name, &worker_address))? + .ok_or(ContractError::WorkerNotFound) +} #[cfg(test)] mod tests { use super::*; + use cosmwasm_std::testing::mock_dependencies; + use std::{str::FromStr, vec}; + + #[test] + fn register_single_worker_chain_single_call_success() { + let mut deps = mock_dependencies(); + let worker = Addr::unchecked("worker"); + let service_name = "validators"; + let chain_name = ChainName::from_str("ethereum").unwrap(); + let chains = vec![chain_name.clone()]; + assert!(register_chains_support( + deps.as_mut().storage, + service_name.into(), + chains, + worker.clone() + ) + .is_ok()); + + let worker_chains = + may_load_chains_per_worker(deps.as_mut().storage, service_name.into(), worker).unwrap(); + assert!(worker_chains.contains(&chain_name)); + } + + #[test] + fn register_multiple_worker_chains_single_call_success() { + let mut deps = mock_dependencies(); + let worker = Addr::unchecked("worker"); + let service_name = "validators"; + let chain_names = vec![ + ChainName::from_str("ethereum").unwrap(), + ChainName::from_str("cosmos").unwrap(), + ]; + + assert!(register_chains_support( + deps.as_mut().storage, + service_name.into(), + chain_names.clone(), + worker.clone() + ) + .is_ok()); + + let worker_chains = + may_load_chains_per_worker(deps.as_mut().storage, service_name.into(), worker).unwrap(); + + for chain_name in chain_names { + assert!(worker_chains.contains(&chain_name)); + } + } + + #[test] + fn register_multiple_worker_chains_multiple_calls_success() { + let mut deps = mock_dependencies(); + let worker = Addr::unchecked("worker"); + let service_name = "validators"; + + let first_chain_name = ChainName::from_str("ethereum").unwrap(); + let first_chains_vector = vec![first_chain_name.clone()]; + assert!(register_chains_support( + deps.as_mut().storage, + service_name.into(), + first_chains_vector, + worker.clone() + ) + .is_ok()); + + let second_chain_name = ChainName::from_str("cosmos").unwrap(); + let second_chains_vector = vec![second_chain_name.clone()]; + assert!(register_chains_support( + deps.as_mut().storage, + service_name.into(), + second_chains_vector, + worker.clone() + ) + .is_ok()); + + let worker_chains = + may_load_chains_per_worker(deps.as_mut().storage, service_name.into(), worker).unwrap(); + + assert!(worker_chains.contains(&first_chain_name)); + assert!(worker_chains.contains(&second_chain_name)); + } + + #[test] + fn get_unregistered_worker_chains_fails() { + let mut deps = mock_dependencies(); + let worker = Addr::unchecked("worker"); + let service_name = "validators"; + + let err = may_load_chains_per_worker(deps.as_mut().storage, service_name.into(), worker) + .unwrap_err(); + assert!(matches!(err, ContractError::WorkerNotFound)); + } #[test] fn test_bonded_add_bond() { - let state = BondingState::Bonded { - amount: Uint128::from(100u32), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Bonded { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; - let res = state.add_bond(Uint128::from(200u32)); + + let res = worker.add_bond(Uint128::from(200u32)); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::Bonded { amount: Uint128::from(300u32) } @@ -156,13 +313,19 @@ mod tests { #[test] fn test_requested_unbonding_add_bond() { - let state = BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::RequestedUnbonding { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; - let res = state.add_bond(Uint128::from(200u32)); + + let res = worker.add_bond(Uint128::from(200u32)); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::Bonded { amount: Uint128::from(300u32) } @@ -171,14 +334,20 @@ mod tests { #[test] fn test_unbonding_add_bond() { - let state = BondingState::Unbonding { - amount: Uint128::from(100u32), - unbonded_at: Timestamp::from_nanos(0), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Unbonding { + amount: Uint128::from(100u32), + unbonded_at: Timestamp::from_nanos(0), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; - let res = state.add_bond(Uint128::from(200u32)); + + let res = worker.add_bond(Uint128::from(200u32)); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::Bonded { amount: Uint128::from(300u32) } @@ -187,11 +356,17 @@ mod tests { #[test] fn test_unbonded_add_bond() { - let state = BondingState::Unbonded; - let res = state.add_bond(Uint128::from(200u32)); + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Unbonded, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = worker.add_bond(Uint128::from(200u32)); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::Bonded { amount: Uint128::from(200u32) } @@ -200,22 +375,39 @@ mod tests { #[test] fn test_zero_bond() { - let state = BondingState::Unbonded; - let res = state.clone().add_bond(Uint128::from(0u32)); + let bonding_state = BondingState::Unbonded; + + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = worker.add_bond(Uint128::from(0u32)); assert!(res.is_err()); - assert_eq!(res.unwrap_err(), ContractError::InvalidBondingState(state)); + assert_eq!( + res.unwrap_err(), + ContractError::InvalidBondingState(bonding_state) + ); } #[test] fn test_bonded_unbond() { - let state = BondingState::Bonded { - amount: Uint128::from(100u32), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Bonded { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; + let unbonded_at = Timestamp::from_nanos(0); - let res = state.unbond(true, unbonded_at); + let res = worker.unbond(true, unbonded_at); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::Unbonding { amount: Uint128::from(100u32), unbonded_at @@ -225,14 +417,20 @@ mod tests { #[test] fn test_bonded_unbond_cant_unbond() { - let state = BondingState::Bonded { - amount: Uint128::from(100u32), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Bonded { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; + let unbonded_at = Timestamp::from_nanos(0); - let res = state.unbond(false, unbonded_at); + let res = worker.unbond(false, unbonded_at); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::RequestedUnbonding { amount: Uint128::from(100u32) } @@ -241,14 +439,20 @@ mod tests { #[test] fn test_requested_unbonding_unbond() { - let state = BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::RequestedUnbonding { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; + let unbonded_at = Timestamp::from_nanos(0); - let res = state.unbond(true, unbonded_at); + let res = worker.unbond(true, unbonded_at); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::Unbonding { amount: Uint128::from(100u32), unbonded_at @@ -258,14 +462,20 @@ mod tests { #[test] fn test_requested_unbonding_cant_unbond() { - let state = BondingState::RequestedUnbonding { - amount: Uint128::from(100u32), + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::RequestedUnbonding { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; + let unbonded_at = Timestamp::from_nanos(0); - let res = state.unbond(false, unbonded_at); + let res = worker.unbond(false, unbonded_at); assert!(res.is_ok()); assert_eq!( - res.unwrap(), + res.unwrap().bonding_state, BondingState::RequestedUnbonding { amount: Uint128::from(100u32) } @@ -274,117 +484,198 @@ mod tests { #[test] fn test_unbonding_unbond() { - let unbonded_at = Timestamp::from_nanos(0); - let state = BondingState::Unbonding { + let bonding_state = BondingState::Unbonding { amount: Uint128::from(100u32), - unbonded_at, + unbonded_at: Timestamp::from_nanos(0), + }; + + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; - let res = state.clone().unbond(true, Timestamp::from_nanos(2)); + + let res = worker.clone().unbond(true, Timestamp::from_nanos(2)); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); - let res = state.clone().unbond(false, Timestamp::from_nanos(2)); + + let res = worker.unbond(false, Timestamp::from_nanos(2)); assert!(res.is_err()); - assert_eq!(res.unwrap_err(), ContractError::InvalidBondingState(state)); + assert_eq!( + res.unwrap_err(), + ContractError::InvalidBondingState(bonding_state.clone()) + ); } #[test] fn test_unbonded_unbond() { - let state = BondingState::Unbonded; - let res = state.clone().unbond(true, Timestamp::from_nanos(2)); + let bonding_state = BondingState::Unbonded; + + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = worker.clone().unbond(true, Timestamp::from_nanos(2)); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); - let res = state.clone().unbond(false, Timestamp::from_nanos(2)); + + let res = worker.unbond(false, Timestamp::from_nanos(2)); assert!(res.is_err()); - assert_eq!(res.unwrap_err(), ContractError::InvalidBondingState(state)); + assert_eq!( + res.unwrap_err(), + ContractError::InvalidBondingState(bonding_state.clone()) + ); } #[test] fn test_bonded_claim_stake() { - let state = BondingState::Bonded { + let bonding_state = BondingState::Bonded { amount: Uint128::from(100u32), }; - let res = state.clone().claim_stake(Timestamp::from_seconds(60), 1); + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = worker.clone().claim_stake(Timestamp::from_seconds(60), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); - let res = state - .clone() - .claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); + + let res = worker.claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); } #[test] fn test_requested_unbonding_claim_stake() { - let state = BondingState::RequestedUnbonding { + let bonding_state = BondingState::RequestedUnbonding { amount: Uint128::from(100u32), }; - let res = state.clone().claim_stake(Timestamp::from_seconds(60), 1); + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = worker.clone().claim_stake(Timestamp::from_seconds(60), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); - let res = state - .clone() - .claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); + + let res = worker.claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); } #[test] fn test_unbonding_claim_stake() { - let unbonded_at = Timestamp::from_nanos(0); - let state = BondingState::Unbonding { + let bonding_state = BondingState::Unbonding { amount: Uint128::from(100u32), - unbonded_at, + unbonded_at: Timestamp::from_nanos(0), + }; + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), }; - let res = state.clone().claim_stake(Timestamp::from_seconds(60), 1); + + let res = worker.clone().claim_stake(Timestamp::from_seconds(60), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); - let res = state - .clone() - .claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); + + let res = worker.claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); assert!(res.is_ok()); + + let (worker, amount) = res.unwrap(); assert_eq!( - res.unwrap(), + (worker.bonding_state, amount), (BondingState::Unbonded, Uint128::from(100u32)) ); } #[test] fn test_unbonded_claim_stake() { - let state = BondingState::Unbonded; - let res = state.clone().claim_stake(Timestamp::from_seconds(60), 1); + let bonding_state = BondingState::Unbonded; + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: bonding_state.clone(), + authorization_state: AuthorizationState::Authorized, + service_name: "validators".to_string(), + }; + + let res = worker.clone().claim_stake(Timestamp::from_seconds(60), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); - let res = state - .clone() - .claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); + + let res = worker.claim_stake(Timestamp::from_seconds(60 * 60 * 24), 1); assert!(res.is_err()); assert_eq!( res.unwrap_err(), - ContractError::InvalidBondingState(state.clone()) + ContractError::InvalidBondingState(bonding_state.clone()) ); } + + #[test] + fn jailed_worker_cannot_unbond() { + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Bonded { + amount: Uint128::from(100u32), + }, + authorization_state: AuthorizationState::Jailed, + service_name: "validators".to_string(), + }; + + let res = worker.unbond(true, Timestamp::from_nanos(0)); + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::WorkerJailed); + } + + #[test] + fn jailed_worker_cannot_claim_stake() { + let worker = Worker { + address: Addr::unchecked("worker"), + bonding_state: BondingState::Unbonding { + amount: Uint128::from(100u32), + unbonded_at: Timestamp::from_nanos(0), + }, + authorization_state: AuthorizationState::Jailed, + service_name: "validators".to_string(), + }; + + let res = worker.claim_stake(Timestamp::from_nanos(1), 0); + assert!(res.is_err()); + assert_eq!(res.unwrap_err(), ContractError::WorkerJailed); + } } diff --git a/contracts/service-registry/tests/tests.rs b/contracts/service-registry/tests/tests.rs index a3e29d157..ccb8f8297 100644 --- a/contracts/service-registry/tests/tests.rs +++ b/contracts/service-registry/tests/tests.rs @@ -3,8 +3,8 @@ mod test_utils; use std::{str::FromStr, vec}; use connection_router_api::ChainName; -use cosmwasm_std::{coins, Addr, BlockInfo, StdResult, Uint128}; -use cw_multi_test::App; +use cosmwasm_std::{coins, Addr, BankMsg, BlockInfo, StdResult, Uint128}; +use cw_multi_test::{App, Executor}; use integration_tests::contract::Contract; use service_registry::msg::QueryMsg; use service_registry::state::{WeightedWorker, WORKER_WEIGHT}; @@ -1717,3 +1717,159 @@ fn get_active_workers_should_not_return_less_than_min() { ); assert!(res.is_err()); } + +#[test] +fn jail_worker() { + let faucet = Addr::unchecked("faucet"); + // init app with faucet balance + let mut app = App::new(|router, _, storage| { + router + .bank + .init_balance(storage, &faucet, coins(100000, AXL_DENOMINATION)) + .unwrap() + }); + + // init service registry contract + let governance = Addr::unchecked("gov"); + let service_registry = + test_utils::ServiceRegistryContract::instantiate_contract(&mut app, governance.clone()); + + // register a service + let service_name = "validators"; + let min_worker_bond = Uint128::new(100); + let unbonding_period_days = 10; + let res = service_registry.execute( + &mut app, + governance.clone(), + &ExecuteMsg::RegisterService { + service_name: service_name.into(), + service_contract: Addr::unchecked("service contract"), + min_num_workers: 0, + max_num_workers: Some(100), + min_worker_bond, + bond_denom: AXL_DENOMINATION.into(), + unbonding_period_days, + description: "Some service".into(), + }, + ); + assert!(res.is_ok()); + + // given a bonded worker + let worker1 = Addr::unchecked("worker-1"); + // fund worker + let msg: cosmwasm_std::CosmosMsg = BankMsg::Send { + to_address: worker1.clone().into(), + amount: coins(min_worker_bond.u128(), AXL_DENOMINATION), + } + .into(); + app.execute(faucet.clone(), msg.clone()).unwrap(); + let res = service_registry.execute_with_funds( + &mut app, + worker1.clone(), + &ExecuteMsg::BondWorker { + service_name: service_name.into(), + }, + &coins(min_worker_bond.u128(), AXL_DENOMINATION), + ); + assert!(res.is_ok()); + + // when worker is jailed + let res = service_registry.execute( + &mut app, + governance.clone(), + &ExecuteMsg::JailWorkers { + workers: vec![worker1.clone().into()], + service_name: service_name.into(), + }, + ); + assert!(res.is_ok()); + + // worker cannot unbond + let err = service_registry + .execute( + &mut app, + worker1.clone(), + &ExecuteMsg::UnbondWorker { + service_name: service_name.into(), + }, + ) + .unwrap_err(); + test_utils::are_contract_err_strings_equal(err, ContractError::WorkerJailed); + + // given a worker passed unbonding period + let worker2 = Addr::unchecked("worker-2"); + // fund worker + let msg: cosmwasm_std::CosmosMsg = BankMsg::Send { + to_address: worker2.clone().into(), + amount: coins(min_worker_bond.u128(), AXL_DENOMINATION), + } + .into(); + app.execute(faucet.clone(), msg.clone()).unwrap(); + // bond worker + let res = service_registry.execute_with_funds( + &mut app, + worker2.clone(), + &ExecuteMsg::BondWorker { + service_name: service_name.into(), + }, + &coins(min_worker_bond.u128(), AXL_DENOMINATION), + ); + assert!(res.is_ok()); + // unbond worker + let res = service_registry.execute( + &mut app, + worker2.clone(), + &ExecuteMsg::UnbondWorker { + service_name: service_name.into(), + }, + ); + assert!(res.is_ok()); + let worker: Worker = service_registry + .query( + &app, + &QueryMsg::GetWorker { + service_name: service_name.into(), + worker: worker2.to_string(), + }, + ) + .unwrap(); + + let block = app.block_info(); + assert_eq!( + worker.bonding_state, + BondingState::Unbonding { + amount: min_worker_bond, + unbonded_at: block.time, + } + ); + + // when worker is jailed + let res = service_registry.execute( + &mut app, + governance, + &ExecuteMsg::JailWorkers { + workers: vec![worker2.clone().into()], + service_name: service_name.into(), + }, + ); + assert!(res.is_ok()); + + // and unbonding period has passed + app.set_block(BlockInfo { + height: block.height + 1, + time: block.time.plus_days((unbonding_period_days + 1).into()), + ..block + }); + + // worker cannot claim stake + let err = service_registry + .execute( + &mut app, + worker2.clone(), + &ExecuteMsg::ClaimStake { + service_name: service_name.into(), + }, + ) + .unwrap_err(); + test_utils::are_contract_err_strings_equal(err, ContractError::WorkerJailed); +} diff --git a/contracts/voting-verifier/Cargo.toml b/contracts/voting-verifier/Cargo.toml index bd936fe17..b56f0dac3 100644 --- a/contracts/voting-verifier/Cargo.toml +++ b/contracts/voting-verifier/Cargo.toml @@ -38,17 +38,12 @@ axelar-wasm-std-derive = { workspace = true } connection-router-api = { workspace = true } cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } -either = "1.8.1" error-stack = { workspace = true } report = { workspace = true } rewards = { workspace = true, features = ["library"] } -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -serde_json = "1.0.89" +serde_json = { workspace = true } service-registry = { workspace = true, features = ["library"] } -sha3 = { workspace = true } thiserror = { workspace = true } [dev-dependencies] diff --git a/contracts/voting-verifier/src/contract.rs b/contracts/voting-verifier/src/contract.rs index 0a1a72498..200d31ee1 100644 --- a/contracts/voting-verifier/src/contract.rs +++ b/contracts/voting-verifier/src/contract.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "library"))] use cosmwasm_std::entry_point; use cosmwasm_std::{ - to_json_binary, Attribute, Binary, Deps, DepsMut, Env, Event, MessageInfo, Response, StdResult, + to_binary, Attribute, Binary, Deps, DepsMut, Env, Event, MessageInfo, Response, StdResult, }; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; @@ -16,6 +16,7 @@ pub fn instantiate( msg: InstantiateMsg, ) -> Result { let config = Config { + governance: deps.api.addr_validate(&msg.governance_address)?, service_name: msg.service_name, service_registry_contract: deps.api.addr_validate(&msg.service_registry_address)?, source_gateway_address: msg.source_gateway_address, @@ -46,6 +47,12 @@ pub fn execute( message_id, new_operators, } => execute::verify_worker_set(deps, env, message_id, new_operators), + ExecuteMsg::UpdateVotingThreshold { + new_voting_threshold, + } => { + execute::require_governance(&deps, info.sender)?; + execute::update_voting_threshold(deps, new_voting_threshold) + } } .map_err(axelar_wasm_std::ContractError::from) } @@ -58,24 +65,27 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } QueryMsg::GetMessagesStatus { messages } => { - to_json_binary(&query::messages_status(deps, &messages)?) + to_binary(&query::messages_status(deps, &messages)?) } QueryMsg::GetWorkerSetStatus { new_operators } => { - to_json_binary(&query::worker_set_status(deps, &new_operators)?) + to_binary(&query::worker_set_status(deps, &new_operators)?) } + QueryMsg::GetCurrentThreshold => to_binary(&query::voting_threshold(deps)?), } } #[cfg(test)] mod test { + use cosmwasm_std::{ - from_json, + from_binary, testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage}, - Addr, Empty, OwnedDeps, Uint128, Uint64, WasmQuery, + Addr, Empty, Fraction, OwnedDeps, Uint128, Uint64, WasmQuery, }; use axelar_wasm_std::{ - nonempty, operators::Operators, voting::Vote, Threshold, VerificationStatus, + nonempty, operators::Operators, voting::Vote, MajorityThreshold, Threshold, + VerificationStatus, }; use connection_router_api::{ChainName, CrossChainId, Message}; use service_registry::state::{ @@ -85,7 +95,6 @@ mod test { use crate::{ error::ContractError, events::{TxEventConfirmation, TX_HASH_EVENT_INDEX_SEPARATOR}, - msg::VerifyMessagesResponse, }; use super::*; @@ -95,11 +104,20 @@ mod test { const REWARDS_ADDRESS: &str = "rewards_address"; const SERVICE_NAME: &str = "service_name"; const POLL_BLOCK_EXPIRY: u64 = 100; + const GOVERNANCE: &str = "governance"; fn source_chain() -> ChainName { "source-chain".parse().unwrap() } + fn governance() -> Addr { + Addr::unchecked(GOVERNANCE) + } + + fn initial_voting_threshold() -> MajorityThreshold { + Threshold::try_from((2, 3)).unwrap().try_into().unwrap() + } + fn assert_contract_err_strings_equal( actual: impl Into, expected: impl Into, @@ -107,38 +125,30 @@ mod test { assert_eq!(actual.into().to_string(), expected.into().to_string()); } - fn workers() -> Vec { - vec![ - Worker { - address: Addr::unchecked("addr1"), + fn workers(num_workers: usize) -> Vec { + let mut workers = vec![]; + for i in 0..num_workers { + workers.push(Worker { + address: Addr::unchecked(format!("addr{}", i)), bonding_state: BondingState::Bonded { amount: Uint128::from(100u128), }, authorization_state: AuthorizationState::Authorized, service_name: SERVICE_NAME.parse().unwrap(), - }, - Worker { - address: Addr::unchecked("addr2"), - bonding_state: BondingState::Bonded { - amount: Uint128::from(100u128), - }, - authorization_state: AuthorizationState::Authorized, - service_name: SERVICE_NAME.parse().unwrap(), - }, - ] + }) + } + workers } - fn setup() -> OwnedDeps { + fn setup(workers: Vec) -> OwnedDeps { let mut deps = mock_dependencies(); let config = Config { + governance: governance(), service_name: SERVICE_NAME.parse().unwrap(), service_registry_contract: Addr::unchecked(SERVICE_REGISTRY_ADDRESS), source_gateway_address: "source_gateway_address".parse().unwrap(), - voting_threshold: Threshold::try_from((2u64, 3u64)) - .unwrap() - .try_into() - .unwrap(), + voting_threshold: initial_voting_threshold(), block_expiry: POLL_BLOCK_EXPIRY, confirmation_height: 100, source_chain: source_chain(), @@ -146,10 +156,11 @@ mod test { }; CONFIG.save(deps.as_mut().storage, &config).unwrap(); - deps.querier.update_wasm(|wq| match wq { + deps.querier.update_wasm(move |wq| match wq { WasmQuery::Smart { contract_addr, .. } if contract_addr == SERVICE_REGISTRY_ADDRESS => { - Ok(to_json_binary( - &workers() + Ok(to_binary( + &workers + .clone() .into_iter() .map(|w| WeightedWorker { worker_info: w, @@ -194,9 +205,20 @@ mod test { env } + fn msg_ids_and_statuses( + messages: Vec, + status: VerificationStatus, + ) -> Vec<(CrossChainId, VerificationStatus)> { + messages + .iter() + .map(|message| (message.cc_id.clone(), status)) + .collect::>() + } + #[test] fn should_fail_if_messages_are_not_from_same_source() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let msg = ExecuteMsg::VerifyMessages { messages: vec![ @@ -226,50 +248,20 @@ mod test { assert_contract_err_strings_equal(err, ContractError::SourceChainMismatch(source_chain())); } - #[test] - fn should_verify_messages_if_not_verified() { - let mut deps = setup(); - - let msg = ExecuteMsg::VerifyMessages { - messages: messages(2), - }; - - let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap(); - let reply: VerifyMessagesResponse = from_json(res.data.unwrap()).unwrap(); - assert_eq!(reply.verification_statuses.len(), 2); - assert_eq!( - reply.verification_statuses, - vec![ - ( - CrossChainId { - id: message_id("id", 0), - chain: source_chain() - }, - VerificationStatus::None - ), - ( - CrossChainId { - id: message_id("id", 1), - chain: source_chain() - }, - VerificationStatus::None - ), - ] - ); - } - #[test] fn should_not_verify_messages_if_in_progress() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); + let messages_count = 5; let messages_in_progress = 3; - let new_messages = 2; + let messages = messages(messages_count as u64); execute( deps.as_mut(), mock_env(), mock_info(SENDER, &[]), ExecuteMsg::VerifyMessages { - messages: messages(messages_in_progress), + messages: messages[0..messages_in_progress].to_vec(), // verify a subset of the messages }, ) .unwrap(); @@ -279,12 +271,12 @@ mod test { mock_env(), mock_info(SENDER, &[]), ExecuteMsg::VerifyMessages { - messages: messages(messages_in_progress + new_messages), // creates the same messages + some new ones + messages: messages.clone(), // verify all messages including the ones from previous execution }, ) .unwrap(); - let messages: Vec = serde_json::from_str( + let actual: Vec = serde_json::from_str( &res.events .into_iter() .find(|event| event.ty == "messages_poll_started") @@ -302,15 +294,24 @@ mod test { ) .unwrap(); - assert_eq!(messages.len() as u64, new_messages); + // messages starting after the ones already in progress + let expected = messages[messages_in_progress..] + .iter() + .cloned() + .map(|e| e.try_into().unwrap()) + .collect::>(); + + assert_eq!(actual, expected); } #[test] fn should_retry_if_message_not_verified() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); + let messages = messages(5); let msg = ExecuteMsg::VerifyMessages { - messages: messages(1), + messages: messages.clone(), }; execute( deps.as_mut(), @@ -330,10 +331,27 @@ mod test { ) .unwrap(); + // confirm it was not verified + let status: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( + deps.as_ref(), + mock_env(), + QueryMsg::GetMessagesStatus { + messages: messages.clone(), + }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!( + status, + msg_ids_and_statuses(messages.clone(), VerificationStatus::FailedToVerify) + ); + // retries same message let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap(); - let messages: Vec = serde_json::from_str( + let actual: Vec = serde_json::from_str( &res.events .into_iter() .find(|event| event.ty == "messages_poll_started") @@ -351,12 +369,18 @@ mod test { ) .unwrap(); - assert_eq!(messages.len() as u64, 1); + let expected = messages + .into_iter() + .map(|e| e.try_into().unwrap()) + .collect::>(); + + assert_eq!(actual, expected); } #[test] fn should_retry_if_status_not_final() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let messages = messages(4); @@ -376,7 +400,7 @@ mod test { // 2. Workers cast votes, but only reach consensus on the first three messages - workers().iter().enumerate().for_each(|(i, worker)| { + workers.iter().enumerate().for_each(|(i, worker)| { let msg = ExecuteMsg::Vote { poll_id: 1u64.into(), votes: vec![ @@ -415,8 +439,8 @@ mod test { ); assert!(res.is_ok()); - let res: Vec<(CrossChainId, VerificationStatus)> = from_json( - query( + let res: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetMessagesStatus { @@ -453,8 +477,8 @@ mod test { ); assert!(res.is_ok()); - let res: Vec<(CrossChainId, VerificationStatus)> = from_json( - query( + let res: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetMessagesStatus { @@ -479,29 +503,49 @@ mod test { } #[test] - fn should_query_message_statuses() { - let mut deps = setup(); + fn should_query_status_none_when_not_verified() { + let workers = workers(2); + let deps = setup(workers.clone()); let messages = messages(10); - let msg = ExecuteMsg::VerifyMessages { - messages: messages.clone(), - }; - - let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg).unwrap(); - - let reply: VerifyMessagesResponse = from_json(res.data.unwrap()).unwrap(); - assert_eq!(reply.verification_statuses.len(), messages.len()); + let statuses: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( + deps.as_ref(), + mock_env(), + QueryMsg::GetMessagesStatus { + messages: messages.clone(), + }, + ) + .unwrap(), + ) + .unwrap(); assert_eq!( - reply.verification_statuses, - messages - .iter() - .map(|message| (message.cc_id.clone(), VerificationStatus::None)) - .collect::>() + statuses, + msg_ids_and_statuses(messages, VerificationStatus::None) ); + } + + #[test] + fn should_query_status_in_progress_when_no_consensus_and_poll_not_ended() { + let workers = workers(2); + let mut deps = setup(workers.clone()); - let statuses: Vec<(CrossChainId, VerificationStatus)> = from_json( - query( + let messages = messages(10); + + // starts verification process + execute( + deps.as_mut(), + mock_env(), + mock_info(SENDER, &[]), + ExecuteMsg::VerifyMessages { + messages: messages.clone(), + }, + ) + .unwrap(); + + let statuses: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetMessagesStatus { @@ -513,49 +557,41 @@ mod test { .unwrap(); assert_eq!( statuses, - messages - .iter() - .map(|message| (message.cc_id.clone(), VerificationStatus::InProgress)) - .collect::>() + msg_ids_and_statuses(messages.clone(), VerificationStatus::InProgress) ); + } - let msg = ExecuteMsg::Vote { - poll_id: Uint64::one().into(), - votes: (0..messages.len()) - .map(|i| { - if i % 2 == 0 { - Vote::SucceededOnChain - } else { - Vote::NotFound - } - }) - .collect::>(), - }; + #[test] + fn should_query_status_failed_to_verify_when_no_consensus_and_poll_ended() { + let workers = workers(2); + let mut deps = setup(workers.clone()); - workers().iter().for_each(|worker| { - execute( - deps.as_mut(), - mock_env(), - mock_info(worker.address.as_str(), &[]), - msg.clone(), - ) - .unwrap(); - }); + let messages = messages(10); - let msg = ExecuteMsg::EndPoll { - poll_id: Uint64::one().into(), - }; + // starts verification process + execute( + deps.as_mut(), + mock_env(), + mock_info(SENDER, &[]), + ExecuteMsg::VerifyMessages { + messages: messages.clone(), + }, + ) + .unwrap(); + // end poll execute( deps.as_mut(), mock_env_expired(), mock_info(SENDER, &[]), - msg, + ExecuteMsg::EndPoll { + poll_id: Uint64::one().into(), + }, ) .unwrap(); - let statuses: Vec<(CrossChainId, VerificationStatus)> = from_json( - query( + let statuses: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetMessagesStatus { @@ -565,27 +601,84 @@ mod test { .unwrap(), ) .unwrap(); - assert_eq!( statuses, - messages - .iter() - .enumerate() - .map(|(i, message)| ( - message.cc_id.clone(), - if i % 2 == 0 { - VerificationStatus::SucceededOnChain - } else { - VerificationStatus::NotFound - } - )) - .collect::>() + msg_ids_and_statuses(messages.clone(), VerificationStatus::FailedToVerify) ); } + #[test] + fn should_query_status_according_to_vote() { + for (consensus_vote, expected_status) in [ + (Vote::SucceededOnChain, VerificationStatus::SucceededOnChain), + (Vote::FailedOnChain, VerificationStatus::FailedOnChain), + (Vote::NotFound, VerificationStatus::NotFound), + ] { + let workers = workers(2); + let mut deps = setup(workers.clone()); + + let messages = messages(10); + + // starts verification process + execute( + deps.as_mut(), + mock_env(), + mock_info(SENDER, &[]), + ExecuteMsg::VerifyMessages { + messages: messages.clone(), + }, + ) + .unwrap(); + + // all workers vote + let vote_msg = ExecuteMsg::Vote { + poll_id: Uint64::one().into(), + votes: vec![consensus_vote; messages.len()], + }; + workers.iter().for_each(|worker| { + execute( + deps.as_mut(), + mock_env(), + mock_info(worker.address.as_str(), &[]), + vote_msg.clone(), + ) + .unwrap(); + }); + + // end poll + execute( + deps.as_mut(), + mock_env_expired(), + mock_info(SENDER, &[]), + ExecuteMsg::EndPoll { + poll_id: Uint64::one().into(), + }, + ) + .unwrap(); + + // check status corresponds to votes + let statuses: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( + deps.as_ref(), + mock_env(), + QueryMsg::GetMessagesStatus { + messages: messages.clone(), + }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!( + statuses, + msg_ids_and_statuses(messages.clone(), expected_status) + ); + } + } + #[test] fn should_start_worker_set_confirmation() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let operators = Operators::new(vec![(vec![0, 1, 0, 1].into(), 1u64.into())], 1u64.into()); let msg = ExecuteMsg::VerifyWorkerSet { @@ -595,8 +688,8 @@ mod test { let res = execute(deps.as_mut(), mock_env(), mock_info(SENDER, &[]), msg); assert!(res.is_ok()); - let res: VerificationStatus = from_json( - query( + let res: VerificationStatus = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetWorkerSetStatus { @@ -611,7 +704,8 @@ mod test { #[test] fn should_confirm_worker_set() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let operators = Operators::new(vec![(vec![0, 1, 0, 1].into(), 1u64.into())], 1u64.into()); let msg = ExecuteMsg::VerifyWorkerSet { @@ -625,7 +719,7 @@ mod test { poll_id: 1u64.into(), votes: vec![Vote::SucceededOnChain], }; - for worker in workers() { + for worker in workers { let res = execute( deps.as_mut(), mock_env(), @@ -645,8 +739,8 @@ mod test { ); assert!(res.is_ok()); - let res: VerificationStatus = from_json( - query( + let res: VerificationStatus = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetWorkerSetStatus { @@ -661,7 +755,8 @@ mod test { #[test] fn should_not_confirm_worker_set() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let operators = Operators::new(vec![(vec![0, 1, 0, 1].into(), 1u64.into())], 1u64.into()); let res = execute( @@ -675,7 +770,7 @@ mod test { ); assert!(res.is_ok()); - for worker in workers() { + for worker in workers { let res = execute( deps.as_mut(), mock_env(), @@ -698,8 +793,8 @@ mod test { ); assert!(res.is_ok()); - let res: VerificationStatus = from_json( - query( + let res: VerificationStatus = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetWorkerSetStatus { @@ -714,9 +809,8 @@ mod test { #[test] fn should_confirm_worker_set_after_failed() { - let mut deps = setup(); - - let workers = workers(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let operators = Operators::new(vec![(vec![0, 1, 0, 1].into(), 1u64.into())], 1u64.into()); let res = execute( @@ -753,8 +847,8 @@ mod test { ); assert!(res.is_ok()); - let res: VerificationStatus = from_json( - query( + let res: VerificationStatus = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetWorkerSetStatus { @@ -800,8 +894,8 @@ mod test { ); assert!(res.is_ok()); - let res: VerificationStatus = from_json( - query( + let res: VerificationStatus = from_binary( + &query( deps.as_ref(), mock_env(), QueryMsg::GetWorkerSetStatus { @@ -816,7 +910,8 @@ mod test { #[test] fn should_not_confirm_twice() { - let mut deps = setup(); + let workers = workers(2); + let mut deps = setup(workers.clone()); let operators = Operators::new(vec![(vec![0, 1, 0, 1].into(), 1u64.into())], 1u64.into()); let res = execute( @@ -829,8 +924,7 @@ mod test { }, ); assert!(res.is_ok()); - - for worker in workers() { + for worker in workers { let res = execute( deps.as_mut(), mock_env(), @@ -853,8 +947,8 @@ mod test { ); assert!(res.is_ok()); - // try again, should fail - let err = execute( + // try again, should return empty response + let res = execute( deps.as_mut(), mock_env_expired(), mock_info(SENDER, &[]), @@ -863,7 +957,214 @@ mod test { new_operators: operators.clone(), }, ) - .unwrap_err(); - assert_contract_err_strings_equal(err, ContractError::WorkerSetAlreadyConfirmed); + .unwrap(); + assert_eq!(res, Response::new()); + } + + #[test] + fn should_be_able_to_update_threshold_and_then_query_new_threshold() { + let workers = workers(2); + let mut deps = setup(workers.clone()); + + let new_voting_threshold: MajorityThreshold = Threshold::try_from(( + initial_voting_threshold().numerator().u64() + 1, + initial_voting_threshold().denominator().u64() + 1, + )) + .unwrap() + .try_into() + .unwrap(); + + execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE, &[]), + ExecuteMsg::UpdateVotingThreshold { + new_voting_threshold, + }, + ) + .unwrap(); + + let res = query(deps.as_ref(), mock_env(), QueryMsg::GetCurrentThreshold).unwrap(); + + let threshold: MajorityThreshold = from_binary(&res).unwrap(); + assert_eq!(threshold, new_voting_threshold); + } + + #[test] + fn threshold_changes_should_not_affect_existing_polls() { + let workers = workers(10); + let initial_threshold = initial_voting_threshold(); + let majority = (workers.len() as u64 * initial_threshold.numerator().u64()) + .div_ceil(initial_threshold.denominator().u64()); + + let mut deps = setup(workers.clone()); + + let messages = messages(1); + + execute( + deps.as_mut(), + mock_env(), + mock_info(SENDER, &[]), + ExecuteMsg::VerifyMessages { + messages: messages.clone(), + }, + ) + .unwrap(); + + // simulate a majority of workers voting for succeeded on chain + workers.iter().enumerate().for_each(|(i, worker)| { + if i >= majority as usize { + return; + } + let msg = ExecuteMsg::Vote { + poll_id: 1u64.into(), + votes: vec![Vote::SucceededOnChain], + }; + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(worker.address.as_str(), &[]), + msg, + ); + assert!(res.is_ok()); + }); + + // increase the threshold. Not enough workers voted to meet the new majority, + // but threshold changes should not affect existing polls + let new_voting_threshold: MajorityThreshold = + Threshold::try_from((majority + 1, workers.len() as u64)) + .unwrap() + .try_into() + .unwrap(); + + execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE, &[]), + ExecuteMsg::UpdateVotingThreshold { + new_voting_threshold, + }, + ) + .unwrap(); + + execute( + deps.as_mut(), + mock_env_expired(), + mock_info(SENDER, &[]), + ExecuteMsg::EndPoll { + poll_id: 1u64.into(), + }, + ) + .unwrap(); + + let res: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( + deps.as_ref(), + mock_env(), + QueryMsg::GetMessagesStatus { + messages: messages.clone(), + }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!( + res, + vec![( + messages[0].cc_id.clone(), + VerificationStatus::SucceededOnChain + )] + ); + } + + #[test] + fn threshold_changes_should_affect_new_polls() { + let workers = workers(10); + let initial_threshold = initial_voting_threshold(); + let old_majority = (workers.len() as u64 * initial_threshold.numerator().u64()) + .div_ceil(initial_threshold.denominator().u64()); + + let mut deps = setup(workers.clone()); + + // increase the threshold prior to starting a poll + let new_voting_threshold: MajorityThreshold = + Threshold::try_from((old_majority + 1, workers.len() as u64)) + .unwrap() + .try_into() + .unwrap(); + + execute( + deps.as_mut(), + mock_env(), + mock_info(GOVERNANCE, &[]), + ExecuteMsg::UpdateVotingThreshold { + new_voting_threshold, + }, + ) + .unwrap(); + + let messages = messages(1); + + // start the poll, should just the new threshold + execute( + deps.as_mut(), + mock_env(), + mock_info(SENDER, &[]), + ExecuteMsg::VerifyMessages { + messages: messages.clone(), + }, + ) + .unwrap(); + + // simulate old_majority of workers voting succeeded on chain, + // which is one less than the updated majority. The messages + // should not receive enough votes to be considered verified + workers.iter().enumerate().for_each(|(i, worker)| { + if i >= old_majority as usize { + return; + } + let msg = ExecuteMsg::Vote { + poll_id: 1u64.into(), + votes: vec![Vote::SucceededOnChain], + }; + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info(worker.address.as_str(), &[]), + msg, + ); + assert!(res.is_ok()); + }); + + execute( + deps.as_mut(), + mock_env_expired(), + mock_info(SENDER, &[]), + ExecuteMsg::EndPoll { + poll_id: 1u64.into(), + }, + ) + .unwrap(); + + let res: Vec<(CrossChainId, VerificationStatus)> = from_binary( + &query( + deps.as_ref(), + mock_env(), + QueryMsg::GetMessagesStatus { + messages: messages.clone(), + }, + ) + .unwrap(), + ) + .unwrap(); + assert_eq!( + res, + vec![( + messages[0].cc_id.clone(), + VerificationStatus::FailedToVerify + )] + ); } } diff --git a/contracts/voting-verifier/src/error.rs b/contracts/voting-verifier/src/error.rs index 42d5c3a00..c94b2f019 100644 --- a/contracts/voting-verifier/src/error.rs +++ b/contracts/voting-verifier/src/error.rs @@ -37,8 +37,8 @@ pub enum ContractError { #[error(transparent)] VoteError(#[from] voting::Error), - #[error("worker set already confirmed")] - WorkerSetAlreadyConfirmed, + #[error("unauthorized")] + Unauthorized, } impl From for StdError { diff --git a/contracts/voting-verifier/src/execute.rs b/contracts/voting-verifier/src/execute.rs index ee07eb564..87c2913fd 100644 --- a/contracts/voting-verifier/src/execute.rs +++ b/contracts/voting-verifier/src/execute.rs @@ -1,5 +1,5 @@ use cosmwasm_std::{ - to_json_binary, Deps, DepsMut, Env, MessageInfo, OverflowError, OverflowOperation, + to_binary, Addr, Deps, DepsMut, Env, MessageInfo, OverflowError, OverflowOperation, QueryRequest, Response, Storage, WasmMsg, WasmQuery, }; @@ -8,7 +8,7 @@ use axelar_wasm_std::{ operators::Operators, snapshot, voting::{PollId, Vote, WeightedPoll}, - VerificationStatus, + MajorityThreshold, VerificationStatus, }; use connection_router_api::{ChainName, Message}; @@ -17,12 +17,32 @@ use service_registry::{msg::QueryMsg, state::WeightedWorker}; use crate::events::{ PollEnded, PollMetadata, PollStarted, TxEventConfirmation, Voted, WorkerSetConfirmation, }; -use crate::msg::{EndPollResponse, VerifyMessagesResponse}; use crate::query::worker_set_status; use crate::state::{self, Poll, PollContent, POLL_MESSAGES, POLL_WORKER_SETS}; use crate::state::{CONFIG, POLLS, POLL_ID}; use crate::{error::ContractError, query::message_status}; +// TODO: this type of function exists in many contracts. Would be better to implement this +// in one place, and then just include it +pub fn require_governance(deps: &DepsMut, sender: Addr) -> Result<(), ContractError> { + let config = CONFIG.load(deps.storage)?; + if config.governance != sender { + return Err(ContractError::Unauthorized); + } + Ok(()) +} + +pub fn update_voting_threshold( + deps: DepsMut, + new_voting_threshold: MajorityThreshold, +) -> Result { + CONFIG.update(deps.storage, |mut config| -> Result<_, ContractError> { + config.voting_threshold = new_voting_threshold; + Ok(config) + })?; + Ok(Response::new()) +} + pub fn verify_worker_set( deps: DepsMut, env: Env, @@ -31,7 +51,7 @@ pub fn verify_worker_set( ) -> Result { let status = worker_set_status(deps.as_ref(), &new_operators)?; if status.is_confirmed() { - return Err(ContractError::WorkerSetAlreadyConfirmed); + return Ok(Response::new()); } let config = CONFIG.load(deps.storage)?; @@ -88,13 +108,6 @@ pub fn verify_messages( .map(|message| message_status(deps.as_ref(), &message).map(|status| (status, message))) .collect::, _>>()?; - let response = Response::new().set_data(to_json_binary(&VerifyMessagesResponse { - verification_statuses: messages - .iter() - .map(|(status, message)| (message.cc_id.to_owned(), status.to_owned())) - .collect(), - })?); - let msgs_to_verify: Vec = messages .into_iter() .filter_map(|(status, message)| match status { @@ -108,7 +121,7 @@ pub fn verify_messages( .collect(); if msgs_to_verify.is_empty() { - return Ok(response); + return Ok(Response::new()); } let snapshot = take_snapshot(deps.as_ref(), &msgs_to_verify[0].cc_id.chain)?; @@ -130,7 +143,7 @@ pub fn verify_messages( .map(TryInto::try_into) .collect::, _>>()?; - Ok(response.add_event( + Ok(Response::new().add_event( PollStarted::Messages { messages, metadata: PollMetadata { @@ -192,7 +205,7 @@ pub fn end_poll(deps: DepsMut, env: Env, poll_id: PollId) -> Result Result Result { @@ -229,7 +239,7 @@ fn take_snapshot(deps: Deps, chain: &ChainName) -> Result = deps.querier.query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: config.service_registry_contract.to_string(), - msg: to_json_binary(&active_workers_query)?, + msg: to_binary(&active_workers_query)?, }))?; let participants = workers @@ -276,3 +286,51 @@ fn calculate_expiration(block_height: u64, block_expiry: u64) -> Result Config { + Config { + governance, + service_registry_contract: Addr::unchecked("doesn't matter"), + service_name: "validators".to_string().try_into().unwrap(), + source_gateway_address: "0x89e51fA8CA5D66cd220bAed62ED01e8951aa7c40" + .to_string() + .try_into() + .unwrap(), + voting_threshold, + source_chain: "ethereum".to_string().try_into().unwrap(), + block_expiry: 10, + confirmation_height: 2, + rewards_contract: Addr::unchecked("rewards"), + } + } + + #[test] + fn require_governance_should_reject_non_governance() { + let mut deps = mock_dependencies(); + let governance = Addr::unchecked("governance"); + CONFIG + .save( + deps.as_mut().storage, + &mock_config( + governance.clone(), + Threshold::try_from((2, 3)).unwrap().try_into().unwrap(), + ), + ) + .unwrap(); + + let res = require_governance(&deps.as_mut(), Addr::unchecked("random")); + assert!(res.is_err()); + + let res = require_governance(&deps.as_mut(), governance); + assert!(res.is_ok()); + } +} diff --git a/contracts/voting-verifier/src/msg.rs b/contracts/voting-verifier/src/msg.rs index c1e228414..7cc078a9e 100644 --- a/contracts/voting-verifier/src/msg.rs +++ b/contracts/voting-verifier/src/msg.rs @@ -3,14 +3,16 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; use axelar_wasm_std::{ nonempty, operators::Operators, - voting::{PollId, PollState, Vote}, + voting::{PollId, Vote}, MajorityThreshold, VerificationStatus, }; use connection_router_api::{ChainName, CrossChainId, Message}; #[cw_serde] pub struct InstantiateMsg { - // params to query register service + pub governance_address: nonempty::String, + + // params to query service_registry pub service_registry_address: nonempty::String, pub service_name: nonempty::String, @@ -47,6 +49,11 @@ pub enum ExecuteMsg { message_id: nonempty::String, new_operators: Operators, }, + + // Update the threshold used for new polls. Callable only by governance + UpdateVotingThreshold { + new_voting_threshold: MajorityThreshold, + }, } #[cw_serde] @@ -66,14 +73,7 @@ pub enum QueryMsg { #[returns(VerificationStatus)] GetWorkerSetStatus { new_operators: Operators }, -} -#[cw_serde] -pub struct VerifyMessagesResponse { - pub verification_statuses: Vec<(CrossChainId, VerificationStatus)>, -} - -#[cw_serde] -pub struct EndPollResponse { - pub poll_result: PollState, + #[returns(MajorityThreshold)] + GetCurrentThreshold, } diff --git a/contracts/voting-verifier/src/query.rs b/contracts/voting-verifier/src/query.rs index ca61ccde2..972a2c3c3 100644 --- a/contracts/voting-verifier/src/query.rs +++ b/contracts/voting-verifier/src/query.rs @@ -1,13 +1,17 @@ use axelar_wasm_std::{ operators::Operators, voting::{PollStatus, Vote}, - VerificationStatus, + MajorityThreshold, VerificationStatus, }; use connection_router_api::{CrossChainId, Message}; use cosmwasm_std::Deps; -use crate::error::ContractError; use crate::state::{self, Poll, PollContent, POLLS, POLL_MESSAGES, POLL_WORKER_SETS}; +use crate::{error::ContractError, state::CONFIG}; + +pub fn voting_threshold(deps: Deps) -> Result { + Ok(CONFIG.load(deps.storage)?.voting_threshold) +} pub fn messages_status( deps: Deps, diff --git a/contracts/voting-verifier/src/state.rs b/contracts/voting-verifier/src/state.rs index fe6e333d3..42ef1ede9 100644 --- a/contracts/voting-verifier/src/state.rs +++ b/contracts/voting-verifier/src/state.rs @@ -16,6 +16,7 @@ use crate::error::ContractError; #[cw_serde] pub struct Config { + pub governance: Addr, pub service_registry_contract: Addr, pub service_name: nonempty::String, pub source_gateway_address: nonempty::String, diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index 4b251f229..787424aea 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -29,32 +29,24 @@ optimize = """docker run --rm -v "$(pwd)":/code \ """ [dependencies] -aggregate-verifier = { workspace = true, features = ["library"] } axelar-wasm-std = { workspace = true } -axelar-wasm-std-derive = { workspace = true } connection-router = { workspace = true } connection-router-api = { workspace = true } -cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-multi-test = "0.15.1" -cw-storage-plus = { workspace = true } error-stack = { workspace = true } gateway = { workspace = true } gateway-api = { workspace = true } -itertools = { workspace = true } k256 = { version = "0.13.1", features = ["ecdsa"] } -mockall = "0.11.3" +monitoring = { workspace = true } multisig = { workspace = true } multisig-prover = { workspace = true } report = { workspace = true } rewards = { workspace = true } -schemars = "0.8.10" -serde = { version = "1.0.145", default-features = false, features = ["derive"] } -serde_json = "1.0.89" +serde = { workspace = true } +serde_json = { workspace = true } service-registry = { workspace = true } sha3 = { workspace = true } -thiserror = { workspace = true } tofn = { git = "https://github.com/axelarnetwork/tofn.git", branch = "update-deps" } voting-verifier = { workspace = true } diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index f9192b121..05de894a3 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -1,6 +1,7 @@ pub mod connection_router_contract; pub mod contract; pub mod gateway_contract; +pub mod monitoring_contract; pub mod multisig_contract; pub mod multisig_prover_contract; pub mod protocol; diff --git a/integration-tests/src/monitoring_contract.rs b/integration-tests/src/monitoring_contract.rs new file mode 100644 index 000000000..9ce96f7d1 --- /dev/null +++ b/integration-tests/src/monitoring_contract.rs @@ -0,0 +1,40 @@ +use crate::contract::Contract; +use cosmwasm_std::Addr; +use cw_multi_test::{App, ContractWrapper, Executor}; +use monitoring::contract::{execute, instantiate, query}; + +#[derive(Clone)] +pub struct MonitoringContract { + pub contract_addr: Addr, +} + +impl MonitoringContract { + pub fn instantiate_contract(app: &mut App, governance: Addr) -> Self { + let code = ContractWrapper::new(execute, instantiate, query); + let code_id = app.store_code(Box::new(code)); + + let contract_addr = app + .instantiate_contract( + code_id, + Addr::unchecked("anyone"), + &monitoring::msg::InstantiateMsg { + governance_address: governance.to_string(), + }, + &[], + "monitoring", + None, + ) + .unwrap(); + + MonitoringContract { contract_addr } + } +} + +impl Contract for MonitoringContract { + type QMsg = monitoring::msg::QueryMsg; + type ExMsg = monitoring::msg::ExecuteMsg; + + fn contract_address(&self) -> Addr { + self.contract_addr.clone() + } +} diff --git a/integration-tests/src/multisig_prover_contract.rs b/integration-tests/src/multisig_prover_contract.rs index c59bcc1a9..07db92953 100644 --- a/integration-tests/src/multisig_prover_contract.rs +++ b/integration-tests/src/multisig_prover_contract.rs @@ -37,6 +37,7 @@ impl MultisigProverContract { governance_address: protocol.governance_address.to_string(), gateway_address: gateway_address.to_string(), multisig_address: protocol.multisig.contract_addr.to_string(), + monitoring_address: protocol.monitoring.contract_addr.to_string(), service_registry_address: protocol.service_registry.contract_addr.to_string(), voting_verifier_address: voting_verifier_address.to_string(), destination_chain_id: Uint256::zero(), diff --git a/integration-tests/src/protocol.rs b/integration-tests/src/protocol.rs index c3a79a493..f504117d1 100644 --- a/integration-tests/src/protocol.rs +++ b/integration-tests/src/protocol.rs @@ -3,8 +3,9 @@ use cosmwasm_std::Addr; use cw_multi_test::App; use crate::{ - connection_router_contract::ConnectionRouterContract, multisig_contract::MultisigContract, - rewards_contract::RewardsContract, service_registry_contract::ServiceRegistryContract, + connection_router_contract::ConnectionRouterContract, monitoring_contract::MonitoringContract, + multisig_contract::MultisigContract, rewards_contract::RewardsContract, + service_registry_contract::ServiceRegistryContract, }; pub struct Protocol { @@ -13,6 +14,7 @@ pub struct Protocol { pub connection_router: ConnectionRouterContract, pub router_admin_address: Addr, pub multisig: MultisigContract, + pub monitoring: MonitoringContract, pub service_registry: ServiceRegistryContract, pub service_name: nonempty::String, pub rewards: RewardsContract, diff --git a/integration-tests/src/voting_verifier_contract.rs b/integration-tests/src/voting_verifier_contract.rs index 9d061a23e..31805430c 100644 --- a/integration-tests/src/voting_verifier_contract.rs +++ b/integration-tests/src/voting_verifier_contract.rs @@ -1,9 +1,10 @@ use crate::contract::Contract; +use crate::protocol::Protocol; use axelar_wasm_std::nonempty; use axelar_wasm_std::MajorityThreshold; use connection_router_api::ChainName; use cosmwasm_std::Addr; -use cw_multi_test::{App, ContractWrapper, Executor}; +use cw_multi_test::{ContractWrapper, Executor}; #[derive(Clone)] pub struct VotingVerifierContract { @@ -12,19 +13,17 @@ pub struct VotingVerifierContract { impl VotingVerifierContract { pub fn instantiate_contract( - app: &mut App, - service_registry_address: nonempty::String, - service_name: nonempty::String, + protocol: &mut Protocol, source_gateway_address: nonempty::String, voting_threshold: MajorityThreshold, source_chain: ChainName, - rewards_address: Addr, ) -> Self { let code = ContractWrapper::new( voting_verifier::contract::execute, voting_verifier::contract::instantiate, voting_verifier::contract::query, ); + let app = &mut protocol.app; let code_id = app.store_code(Box::new(code)); let contract_addr = app @@ -32,14 +31,20 @@ impl VotingVerifierContract { code_id, Addr::unchecked("anyone"), &voting_verifier::msg::InstantiateMsg { - service_registry_address, - service_name, + governance_address: protocol.governance_address.to_string().try_into().unwrap(), + service_registry_address: protocol + .service_registry + .contract_addr + .to_string() + .try_into() + .unwrap(), + service_name: protocol.service_name.clone(), source_gateway_address, voting_threshold, block_expiry: 10, confirmation_height: 5, source_chain, - rewards_address: rewards_address.to_string(), + rewards_address: protocol.rewards.contract_addr.to_string(), }, &[], "voting_verifier", diff --git a/integration-tests/tests/chain_freeze_unfreeze.rs b/integration-tests/tests/chain_freeze_unfreeze.rs new file mode 100644 index 000000000..94c122935 --- /dev/null +++ b/integration-tests/tests/chain_freeze_unfreeze.rs @@ -0,0 +1,93 @@ +use cosmwasm_std::{Addr, HexBinary}; + +use connection_router_api::{CrossChainId, Message}; +use integration_tests::contract::Contract; + +pub mod test_utils; + +// Tests that a chain can be frozen and unfrozen +#[test] +fn chain_can_be_freezed_unfreezed() { + let (mut protocol, chain1, chain2, workers, _) = test_utils::setup_test_case(); + + let msgs = vec![Message { + cc_id: CrossChainId { + chain: chain1.chain_name.clone(), + id: "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3" + .to_string() + .try_into() + .unwrap(), + }, + source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" + .to_string() + .try_into() + .unwrap(), + destination_address: "0xce16F69375520ab01377ce7B88f5BA8C48F8D666" + .to_string() + .try_into() + .unwrap(), + destination_chain: chain2.chain_name.clone(), + payload_hash: HexBinary::from_hex( + "3e50a012285f8e7ec59b558179cd546c55c477ebe16202aac7d7747e25be03be", + ) + .unwrap() + .as_slice() + .try_into() + .unwrap(), + }]; + let msg_ids: Vec = msgs.iter().map(|msg| msg.cc_id.clone()).collect(); + + // start the flow by submitting the message to the gateway + let (poll_id, expiry) = test_utils::verify_messages(&mut protocol.app, &chain1.gateway, &msgs); + + // do voting + test_utils::vote_success_for_all_messages( + &mut protocol.app, + &chain1.voting_verifier, + &msgs, + &workers, + poll_id, + ); + + test_utils::advance_at_least_to_height(&mut protocol.app, expiry); + + test_utils::end_poll(&mut protocol.app, &chain1.voting_verifier, poll_id); + + test_utils::route_messages(&mut protocol.app, &chain1.gateway, &msgs); + + test_utils::freeze_chain( + &mut protocol.app, + &protocol.connection_router, + &chain1.chain_name, + connection_router_api::GatewayDirection::Bidirectional, + &protocol.router_admin_address, + ); + + let response = chain1.gateway.execute( + &mut protocol.app, + Addr::unchecked("relayer"), + &gateway_api::msg::ExecuteMsg::RouteMessages(msgs.to_vec()), + ); + test_utils::assert_contract_err_strings_equal( + response.unwrap_err(), + connection_router_api::error::Error::ChainFrozen { + chain: chain1.chain_name.clone(), + }, + ); + + test_utils::unfreeze_chain( + &mut protocol.app, + &protocol.connection_router, + &chain1.chain_name, + connection_router_api::GatewayDirection::Bidirectional, + &protocol.router_admin_address, + ); + + // routed message should have been preserved + let found_msgs = + test_utils::get_messages_from_gateway(&mut protocol.app, &chain2.gateway, &msg_ids); + assert_eq!(found_msgs, msgs); + + // can route again + test_utils::route_messages(&mut protocol.app, &chain1.gateway, &msgs); +} diff --git a/integration-tests/tests/message_routing.rs b/integration-tests/tests/message_routing.rs index e61425c36..8954f9df3 100644 --- a/integration-tests/tests/message_routing.rs +++ b/integration-tests/tests/message_routing.rs @@ -1,6 +1,7 @@ -use cosmwasm_std::{HexBinary, Uint128}; +use cosmwasm_std::{Addr, HexBinary, Uint128}; use connection_router_api::{CrossChainId, Message}; +use integration_tests::contract::Contract; use crate::test_utils::AXL_DENOMINATION; @@ -109,3 +110,52 @@ fn single_message_can_be_verified_and_routed_and_proven_and_rewards_are_distribu assert_eq!(balance.amount, expected_rewards); } } + +#[test] +fn routing_to_incorrect_gateway_interface() { + let (mut protocol, chain1, chain2, _, _) = test_utils::setup_test_case(); + + let msgs = vec![Message { + cc_id: CrossChainId { + chain: chain1.chain_name.clone(), + id: "0x88d7956fd7b6fcec846548d83bd25727f2585b4be3add21438ae9fbb34625924-3" + .to_string() + .try_into() + .unwrap(), + }, + source_address: "0xBf12773B49()0e1Deb57039061AAcFA2A87DEaC9b9" + .to_string() + .try_into() + .unwrap(), + destination_address: "0xce16F69375520ab01377ce7B88f5BA8C48F8D666" + .to_string() + .try_into() + .unwrap(), + destination_chain: chain2.chain_name.clone(), + payload_hash: HexBinary::from_hex( + "3e50a012285f8e7ec59b558179cd546c55c477ebe16202aac7d7747e25be03be", + ) + .unwrap() + .as_slice() + .try_into() + .unwrap(), + }]; + + test_utils::upgrade_gateway( + &mut protocol.app, + &protocol.connection_router, + &protocol.governance_address, + &chain2.chain_name, + Addr::unchecked("some random address") + .to_string() + .try_into() + .unwrap(), // gateway address does not implement required interface, + ); + + let response = protocol.connection_router.execute( + &mut protocol.app, + chain1.gateway.contract_addr.clone(), + &connection_router_api::msg::ExecuteMsg::RouteMessages(msgs.to_vec()), + ); + assert!(response.is_err()) +} diff --git a/integration-tests/tests/test_utils/mod.rs b/integration-tests/tests/test_utils/mod.rs index 0282ff4e9..4502dafda 100644 --- a/integration-tests/tests/test_utils/mod.rs +++ b/integration-tests/tests/test_utils/mod.rs @@ -3,7 +3,7 @@ use axelar_wasm_std::{ voting::{PollId, Vote}, Participant, Threshold, }; -use connection_router_api::{ChainName, CrossChainId, Message}; +use connection_router_api::{Address, ChainName, CrossChainId, GatewayDirection, Message}; use cosmwasm_std::{ coins, Addr, Attribute, BlockInfo, Event, HexBinary, StdError, Uint128, Uint256, Uint64, }; @@ -11,6 +11,7 @@ use cw_multi_test::{App, AppResponse, Executor}; use integration_tests::contract::Contract; use integration_tests::gateway_contract::GatewayContract; +use integration_tests::monitoring_contract::MonitoringContract; use integration_tests::multisig_contract::MultisigContract; use integration_tests::multisig_prover_contract::MultisigProverContract; use integration_tests::rewards_contract::RewardsContract; @@ -81,6 +82,60 @@ pub fn route_messages(app: &mut App, gateway: &GatewayContract, msgs: &[Message] assert!(response.is_ok()); } +pub fn freeze_chain( + app: &mut App, + router: &ConnectionRouterContract, + chain_name: &ChainName, + direction: GatewayDirection, + admin: &Addr, +) { + let response = router.execute( + app, + admin.clone(), + &connection_router_api::msg::ExecuteMsg::FreezeChain { + chain: chain_name.clone(), + direction, + }, + ); + assert!(response.is_ok(), "{:?}", response); +} + +pub fn unfreeze_chain( + app: &mut App, + router: &ConnectionRouterContract, + chain_name: &ChainName, + direction: GatewayDirection, + admin: &Addr, +) { + let response = router.execute( + app, + admin.clone(), + &connection_router_api::msg::ExecuteMsg::UnfreezeChain { + chain: chain_name.clone(), + direction, + }, + ); + assert!(response.is_ok(), "{:?}", response); +} + +pub fn upgrade_gateway( + app: &mut App, + router: &ConnectionRouterContract, + governance: &Addr, + chain_name: &ChainName, + contract_address: Address, +) { + let response = router.execute( + app, + governance.clone(), + &connection_router_api::msg::ExecuteMsg::UpgradeGateway { + chain: chain_name.clone(), + contract_address, + }, + ); + assert!(response.is_ok(), "{:?}", response); +} + pub fn vote_success_for_all_messages( app: &mut App, voting_verifier: &VotingVerifierContract, @@ -148,14 +203,17 @@ pub fn construct_proof_and_sign( sign_proof(protocol, workers, response.unwrap()) } +pub fn get_multisig_session_id(response: AppResponse) -> Uint64 { + get_event_attribute(&response.events, "wasm-signing_started", "session_id") + .map(|attr| attr.value.as_str().try_into().unwrap()) + .expect("couldn't get session_id") +} + pub fn sign_proof(protocol: &mut Protocol, workers: &Vec, response: AppResponse) -> Uint64 { let msg_to_sign = get_event_attribute(&response.events, "wasm-signing_started", "msg") .map(|attr| attr.value.clone()) .expect("couldn't find message to sign"); - let session_id: Uint64 = - get_event_attribute(&response.events, "wasm-signing_started", "session_id") - .map(|attr| attr.value.as_str().try_into().unwrap()) - .expect("couldn't get session_id"); + let session_id = get_multisig_session_id(response); for worker in workers { let signature = tofn::ecdsa::sign( @@ -318,6 +376,8 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { SIGNATURE_BLOCK_EXPIRY, ); + let monitoring = MonitoringContract::instantiate_contract(&mut app, governance_address.clone()); + let service_registry = ServiceRegistryContract::instantiate_contract(&mut app, governance_address.clone()); @@ -327,6 +387,7 @@ pub fn setup_protocol(service_name: nonempty::String) -> Protocol { connection_router, router_admin_address, multisig, + monitoring, service_registry, service_name, rewards, @@ -593,18 +654,10 @@ pub struct Chain { pub fn setup_chain(protocol: &mut Protocol, chain_name: ChainName) -> Chain { let voting_verifier = VotingVerifierContract::instantiate_contract( - &mut protocol.app, - protocol - .service_registry - .contract_addr - .to_string() - .try_into() - .unwrap(), - protocol.service_name.clone(), + protocol, "doesn't matter".to_string().try_into().unwrap(), Threshold::try_from((9, 10)).unwrap().try_into().unwrap(), chain_name.clone(), - protocol.rewards.contract_addr.clone(), ); let gateway = GatewayContract::instantiate_contract( @@ -709,3 +762,10 @@ pub fn setup_test_case() -> (Protocol, Chain, Chain, Vec, Uint128) { let chain2 = setup_chain(&mut protocol, chains.get(1).unwrap().clone()); (protocol, chain1, chain2, workers, min_worker_bond) } + +pub fn assert_contract_err_strings_equal( + actual: impl Into, + expected: impl Into, +) { + assert_eq!(actual.into().to_string(), expected.into().to_string()); +} diff --git a/integration-tests/tests/update_worker_set.rs b/integration-tests/tests/update_worker_set.rs index c63199b2f..b2f26dbe0 100644 --- a/integration-tests/tests/update_worker_set.rs +++ b/integration-tests/tests/update_worker_set.rs @@ -4,6 +4,8 @@ use cw_multi_test::Executor; use integration_tests::contract::Contract; use test_utils::Worker; +use crate::test_utils::get_multisig_session_id; + pub mod test_utils; #[test] @@ -115,6 +117,9 @@ fn worker_set_cannot_be_updated_again_while_pending_worker_is_not_yet_confirmed( vec![("worker3".to_string(), 2), ("worker4".to_string(), 3)], ); + let expected_new_worker_set = + test_utils::workers_to_worker_set(&mut protocol, &first_wave_of_new_workers); + test_utils::register_workers(&mut protocol, &first_wave_of_new_workers, min_worker_bond); // Deregister old workers @@ -158,10 +163,123 @@ fn worker_set_cannot_be_updated_again_while_pending_worker_is_not_yet_confirmed( // Deregister old workers test_utils::deregister_workers(&mut protocol, &first_wave_of_new_workers); + // call update_worker_set again. This should just trigger resigning for the initial worker set update, + // ignoring any further changes to the worker set let response = ethereum.multisig_prover.execute( &mut protocol.app, - Addr::unchecked("relayer"), + ethereum.multisig_prover.admin_addr.clone(), &multisig_prover::msg::ExecuteMsg::UpdateWorkerSet, ); + assert!(response.is_ok()); + + test_utils::confirm_worker_set( + &mut protocol.app, + ethereum.multisig_prover.admin_addr.clone(), + ðereum.multisig_prover, + ); + + let new_worker_set = test_utils::get_worker_set(&mut protocol.app, ðereum.multisig_prover); + + assert_eq!(new_worker_set, expected_new_worker_set); + + // starting and ending a poll for the second worker rotation + // in reality, this shouldn't succeed, because the prover should have prevented another rotation while an existing rotation was in progress. + // But even if there is a poll, the prover should ignore it + test_utils::execute_worker_set_poll( + &mut protocol, + &Addr::unchecked("relayer"), + ðereum.voting_verifier, + &second_wave_of_new_workers, + ); + + let response = ethereum.multisig_prover.execute( + &mut protocol.app, + ethereum.multisig_prover.admin_addr.clone(), + &multisig_prover::msg::ExecuteMsg::ConfirmWorkerSet, + ); assert!(response.is_err()); } + +#[test] +fn worker_set_update_can_be_resigned() { + let chains = vec![ + "Ethereum".to_string().try_into().unwrap(), + "Polygon".to_string().try_into().unwrap(), + ]; + let (mut protocol, ethereum, _, initial_workers, min_worker_bond) = + test_utils::setup_test_case(); + + let simulated_worker_set = test_utils::workers_to_worker_set(&mut protocol, &initial_workers); + + let worker_set = test_utils::get_worker_set(&mut protocol.app, ðereum.multisig_prover); + + assert_eq!(worker_set, simulated_worker_set); + + // creating a new worker set that only consists of two new workers + let first_wave_of_new_workers = test_utils::create_new_workers_vec( + chains.clone(), + vec![("worker3".to_string(), 2), ("worker4".to_string(), 3)], + ); + + test_utils::register_workers(&mut protocol, &first_wave_of_new_workers, min_worker_bond); + + // Deregister old workers + test_utils::deregister_workers(&mut protocol, &initial_workers); + + let response = protocol + .app + .execute_contract( + ethereum.multisig_prover.admin_addr.clone(), + ethereum.multisig_prover.contract_addr.clone(), + &multisig_prover::msg::ExecuteMsg::UpdateWorkerSet, + &[], + ) + .unwrap(); + + let first_session_id = get_multisig_session_id(response.clone()); + + // signing didn't occur, trigger signing again + let response = protocol + .app + .execute_contract( + ethereum.multisig_prover.admin_addr.clone(), + ethereum.multisig_prover.contract_addr.clone(), + &multisig_prover::msg::ExecuteMsg::UpdateWorkerSet, + &[], + ) + .unwrap(); + + let second_session_id = get_multisig_session_id(response.clone()); + assert_ne!(first_session_id, second_session_id); + + test_utils::sign_proof(&mut protocol, &initial_workers, response); + + // signing did occur, trigger signing again (in case proof was lost) + let response = protocol + .app + .execute_contract( + ethereum.multisig_prover.admin_addr.clone(), + ethereum.multisig_prover.contract_addr.clone(), + &multisig_prover::msg::ExecuteMsg::UpdateWorkerSet, + &[], + ) + .unwrap(); + + let third_session_id = get_multisig_session_id(response.clone()); + assert_ne!(first_session_id, second_session_id); + assert_ne!(second_session_id, third_session_id); + + test_utils::sign_proof(&mut protocol, &initial_workers, response); + + let proof = test_utils::get_proof( + &mut protocol.app, + ðereum.multisig_prover, + &second_session_id, + ); + + // proof must be completed + assert!(matches!( + proof.status, + multisig_prover::msg::ProofStatus::Completed { .. } + )); +} diff --git a/packages/axelar-wasm-std/Cargo.toml b/packages/axelar-wasm-std/Cargo.toml index ccad58344..32169afc6 100644 --- a/packages/axelar-wasm-std/Cargo.toml +++ b/packages/axelar-wasm-std/Cargo.toml @@ -31,11 +31,12 @@ optimize = """docker run --rm -v "$(pwd)":/code \ [dependencies] cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } +lazy_static = "1.4.0" num-traits = { workspace = true } +regex = { version = "1.10.0", default-features = false, features = ["perf", "std"] } report = { workspace = true } schemars = "0.8.10" serde = { version = "1.0.145", default-features = false, features = ["derive"] } diff --git a/packages/axelar-wasm-std/src/lib.rs b/packages/axelar-wasm-std/src/lib.rs index d6fb35755..2f0aacb72 100644 --- a/packages/axelar-wasm-std/src/lib.rs +++ b/packages/axelar-wasm-std/src/lib.rs @@ -13,6 +13,7 @@ pub mod flagset; mod fn_ext; pub mod hash; pub mod hex; +pub mod msg_id; pub mod nonempty; pub mod operators; pub mod snapshot; diff --git a/packages/axelar-wasm-std/src/msg_id/mod.rs b/packages/axelar-wasm-std/src/msg_id/mod.rs new file mode 100644 index 000000000..c12108c32 --- /dev/null +++ b/packages/axelar-wasm-std/src/msg_id/mod.rs @@ -0,0 +1,47 @@ +use std::{fmt::Display, str::FromStr}; + +use cosmwasm_schema::cw_serde; +use error_stack::Report; + +use self::tx_hash_event_index::HexTxHashAndEventIndex; + +pub mod tx_hash_event_index; + +#[derive(thiserror::Error)] +#[cw_serde] +pub enum Error { + #[error("invalid message id '{id}', expected format: {expected_format}")] + InvalidMessageID { id: String, expected_format: String }, + #[error("event index in message id '{0}' is larger than u32 max value")] + EventIndexOverflow(String), + #[error("invalid transaction hash in message id '{0}'")] + InvalidTxHash(String), +} + +/// Any message id format must implement this trait. +/// The implementation must satisfy the following invariants: +/// +/// * if m1 != m2 then from_str(m1) != from_str(m2) (two different strings cannot parse to the same message id) +/// +/// * if t1 != t2 then to_string(t1) != to_string(t2) (two different message ids cannot serialize to the same string) +/// +/// There should be only one string that can identify a given message. +/// Take extra care to handle things like leading 0s, casing, etc. +pub trait MessageId: FromStr + Display {} + +/// enum to pass to the router when registering a new chain +#[cw_serde] +pub enum MessageIdFormat { + HexTxHashAndEventIndex, + Base58TxDigestAndEventIndex, +} + +// function the router calls to verify msg ids +pub fn verify_msg_id(message_id: &str, format: &MessageIdFormat) -> Result<(), Report> { + match format { + MessageIdFormat::HexTxHashAndEventIndex => { + HexTxHashAndEventIndex::from_str(message_id).map(|_| ()) + } + MessageIdFormat::Base58TxDigestAndEventIndex => todo!(), + } +} diff --git a/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs b/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs new file mode 100644 index 000000000..25215f92d --- /dev/null +++ b/packages/axelar-wasm-std/src/msg_id/tx_hash_event_index.rs @@ -0,0 +1,199 @@ +use core::fmt; +use std::{fmt::Display, str::FromStr}; + +use cosmwasm_std::HexBinary; +use error_stack::{Report, ResultExt}; +use lazy_static::lazy_static; +use regex::Regex; + +use super::Error; +use crate::{hash::Hash, nonempty}; + +pub struct HexTxHashAndEventIndex { + pub tx_hash: Hash, + pub event_index: u32, +} + +impl HexTxHashAndEventIndex { + pub fn tx_hash_as_hex(&self) -> nonempty::String { + format!("0x{}", HexBinary::from(self.tx_hash).to_hex()) + .try_into() + .expect("failed to convert tx hash to non-empty string") + } +} + +const PATTERN: &str = "^(0x[0-9a-f]{64})-(0|[1-9][0-9]*)$"; +lazy_static! { + static ref REGEX: Regex = Regex::new(PATTERN).expect("invalid regex"); +} + +impl FromStr for HexTxHashAndEventIndex { + type Err = Report; + + fn from_str(message_id: &str) -> Result + where + Self: Sized, + { + // the PATTERN has exactly two capture groups, so the groups can be extracted safely + let (_, [tx_id, event_index]) = REGEX + .captures(message_id) + .ok_or(Error::InvalidMessageID { + id: message_id.to_string(), + expected_format: PATTERN.to_string(), + })? + .extract(); + Ok(HexTxHashAndEventIndex { + tx_hash: HexBinary::from_hex(&tx_id[2..]) + .change_context(Error::InvalidTxHash(message_id.to_string()))? + .as_slice() + .try_into() + .map_err(|_| Error::InvalidTxHash(message_id.to_string()))?, + event_index: event_index + .parse() + .map_err(|_| Error::EventIndexOverflow(message_id.to_string()))?, + }) + } +} + +impl Display for HexTxHashAndEventIndex { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "0x{}-{}", + HexBinary::from(self.tx_hash).to_hex(), + self.event_index + ) + } +} + +#[cfg(test)] +mod tests { + + use super::*; + + fn random_hash() -> String { + let mut bytes = vec![]; + for _ in 0..32 { + let byte: u8 = rand::random(); + bytes.push(byte) + } + format!("0x{}", HexBinary::from(bytes).to_hex()) + } + + fn random_event_index() -> u32 { + rand::random() + } + + #[test] + fn should_parse_msg_id() { + let res = HexTxHashAndEventIndex::from_str( + "0x7cedbb3799cd99636045c84c5c55aef8a138f107ac8ba53a08cad1070ba4385b-0", + ); + assert!(res.is_ok()); + + for _ in 0..1000 { + let tx_hash = random_hash(); + let event_index = random_event_index(); + let msg_id = format!("{}-{}", tx_hash, event_index); + + let res = HexTxHashAndEventIndex::from_str(&msg_id); + let parsed = res.unwrap(); + assert_eq!(parsed.event_index, event_index); + assert_eq!(parsed.tx_hash_as_hex(), tx_hash.try_into().unwrap(),); + assert_eq!(parsed.to_string(), msg_id); + } + } + + #[test] + fn should_not_parse_msg_id_with_wrong_length_tx_hash() { + let tx_hash = random_hash(); + let res = HexTxHashAndEventIndex::from_str(&format!("{}ff-{}", tx_hash, 1)); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_uppercase_tx_hash() { + let tx_hash = &random_hash()[2..]; + let res = HexTxHashAndEventIndex::from_str(&format!("0x{}-{}", tx_hash.to_uppercase(), 1)); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_non_hex_tx_hash() { + let msg_id = "82GKYvWv5EKm7jnYksHoh3u5M2RxHN2boPreM8Df4ej9-1"; + let res = HexTxHashAndEventIndex::from_str(msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_without_0x() { + let msg_id = "7cedbb3799cd99636045c84c5c55aef8a138f107ac8ba53a08cad1070ba4385b-1"; + let res = HexTxHashAndEventIndex::from_str(msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_missing_event_index() { + let msg_id = random_hash(); + let res = HexTxHashAndEventIndex::from_str(&msg_id); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_wrong_separator() { + let tx_hash = random_hash(); + let event_index = random_event_index(); + let res = HexTxHashAndEventIndex::from_str(&format!("{}:{}", tx_hash, event_index)); + assert!(res.is_err()); + let res = HexTxHashAndEventIndex::from_str(&format!("{}_{}", tx_hash, event_index)); + assert!(res.is_err()); + let res = HexTxHashAndEventIndex::from_str(&format!("{}+{}", tx_hash, event_index)); + assert!(res.is_err()); + + for _ in 0..10 { + let random_sep: char = rand::random(); + if random_sep == '-' { + continue; + } + let res = HexTxHashAndEventIndex::from_str(&format!( + "{}{}{}", + tx_hash, random_sep, event_index + )); + assert!(res.is_err()); + } + } + + #[test] + fn should_not_parse_msg_id_with_event_index_with_leading_zeroes() { + let tx_hash = random_hash(); + let res = HexTxHashAndEventIndex::from_str(&format!("{}-01", tx_hash)); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_non_integer_event_index() { + let tx_hash = random_hash(); + let res = HexTxHashAndEventIndex::from_str(&format!("{}-1.0", tx_hash)); + assert!(res.is_err()); + + let res = HexTxHashAndEventIndex::from_str(&format!("{}-0x00", tx_hash)); + assert!(res.is_err()); + + let res = HexTxHashAndEventIndex::from_str(&format!("{}-foobar", tx_hash)); + assert!(res.is_err()); + + let res = HexTxHashAndEventIndex::from_str(&format!("{}-true", tx_hash)); + assert!(res.is_err()); + + let res = HexTxHashAndEventIndex::from_str(&format!("{}-", tx_hash)); + assert!(res.is_err()); + } + + #[test] + fn should_not_parse_msg_id_with_overflowing_event_index() { + let event_index: u64 = u64::MAX; + let tx_hash = random_hash(); + let res = HexTxHashAndEventIndex::from_str(&format!("{}-{}", tx_hash, event_index)); + assert!(res.is_err()); + } +} diff --git a/packages/axelar-wasm-std/src/operators.rs b/packages/axelar-wasm-std/src/operators.rs index 37c0a87e7..ec58163c7 100644 --- a/packages/axelar-wasm-std/src/operators.rs +++ b/packages/axelar-wasm-std/src/operators.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::cw_serde; -use cosmwasm_std::{to_json_binary, HexBinary, Uint256}; +use cosmwasm_std::{to_binary, HexBinary, Uint256}; use sha3::{Digest, Keccak256}; @@ -24,8 +24,7 @@ impl Operators { pub fn hash(&self) -> Hash { let mut hasher = Keccak256::new(); hasher.update( - to_json_binary(&self.weights_by_addresses) - .expect("could not serialize serializable object"), + to_binary(&self.weights_by_addresses).expect("could not serialize serializable object"), ); hasher.update(self.threshold.to_be_bytes()); hasher.finalize().into() diff --git a/packages/axelar-wasm-std/src/snapshot.rs b/packages/axelar-wasm-std/src/snapshot.rs index 56e67f4fa..d267a1e9d 100644 --- a/packages/axelar-wasm-std/src/snapshot.rs +++ b/packages/axelar-wasm-std/src/snapshot.rs @@ -65,7 +65,7 @@ impl Snapshot { #[cfg(test)] mod tests { - use cosmwasm_std::{from_json, to_json_binary, Uint64}; + use cosmwasm_std::{from_binary, to_binary, Uint64}; use crate::Threshold; @@ -133,8 +133,8 @@ mod tests { default_participants(), ); - let serialized = to_json_binary(&snapshot).unwrap(); - let deserialized: Snapshot = from_json(serialized).unwrap(); + let serialized = to_binary(&snapshot).unwrap(); + let deserialized: Snapshot = from_binary(&serialized).unwrap(); assert_eq!(snapshot, deserialized); } diff --git a/packages/client/Cargo.toml b/packages/client/Cargo.toml new file mode 100644 index 000000000..8cd9ca5c1 --- /dev/null +++ b/packages/client/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "client" +version = "0.1.0" +edition = "2021" +rust-version = { workspace = true } +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cosmwasm-std = { workspace = true } +error-stack = { workspace = true } +serde = { workspace = true } +thiserror = { workspace = true } + +[lints] +workspace = true diff --git a/packages/client/src/lib.rs b/packages/client/src/lib.rs new file mode 100644 index 000000000..ed6c03477 --- /dev/null +++ b/packages/client/src/lib.rs @@ -0,0 +1,57 @@ +use std::marker::PhantomData; + +use cosmwasm_std::{to_binary, Addr, QuerierWrapper, QueryRequest, WasmMsg, WasmQuery}; +use error_stack::{Result, ResultExt}; +use serde::{de::DeserializeOwned, Serialize}; + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("could not query the contract")] + Query, +} + +pub struct Client<'a, M, Q> +where + M: Serialize, + Q: Serialize, +{ + pub querier: QuerierWrapper<'a>, + pub address: Addr, + execute_msg_type: PhantomData, + query_msg_type: PhantomData, +} + +impl<'a, M, Q> Client<'a, M, Q> +where + M: Serialize, + Q: Serialize, +{ + pub fn new(querier: QuerierWrapper<'a>, address: Addr) -> Self { + Client { + querier, + address, + execute_msg_type: PhantomData, + query_msg_type: PhantomData, + } + } + + pub fn execute(&self, msg: &M) -> WasmMsg { + WasmMsg::Execute { + contract_addr: self.address.to_string(), + msg: to_binary(msg).expect("msg should always be serializable"), + funds: vec![], + } + } + + pub fn query(&self, msg: &Q) -> Result + where + R: DeserializeOwned, + { + self.querier + .query(&QueryRequest::Wasm(WasmQuery::Smart { + contract_addr: self.address.to_string(), + msg: to_binary(msg).expect("msg should always be serializable"), + })) + .change_context(Error::Query) + } +} diff --git a/packages/connection-router-api/Cargo.toml b/packages/connection-router-api/Cargo.toml index 470270374..b5618ee9c 100644 --- a/packages/connection-router-api/Cargo.toml +++ b/packages/connection-router-api/Cargo.toml @@ -13,7 +13,6 @@ cosmwasm-std = { workspace = true } cw-storage-plus = { workspace = true } error-stack = { workspace = true } flagset = { version = "0.4.3", features = ["serde"] } -regex = "1.10.0" report = { workspace = true } schemars = { workspace = true } serde = { workspace = true } diff --git a/packages/connection-router-api/src/client.rs b/packages/connection-router-api/src/client.rs index e756a318d..a0a8cad01 100644 --- a/packages/connection-router-api/src/client.rs +++ b/packages/connection-router-api/src/client.rs @@ -1,4 +1,4 @@ -use cosmwasm_std::{to_json_binary, Addr, WasmMsg}; +use cosmwasm_std::{to_binary, Addr, WasmMsg}; use crate::msg::ExecuteMsg; use crate::Message; @@ -11,7 +11,7 @@ impl Router { fn execute(&self, msg: &ExecuteMsg) -> WasmMsg { WasmMsg::Execute { contract_addr: self.address.to_string(), - msg: to_json_binary(&msg).expect("msg should always be serializable"), + msg: to_binary(&msg).expect("msg should always be serializable"), funds: vec![], } } diff --git a/packages/connection-router-api/src/msg.rs b/packages/connection-router-api/src/msg.rs index 6ea3259b1..0a00a3bf6 100644 --- a/packages/connection-router-api/src/msg.rs +++ b/packages/connection-router-api/src/msg.rs @@ -48,4 +48,14 @@ pub enum ExecuteMsg { pub enum QueryMsg { #[returns(ChainEndpoint)] GetChainInfo(ChainName), + + // Returns a list of chains registered with the router + // The list is paginated by: + // - start_after: the chain name to start after, which the next page of results should start. + // - limit: limit the number of chains returned, default is u32::MAX. + #[returns(Vec)] + Chains { + start_after: Option, + limit: Option, + }, } diff --git a/packages/connection-router-api/src/primitives.rs b/packages/connection-router-api/src/primitives.rs index 0b4791ae1..4f7505d35 100644 --- a/packages/connection-router-api/src/primitives.rs +++ b/packages/connection-router-api/src/primitives.rs @@ -277,7 +277,7 @@ impl ChainEndpoint { mod tests { use super::*; - use cosmwasm_std::to_json_vec; + use cosmwasm_std::to_vec; use rand::distributions::Alphanumeric; use rand::{thread_rng, Rng}; use sha3::{Digest, Sha3_256}; @@ -292,7 +292,7 @@ mod tests { let msg = dummy_message(); assert_eq!( - hex::encode(Sha3_256::digest(to_json_vec(&msg).unwrap())), + hex::encode(Sha3_256::digest(to_vec(&msg).unwrap())), expected_message_hash ); } diff --git a/packages/signature-verifier-api/Cargo.toml b/packages/signature-verifier-api/Cargo.toml index 032f49ee2..1602a84e2 100644 --- a/packages/signature-verifier-api/Cargo.toml +++ b/packages/signature-verifier-api/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" [dependencies] cosmwasm-schema = { workspace = true } cosmwasm-std = { workspace = true } -cosmwasm-storage = { workspace = true } error-stack = { workspace = true } thiserror = { workspace = true } diff --git a/packages/signature-verifier-api/src/client.rs b/packages/signature-verifier-api/src/client.rs index 14851c740..3b549ee89 100644 --- a/packages/signature-verifier-api/src/client.rs +++ b/packages/signature-verifier-api/src/client.rs @@ -1,7 +1,5 @@ use cosmwasm_schema::serde::de::DeserializeOwned; -use cosmwasm_std::{ - to_json_binary, Addr, HexBinary, QuerierWrapper, QueryRequest, Uint64, WasmQuery, -}; +use cosmwasm_std::{to_binary, Addr, HexBinary, QuerierWrapper, QueryRequest, Uint64, WasmQuery}; use error_stack::{Result, ResultExt}; use crate::msg::QueryMsg; @@ -16,7 +14,7 @@ impl SignatureVerifier<'_> { self.querier .query(&QueryRequest::Wasm(WasmQuery::Smart { contract_addr: self.address.to_string(), - msg: to_json_binary(msg).expect("msg should always be serializable"), + msg: to_binary(msg).expect("msg should always be serializable"), })) .change_context(Error::QuerySignatureVerifier) }