diff --git a/.github/workflows/benchmarking.yml b/.github/workflows/benchmarking.yml index a2674db30..10490c0e1 100644 --- a/.github/workflows/benchmarking.yml +++ b/.github/workflows/benchmarking.yml @@ -22,7 +22,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -30,7 +30,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-benchmarking-rust:1.60.0-{{ checksum "Cargo.lock" }} + key: cargocache-v2-benchmarking-rust:1.70.0-{{ checksum "Cargo.lock" }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Run vm benchmarks (Singlepass) @@ -51,7 +51,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -59,7 +59,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_crypto-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_crypto-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build @@ -80,7 +80,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -88,7 +88,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_vm-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_vm-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1d50ccbda..a432811b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -33,7 +33,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 270563179..bcdc2355d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -51,13 +51,13 @@ jobs: if: ${{ steps.get_version.outputs.version != steps.get_latest_tag.outputs.tag }} run: | echo "Building all contracts under ./contracts" - docker run --volumes-from with_code cosmwasm/rust-optimizer:0.12.9 ./contracts/*/ + docker run --volumes-from with_code cosmwasm/rust-optimizer:0.12.13 ./contracts/*/ - name: Check development contracts if: ${{ steps.get_version.outputs.version != steps.get_latest_tag.outputs.tag }} working-directory: ./ run: | echo "Checking all contracts under ./artifacts" - docker run --volumes-from with_code rust:1.60.0 /bin/bash -e -c 'cd ./code/packages/check; export GLOBIGNORE=../../artifacts/floaty.wasm; cargo run ../../artifacts/*.wasm' + docker run --volumes-from with_code rust:1.70.0 /bin/bash -e -c 'cd ./code/packages/check; export GLOBIGNORE=../../artifacts/floaty.wasm; cargo run ../../artifacts/*.wasm' docker cp with_code:/code/artifacts . - name: Create Release diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 5544c9486..cdddf3f1f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -19,7 +19,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -27,7 +27,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_crypto-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_crypto-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build @@ -48,7 +48,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -56,7 +56,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_derive-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_derive-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build @@ -77,7 +77,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -85,7 +85,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_schema-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_schema-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build @@ -106,7 +106,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -114,7 +114,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_std-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_std-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -137,17 +137,6 @@ jobs: - name: Run unit tests (all features) working-directory: ${{env.working-directory}} run: cargo test --locked --features iterator,staking,stargate - - name: Build and run schema generator - working-directory: ${{env.working-directory}} - run: cargo schema --locked - - name: Ensure schemas are up-to-date - run: | - CHANGES_IN_REPO=$(git status --porcelain) - if [[ -n "$CHANGES_IN_REPO" ]]; then - echo "Repository is dirty. Showing 'git status' and 'git --no-pager diff' for debugging now:" - git status && git --no-pager diff - exit 1 - fi package_storage: name: package_storage @@ -160,7 +149,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -168,7 +157,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_storage-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_storage-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build library for native target @@ -192,7 +181,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -200,7 +189,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-package_vm-rust:1.60.0-${{ hashFiles('Cargo.lock') }} + key: cargocache-v2-package_vm-rust:1.70.0-${{ hashFiles('Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Build @@ -227,7 +216,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -235,7 +224,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_burner-rust:1.60.0-${{ hashFiles('contracts/burner/Cargo.lock') }} + key: cargocache-v2-contract_burner-rust:1.70.0-${{ hashFiles('contracts/burner/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -273,7 +262,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -281,7 +270,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_crypto_verify-rust:1.60.0-${{ hashFiles('contracts/crypto-verify/Cargo.lock') }} + key: cargocache-v2-contract_crypto_verify-rust:1.70.0-${{ hashFiles('contracts/crypto-verify/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -319,7 +308,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -327,7 +316,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_hackatom-rust:1.60.0-${{ hashFiles('contracts/hackatom/Cargo.lock') }} + key: cargocache-v2-contract_hackatom-rust:1.70.0-${{ hashFiles('contracts/hackatom/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -365,7 +354,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -373,7 +362,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_ibc_reflect-rust:1.60.0-${{ hashFiles('contracts/ibc-reflect/Cargo.lock') }} + key: cargocache-v2-contract_ibc_reflect-rust:1.70.0-${{ hashFiles('contracts/ibc-reflect/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -411,7 +400,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -419,7 +408,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_ibc_reflect_send-rust:1.60.0-${{ hashFiles('contracts/ibc-reflect-send/Cargo.lock') }} + key: cargocache-v2-contract_ibc_reflect_send-rust:1.70.0-${{ hashFiles('contracts/ibc-reflect-send/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -457,7 +446,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -465,7 +454,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_queue-rust:1.60.0-${{ hashFiles('contracts/queue/Cargo.lock') }} + key: cargocache-v2-contract_queue-rust:1.70.0-${{ hashFiles('contracts/queue/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -504,7 +493,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -512,7 +501,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_query_queue-rust:1.60.0-${{ hashFiles('contracts/queue/Cargo.lock', 'contracts/query-queue/Cargo.lock') }} + key: cargocache-v2-contract_query_queue-rust:1.70.0-${{ hashFiles('contracts/queue/Cargo.lock', 'contracts/query-queue/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -553,7 +542,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -561,7 +550,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_reflect-rust:1.60.0-${{ hashFiles('contracts/reflect/Cargo.lock') }} + key: cargocache-v2-contract_reflect-rust:1.70.0-${{ hashFiles('contracts/reflect/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -599,7 +588,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -607,7 +596,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_staking-rust:1.60.0-${{ hashFiles('contracts/staking/Cargo.lock') }} + key: cargocache-v2-contract_staking-rust:1.70.0-${{ hashFiles('contracts/staking/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -645,7 +634,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -653,7 +642,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-contract_staking-rust:1.60.0-${{ hashFiles('contracts/voting-with-uuid/Cargo.lock') }} + key: cargocache-v2-contract_staking-rust:1.70.0-${{ hashFiles('contracts/voting-with-uuid/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add wasm32 target @@ -691,7 +680,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -699,7 +688,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-fmt-rust:1.60.0-${{ hashFiles('Cargo.lock', 'contracts/*/Cargo.lock') }} + key: cargocache-v2-fmt-rust:1.70.0-${{ hashFiles('Cargo.lock', 'contracts/*/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add rustfmt component @@ -743,7 +732,7 @@ jobs: - name: Install Rust uses: actions-rs/toolchain@v1 with: - toolchain: 1.60.0 + toolchain: 1.70.0 target: wasm32-unknown-unknown profile: minimal override: true @@ -751,7 +740,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cargo - key: cargocache-v2-clippy-rust:1.60.0-${{ hashFiles('Cargo.lock', 'contracts/*/Cargo.lock') }} + key: cargocache-v2-clippy-rust:1.70.0-${{ hashFiles('Cargo.lock', 'contracts/*/Cargo.lock') }} - name: Version information run: rustc --version; cargo --version; rustup --version; rustup target list --installed - name: Add clippy component diff --git a/.gitignore b/.gitignore index b0ea61c7f..6f20a8ecd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,6 @@ target/ artifacts/ # IDEs -.vscode/ .idea/ *.iml diff --git a/.mergify.yml b/.mergify.yml index b4bc4cfda..4bb3f061d 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -6,30 +6,50 @@ pull_request_rules: - "#approved-reviews-by>=1" - base=main - label=automerge + - -draft - label!=WIP - # We need to list them all individually. Here is why: https://doc.mergify.io/conditions.html#validating-all-status-check - - "status-success=ci/circleci: package_crypto" - - "status-success=ci/circleci: package_schema" - - "status-success=ci/circleci: package_std" - - "status-success=ci/circleci: package_storage" - - "status-success=ci/circleci: package_ext" - - "status-success=ci/circleci: package_vm" + # We need to list them all individually. Here is why: https://docs.mergify.com/conditions/#validating-all-status-checks + # Also make sure to update this when the CI names change + - "status-success=macOS" + - "status-success=Windows" + - "status-success=ci/circleci: arm64" + - "status-success=ci/circleci: clippy-1.67.0" + - "status-success=ci/circleci: clippy-1.68.2" - "status-success=ci/circleci: contract_burner" - "status-success=ci/circleci: contract_crypto_verify" + - "status-success=ci/circleci: contract_cyberpunk" + - "status-success=ci/circleci: contract_floaty" + - "status-success=ci/circleci: contract_hackatom" - "status-success=ci/circleci: contract_hackatom" - "status-success=ci/circleci: contract_ibc_reflect" - "status-success=ci/circleci: contract_ibc_reflect_send" - - "status-success=ci/circleci: contract_floaty" - "status-success=ci/circleci: contract_queue" - "status-success=ci/circleci: contract_reflect" - "status-success=ci/circleci: contract_staking" - - "status-success=ci/circleci: contract_token_tester" - - "status-success=ci/circleci: contract_collection_tester" + - "status-success=ci/circleci: contract_virus" + # disabled temporarily because Rust version is too low + # - "status-success=ci/circleci: coverage" - "status-success=ci/circleci: fmt" - - "status-success=ci/circleci: clippy-1.54.0" - - "status-success=ci/circleci: clippy-1.58.1" - - "status-success=Windows" - - "status-success=macOS" + - "status-success=ci/circleci: fmt_extra" + - "status-success=ci/circleci: package_check" + - "status-success=ci/circleci: package_crypto" + - "status-success=ci/circleci: package_schema" + - "status-success=ci/circleci: package_schema_derive" + - "status-success=ci/circleci: package_std" + - "status-success=ci/circleci: package_storage" + - "status-success=ci/circleci: package_vm" + - "status-success=ci/circleci: package_vm_windows" actions: merge: method: merge + - name: backport PRs to minor version branch + conditions: + - base=main + - label=backport + actions: + backport: + branches: + # Update this when going to a new minor version + - "release/1.4" + assignees: + - "{{ author }}" diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..a9e08224c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "rust-analyzer.cargo.features": [ + "abort", + "stargate", + "staking", + "cosmwasm_1_4" + ] +} diff --git a/Cargo.lock b/Cargo.lock index a41a2363a..02e6cb366 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,23 @@ # 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.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,9 +29,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -29,19 +39,100 @@ dependencies = [ ] [[package]] -name = "ansi_term" -version = "0.12.1" +name = "aho-corasick" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ - "winapi", + "memchr", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle 1.0.4", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +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 = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle 1.0.4", + "windows-sys 0.48.0", ] [[package]] name = "anyhow" -version = "1.0.66" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "assert_cmd" +version = "2.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0b2340f55d9661d76793b2bfc2eb0e62689bd79d067a95707ea762afd5e9dd" +dependencies = [ + "anstyle 0.3.5", + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] [[package]] name = "atty" @@ -49,7 +140,7 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", "winapi", ] @@ -62,36 +153,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -99,6 +190,24 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -110,20 +219,25 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bstr" -version = "0.2.17" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +checksum = "c79ad7fb2dd38f3dabd76b09c6a5a20c038fc0213ef1e9afd30eb777f120f019" dependencies = [ - "lazy_static", "memchr", "regex-automata", "serde", @@ -131,36 +245,43 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cast" @@ -170,9 +291,12 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -182,51 +306,116 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ - "num-integer", "num-traits", ] +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "clap" -version = "2.34.0" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", + "bitflags 1.3.2", + "clap_lex 0.2.4", + "indexmap", "textwrap", - "unicode-width", - "vec_map", ] +[[package]] +name = "clap" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +dependencies = [ + "anstream", + "anstyle 1.0.4", + "clap_lex 0.6.0", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + [[package]] name = "clru" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + [[package]] name = "colored" -version = "2.0.0" +version = "2.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" +checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ - "atty", + "is-terminal", "lazy_static", - "winapi", + "windows-sys 0.48.0", ] [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -236,15 +425,15 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", "libc", "scopeguard", - "windows-sys", + "windows-sys 0.33.0", ] [[package]] @@ -252,19 +441,20 @@ name = "cosmwasm-check" version = "1.1.9+0.8.1" dependencies = [ "anyhow", - "clap", + "assert_cmd", + "clap 4.4.7", "colored", "cosmwasm-std", "cosmwasm-vm", + "predicates", ] [[package]] name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "base64", "criterion", - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "english-numbers", "hex", @@ -274,7 +464,7 @@ dependencies = [ "serde", "serde_json", "sha-1", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", ] @@ -286,7 +476,7 @@ dependencies = [ "cosmwasm-std", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -295,6 +485,7 @@ version = "1.1.9+0.8.1" dependencies = [ "anyhow", "cosmwasm-schema-derive", + "cosmwasm-std", "schemars", "semver", "serde", @@ -309,7 +500,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -317,10 +508,12 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "chrono", "cosmwasm-crypto", "cosmwasm-derive", "cosmwasm-schema", + "crc32fast", "derivative", "forward_ref", "hex", @@ -328,8 +521,9 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "serde_json", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] @@ -345,24 +539,27 @@ dependencies = [ name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytecheck", - "clap", + "bytes", + "clap 4.4.7", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", "criterion", + "derivative", "enumset", + "glob", "hex", "hex-literal", "leb128", - "loupe", - "parity-wasm", "rand", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", + "target-lexicon", "tempfile", "thiserror", "wasmer", @@ -372,65 +569,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -438,6 +653,12 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + [[package]] name = "crc32fast" version = "1.3.2" @@ -449,16 +670,17 @@ dependencies = [ [[package]] name = "criterion" -version = "0.3.6" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" dependencies = [ + "anes", "atty", "cast", - "clap", + "ciborium", + "clap 3.2.25", "criterion-plot", - "csv", - "itertools", + "itertools 0.10.5", "lazy_static", "num-traits", "oorandom", @@ -466,7 +688,6 @@ dependencies = [ "rayon", "regex", "serde", - "serde_cbor", "serde_derive", "serde_json", "tinytemplate", @@ -475,29 +696,19 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ "cast", - "itertools", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" -dependencies = [ - "cfg-if", - "crossbeam-utils", + "itertools 0.10.5", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -506,37 +717,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -554,28 +759,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.8", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - [[package]] name = "curve25519-dalek" version = "3.2.0" @@ -591,9 +774,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -601,33 +784,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -641,9 +837,15 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] +[[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" @@ -655,20 +857,27 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -676,13 +885,13 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "byteorder", "lazy_static", "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -698,14 +907,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -725,20 +936,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -772,28 +982,38 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -804,50 +1024,81 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.8.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", ] +[[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.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -867,15 +1118,33 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" + +[[package]] +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "go-gen" +version = "0.1.0" +dependencies = [ + "Inflector", + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "indenter", + "schemars", +] [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", @@ -890,21 +1159,18 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hermit-abi" @@ -915,6 +1181,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + [[package]] name = "hex" version = "0.4.3" @@ -933,7 +1205,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -942,24 +1214,41 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] -name = "instant" -version = "0.1.12" +name = "is-terminal" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "cfg-if", + "hermit-abi 0.3.3", + "rustix", + "windows-sys 0.48.0", ] [[package]] @@ -972,36 +1261,41 @@ dependencies = [ ] [[package]] -name = "itoa" -version = "0.4.8" +name = "itertools" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -1018,49 +1312,31 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "linux-raw-sys" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] -name = "log" -version = "0.4.17" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", -] - -[[package]] -name = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", + "autocfg", + "scopeguard", ] [[package]] -name = "loupe-derive" -version = "0.1.3" +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -1073,42 +1349,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -1120,60 +1396,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] -name = "num-integer" -version = "0.1.45" +name = "normalize-line-endings" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "oorandom" @@ -1188,22 +1438,41 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "os_str_bytes" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1211,9 +1480,9 @@ dependencies = [ [[package]] name = "plotters" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" dependencies = [ "num-traits", "plotters-backend", @@ -1224,15 +1493,15 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" [[package]] name = "plotters-svg" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" dependencies = [ "plotters-backend", ] @@ -1243,6 +1512,37 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "predicates" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0" +dependencies = [ + "anstyle 1.0.4", + "difflib", + "float-cmp", + "itertools 0.11.0", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1252,7 +1552,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1269,9 +1569,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1293,18 +1593,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" @@ -1343,9 +1649,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1353,56 +1659,63 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] [[package]] name = "regex" -version = "1.7.0" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.1.10" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "region" @@ -1410,89 +1723,84 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", "mach", "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] -name = "rustversion" -version = "1.0.9" +name = "rustix" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "same-file" @@ -1505,9 +1813,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1517,21 +1825,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1541,9 +1849,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1555,56 +1863,48 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.14" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_bytes" -version = "0.11.7" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_cbor" -version = "0.11.2" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ - "half", + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1615,16 +1915,16 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ - "itoa 1.0.4", + "itoa", "ryu", "serde", ] @@ -1663,36 +1963,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1705,81 +2017,94 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "strsim" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] -name = "strsim" -version = "0.8.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.48.0", ] +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + [[package]] name = "textwrap" -version = "0.11.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1792,14 +2117,27 @@ dependencies = [ "serde_json", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1807,69 +2145,83 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" [[package]] -name = "uuid" -version = "1.2.2" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ - "serde", - "sha1_smol", + "form_urlencoded", + "idna", + "percent-encoding", ] [[package]] -name = "vec_map" -version = "0.8.2" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "serde", + "sha1_smol", +] [[package]] name = "version_check" @@ -1877,14 +2229,22 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -1896,9 +2256,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1906,24 +2266,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1931,101 +2314,93 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasm-encoder" -version = "0.20.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05632e0a66a6ed8cca593c24223aabd6262f256c3693ad9822c315285f010614" +checksum = "53ae0be20bf87918df4fa831bfbbd0b491d24aee407ed86360eae4c2c5608d38" dependencies = [ "leb128", ] [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -2037,16 +2412,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -2056,180 +2431,85 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" +dependencies = [ + "indexmap", + "url", +] [[package]] name = "wast" -version = "50.0.0" +version = "67.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2cbb59d4ac799842791fe7e806fa5dbbf6b5554d538e51cc8e176db6ff0ae34" +checksum = "36c2933efd77ff2398b83817a98984ffe4b67aefd9aa1d2c8e68e19b553f1c38" dependencies = [ "leb128", "memchr", @@ -2239,34 +2519,23 @@ dependencies = [ [[package]] name = "wat" -version = "1.0.52" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "584aaf7a1ecf4d383bbe1a25eeab0cbb8ff96acc6796707ff65cde48f4632f15" +checksum = "c02905d13751dcb18f4e19f489d37a1bf139f519feaeef28d072a41a78e69a74" dependencies = [ "wast", ] [[package]] name = "web-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" +checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "which" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" -dependencies = [ - "either", - "libc", - "once_cell", -] - [[package]] name = "winapi" version = "0.3.9" @@ -2285,9 +2554,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -2304,45 +2573,120 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/IBC.md b/IBC.md index 41497bdd4..fcefc92ff 100644 --- a/IBC.md +++ b/IBC.md @@ -264,7 +264,9 @@ pub fn ibc_packet_receive( deps: DepsMut, env: Env, msg: IbcPacketReceiveMsg, -) -> StdResult { } +) -> Result { + // ... +} ``` This is a very special entry point as it has a unique workflow. (Please see the @@ -350,27 +352,33 @@ produced 3 suggestions on how to handle errors and rollbacks _inside [main dispatch loop in `ibc-reflect`](https://github.com/CosmWasm/cosmwasm/blob/cd784cd1148ee395574f3e564f102d0d7b5adcc3/contracts/ibc-reflect/src/contract.rs#L217-L248): ```rust - (|| { - // which local channel did this packet come on - let caller = packet.dest.channel_id; - let msg: PacketMsg = from_slice(&packet.data)?; - match msg { - PacketMsg::Dispatch { msgs } => receive_dispatch(deps, caller, msgs), - PacketMsg::WhoAmI {} => receive_who_am_i(deps, caller), - PacketMsg::Balances {} => receive_balances(deps, caller), - } - })() - .or_else(|e| { - // we try to capture all app-level errors and convert them into - // acknowledgement packets that contain an error code. - let acknowledgement = encode_ibc_error(format!("invalid packet: {}", e)); - Ok(IbcReceiveResponse { - acknowledgement, - submessages: vec![], - messages: vec![], - attributes: vec![], - }) - }) + pub fn ibc_packet_receive( + deps: DepsMut, + _env: Env, + msg: IbcPacketReceiveMsg, + ) -> Result { + (|| { + // which local channel did this packet come on + let caller = packet.dest.channel_id; + let msg: PacketMsg = from_slice(&packet.data)?; + match msg { + PacketMsg::Dispatch { msgs } => receive_dispatch(deps, caller, msgs), + PacketMsg::WhoAmI {} => receive_who_am_i(deps, caller), + PacketMsg::Balances {} => receive_balances(deps, caller), + } + })() + .or_else(|e| { + // we try to capture all app-level errors and convert them into + // acknowledgement packets that contain an error code. + let acknowledgement = encode_ibc_error(format!("invalid packet: {}", e)); + Ok(IbcReceiveResponse { + acknowledgement, + submessages: vec![], + messages: vec![], + attributes: vec![], + }) + }) + } ``` 2. If we modify state with an external call, we need to wrap it in a diff --git a/MIGRATING.md b/MIGRATING.md index b9cadf4b6..d06877b40 100644 --- a/MIGRATING.md +++ b/MIGRATING.md @@ -4,6 +4,101 @@ This guide explains what is needed to upgrade contracts when migrating over major releases of `cosmwasm`. Note that you can also view the [complete CHANGELOG](./CHANGELOG.md) to understand the differences. +## 1.3.x -> 1.4.0 + +- Update `cosmwasm-*` dependencies in Cargo.toml (skip the ones you don't use): + + ``` + [dependencies] + cosmwasm-std = "1.4.0" + cosmwasm-storage = "1.4.0" + # ... + + [dev-dependencies] + cosmwasm-schema = "1.4.0" + cosmwasm-vm = "1.4.0" + # ... + ``` + +- If you want to use a feature that is only available on CosmWasm 1.4+ chains, + use this feature: + + ```diff + -cosmwasm-std = { version = "1.4.0", features = ["stargate"] } + +cosmwasm-std = { version = "1.4.0", features = ["stargate", "cosmwasm_1_4"] } + ``` + + Please note that `cosmwasm_1_2` implies `cosmwasm_1_1`, and `cosmwasm_1_3` + implies `cosmwasm_1_2`, and so on, so there is no need to set multiple. + +## 1.2.x -> 1.3.0 + +- Update `cosmwasm-*` dependencies in Cargo.toml (skip the ones you don't use): + + ``` + [dependencies] + cosmwasm-std = "1.3.0" + cosmwasm-storage = "1.3.0" + # ... + + [dev-dependencies] + cosmwasm-schema = "1.3.0" + cosmwasm-vm = "1.3.0" + # ... + ``` + +- If you want to use a feature that is only available on CosmWasm 1.3+ chains, + use this feature: + + ```diff + -cosmwasm-std = { version = "1.3.0", features = ["stargate"] } + +cosmwasm-std = { version = "1.3.0", features = ["stargate", "cosmwasm_1_3"] } + ``` + + Please note that `cosmwasm_1_2` implies `cosmwasm_1_1`, and `cosmwasm_1_3` + implies `cosmwasm_1_2`, and so on, so there is no need to set multiple. + +## 1.1.x -> 1.2.0 + +- Update `cosmwasm-*` dependencies in Cargo.toml (skip the ones you don't use): + + ``` + [dependencies] + cosmwasm-std = "1.2.0" + cosmwasm-storage = "1.2.0" + # ... + + [dev-dependencies] + cosmwasm-schema = "1.2.0" + cosmwasm-vm = "1.2.0" + # ... + ``` + +- If you want to use a fewture that os only available on CosmWasm 1.2+ chains, + use this feature: + + ```diff + -cosmwasm-std = { version = "1.1.0", features = ["stargate"] } + +cosmwasm-std = { version = "1.1.0", features = ["stargate", "cosmwasm_1_2"] } + ``` + + Please note that `cosmwasm_1_2` implies `cosmwasm_1_1`, so there is no need to + set both. + +- If you use mixed type multiplication between `Uint{64,128,256}` and + `Decimal{,256}`, check out + `mul_floor`/`checked_mul_floor`/`mul_ceil`/`checked_mul_ceil`. Mixed type + arithmetic [will be removed](https://github.com/CosmWasm/cosmwasm/issues/1485) + at some point. + + ```diff + let a = Uint128::new(123); + let b = Decimal::percent(150) + + -let c = a * b; + +let c = a.mul_floor(b); + ``` + ## 1.0.0 -> 1.1.0 - Update `cosmwasm-*` dependencies in Cargo.toml (skip the ones you don't use): diff --git a/contracts/README.md b/contracts/README.md index f8e722104..9cc8aed31 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -4,6 +4,41 @@ Those contracts are made for development purpose only. For more realistic example contracts, see [cosmwasm-examples](https://github.com/CosmWasm/cosmwasm-examples). +## The contracts + +Introducing the development contracts in the order they were created. + +1. **hackatom** is the very first development contract that was created at a + Cosmos Hackatom in Berlin in 2019, the event where CosmWasm was born. It is a + very basic escrow contract. During the years of CosmWasm development, many + more test cases were hacked into it. +2. **queue** shows and tests the newly added iterator support + ([#181](https://github.com/CosmWasm/cosmwasm/pull/181)). +3. **reflect** is an evolution of the + [mask contract](https://medium.com/cosmwasm/introducing-the-mask-41d11e51bccf), + which allows the user to send messages to the contract which are then emitted + with the contract as the sender. It later got support to handle sub messages + and replys ([#796](https://github.com/CosmWasm/cosmwasm/pull/796)). +4. **staking** is a staking derivatives example showing how the contract itself + can be a delegator. +5. **burner** shows how contract migrations work, which were added in CosmWasm + 0.9 ([#413](https://github.com/CosmWasm/cosmwasm/pull/413)). It shuts down + the contract my clearing all state and sending all tokens to a given address. +6. **ibc-reflect**/**ibc-reflect-send** are inspired by the idea of Interchain + Accounts and demonstrate the power of contract to contract IBC. + ibc-reflect-send receives a message on chain A and sends it to an ibc-reflect + instance on chain B where the message is executed. +7. **crypto-verify** shows how to use the CosmWasm crypto APIs for signature + verification ([#783](https://github.com/CosmWasm/cosmwasm/pull/783)). +8. **floaty** emits float operations when compiled to Wasm and allows us to test + how tooling and the runtime deal with those operations + ([#970](https://github.com/CosmWasm/cosmwasm/pull/970)). +9. **cyberpunk** is an attempt to cleanup hackatom and make writing runtime + tests (cosmwasm-vm/wamsmvm) easier by avoid the need for the escrow setup + that hackatom has. +10. **virus** is a contract that reproduces itself and does nothing useful + beyond that, showing how to use instantiate2 from a contract. + ## Optimized builds Those development contracts are used for testing in other repos, e.g. in @@ -18,57 +53,62 @@ reason, use the following commands: docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_burner",target=/code/contracts/burner/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/burner + cosmwasm/rust-optimizer:0.12.13 ./contracts/burner docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_crypto_verify",target=/code/contracts/crypto-verify/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/crypto-verify + cosmwasm/rust-optimizer:0.12.13 ./contracts/crypto-verify docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_floaty",target=/code/contracts/floaty/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/floaty + cosmwasm/rust-optimizer:0.12.13 ./contracts/floaty docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_hackatom",target=/code/contracts/hackatom/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/hackatom + cosmwasm/rust-optimizer:0.12.13 ./contracts/hackatom docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_ibc_reflect",target=/code/contracts/ibc-reflect/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/ibc-reflect + cosmwasm/rust-optimizer:0.12.13 ./contracts/ibc-reflect docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_ibc_reflect_send",target=/code/contracts/ibc-reflect-send/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/ibc-reflect-send + cosmwasm/rust-optimizer:0.12.13 ./contracts/ibc-reflect-send docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_query_queue",target=/code/contracts/query-queue/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/query-queue + cosmwasm/rust-optimizer:0.12.13 ./contracts/query-queue docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_queue",target=/code/contracts/queue/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/queue + cosmwasm/rust-optimizer:0.12.13 ./contracts/queue docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_reflect",target=/code/contracts/reflect/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/reflect + cosmwasm/rust-optimizer:0.12.13 ./contracts/reflect docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_staking",target=/code/contracts/staking/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/staking + cosmwasm/rust-optimizer:0.12.13 ./contracts/staking docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_voting_with_uuid",target=/code/contracts/voting-with-uuid/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/voting-with-uuid + cosmwasm/rust-optimizer:0.12.13 ./contracts/voting-with-uuid + +docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="devcontract_cache_virus",target=/code/contracts/virus/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.13 ./contracts/virus ``` ## Entry points @@ -85,3 +125,4 @@ points in order to demonstrate and test the flexibility we have. | reflect | yes | no | | staking | yes | no | | voting-with-uuid | yes | no | +| virus     | no | no | diff --git a/contracts/burner/.cargo/config b/contracts/burner/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/burner/.cargo/config +++ b/contracts/burner/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/burner/Cargo.lock b/contracts/burner/Cargo.lock index ce142df7c..e8b46cf4e 100644 --- a/contracts/burner/Cargo.lock +++ b/contracts/burner/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,18 +102,24 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "burner" @@ -110,36 +134,46 @@ dependencies = [ [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -155,9 +189,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -167,9 +201,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -182,7 +216,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -197,7 +231,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -217,7 +251,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -225,6 +259,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -233,8 +268,8 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] @@ -244,17 +279,18 @@ version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -262,65 +298,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -329,29 +383,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -360,37 +410,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -423,9 +467,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -433,33 +477,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -473,7 +530,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -487,20 +544,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -514,7 +572,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -530,14 +588,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -557,20 +617,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -598,28 +657,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -628,20 +687,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -653,27 +703,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -693,30 +768,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -727,13 +793,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -747,7 +810,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -757,50 +820,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -817,49 +882,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -872,42 +913,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -918,42 +959,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" -version = "0.28.4" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - -[[package]] -name = "object" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -962,22 +981,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -992,7 +1024,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1009,9 +1041,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1033,18 +1065,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1062,9 +1100,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1072,33 +1110,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1114,89 +1151,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1206,21 +1225,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1230,9 +1249,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1244,40 +1263,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1288,14 +1309,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1336,36 +1357,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1378,22 +1411,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1401,53 +1439,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1455,53 +1498,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1521,9 +1578,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1531,24 +1588,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1556,92 +1636,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1653,16 +1725,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1672,184 +1744,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1880,45 +1846,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/burner/Cargo.toml b/contracts/burner/Cargo.toml index 93a74b7ef..394074b75 100644 --- a/contracts/burner/Cargo.toml +++ b/contracts/burner/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "burner" version = "0.0.0" -authors = ["Ethan Frey "] +authors = ["Ethan Frey ", "Simon Warta "] edition = "2021" publish = false license = "Apache-2.0" @@ -33,7 +33,7 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } -cosmwasm-std = { path = "../../packages/std", features = ["iterator"] } +cosmwasm-std = { path = "../../packages/std", features = ["iterator", "cosmwasm_1_4"] } schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/burner/LICENSE b/contracts/burner/LICENSE deleted file mode 100644 index d64569567..000000000 --- a/contracts/burner/LICENSE +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/contracts/burner/NOTICE b/contracts/burner/NOTICE deleted file mode 100644 index b8f34a8f1..000000000 --- a/contracts/burner/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2020 Ethan Frey - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/contracts/burner/schema/burner.json b/contracts/burner/schema/burner.json index 58e102e12..94c2124eb 100644 --- a/contracts/burner/schema/burner.json +++ b/contracts/burner/schema/burner.json @@ -19,7 +19,15 @@ "payout" ], "properties": { + "delete": { + "description": "Optional amount of items to delete in this call. If it is not provided, nothing will be deleted. You can delete further items in a subsequent execute call.", + "default": 0, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, "payout": { + "description": "The address we send all remaining balance to", "type": "string" } }, diff --git a/contracts/burner/schema/raw/instantiate.json b/contracts/burner/schema/raw/instantiate.json new file mode 100644 index 000000000..b055cda39 --- /dev/null +++ b/contracts/burner/schema/raw/instantiate.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "A placeholder where we don't take any input", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/burner/schema/raw/migrate.json b/contracts/burner/schema/raw/migrate.json new file mode 100644 index 000000000..752175c3e --- /dev/null +++ b/contracts/burner/schema/raw/migrate.json @@ -0,0 +1,22 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "required": [ + "payout" + ], + "properties": { + "delete": { + "description": "Optional amount of items to delete in this call. If it is not provided, nothing will be deleted. You can delete further items in a subsequent execute call.", + "default": 0, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "payout": { + "description": "The address we send all remaining balance to", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/burner/examples/schema.rs b/contracts/burner/src/bin/schema.rs similarity index 100% rename from contracts/burner/examples/schema.rs rename to contracts/burner/src/bin/schema.rs diff --git a/contracts/burner/src/contract.rs b/contracts/burner/src/contract.rs index e486be5b1..d6a96a0e0 100644 --- a/contracts/burner/src/contract.rs +++ b/contracts/burner/src/contract.rs @@ -1,8 +1,8 @@ use cosmwasm_std::{ - entry_point, BankMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, + entry_point, BankMsg, DepsMut, Env, MessageInfo, Order, Response, StdError, StdResult, Storage, }; -use crate::msg::{InstantiateMsg, MigrateMsg}; +use crate::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}; #[entry_point] pub fn instantiate( @@ -18,17 +18,6 @@ pub fn instantiate( #[entry_point] pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult { - // delete all state - let keys: Vec<_> = deps - .storage - .range(None, None, Order::Ascending) - .map(|(k, _)| k) - .collect(); - let count = keys.len(); - for k in keys { - deps.storage.remove(&k); - } - // get balance and send all to recipient let balance = deps.querier.query_all_balances(env.contract.address)?; let send = BankMsg::Send { @@ -36,13 +25,58 @@ pub fn migrate(deps: DepsMut, env: Env, msg: MigrateMsg) -> StdResult amount: balance, }; - let data_msg = format!("burnt {} keys", count).into_bytes(); + let deleted = cleanup(deps.storage, msg.delete as usize); Ok(Response::new() .add_message(send) - .add_attribute("action", "burn") + .add_attribute("action", "migrate") .add_attribute("payout", msg.payout) - .set_data(data_msg)) + .add_attribute("deleted_entries", deleted.to_string())) +} + +#[entry_point] +pub fn execute(deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg) -> StdResult { + match msg { + ExecuteMsg::Cleanup { limit } => execute_cleanup(deps, env, info, limit), + } +} + +pub fn execute_cleanup( + deps: DepsMut, + _env: Env, + _info: MessageInfo, + limit: Option, +) -> StdResult { + let limit = limit.unwrap_or(u32::MAX) as usize; + let deleted = cleanup(deps.storage, limit); + + Ok(Response::new() + .add_attribute("action", "cleanup") + .add_attribute("deleted_entries", deleted.to_string())) +} + +fn cleanup(storage: &mut dyn Storage, mut limit: usize) -> usize { + let mut deleted = 0; + const PER_SCAN: usize = 20; + loop { + let take_this_scan = std::cmp::min(PER_SCAN, limit); + let keys: Vec<_> = storage + .range_keys(None, None, Order::Ascending) + .take(take_this_scan) + .collect(); + let deleted_this_scan = keys.len(); + for k in keys { + storage.remove(&k); + } + deleted += deleted_this_scan; + // decrease the number of elements we can still take + limit -= deleted_this_scan; + if limit == 0 || deleted_this_scan < take_this_scan { + break; + } + } + + deleted } #[cfg(test)] @@ -51,7 +85,18 @@ mod tests { use cosmwasm_std::testing::{ mock_dependencies, mock_dependencies_with_balance, mock_env, mock_info, }; - use cosmwasm_std::{coins, StdError, Storage, SubMsg}; + use cosmwasm_std::{coins, Attribute, StdError, Storage, SubMsg}; + + /// Gets the value of the first attribute with the given key + fn first_attr(data: impl AsRef<[Attribute]>, search_key: &str) -> Option { + data.as_ref().iter().find_map(|a| { + if a.key == search_key { + Some(a.value.clone()) + } else { + None + } + }) + } #[test] fn instantiate_fails() { @@ -70,20 +115,14 @@ mod tests { } #[test] - fn migrate_cleans_up_data() { + fn migrate_sends_funds() { let mut deps = mock_dependencies_with_balance(&coins(123456, "gold")); - // store some sample data - deps.storage.set(b"foo", b"bar"); - deps.storage.set(b"key2", b"data2"); - deps.storage.set(b"key3", b"cool stuff"); - let cnt = deps.storage.range(None, None, Order::Ascending).count(); - assert_eq!(3, cnt); - // change the verifier via migrate let payout = String::from("someone else"); let msg = MigrateMsg { payout: payout.clone(), + delete: 0, }; let res = migrate(deps.as_mut(), mock_env(), msg).unwrap(); // check payout @@ -96,9 +135,71 @@ mod tests { amount: coins(123456, "gold"), }) ); + } + + #[test] + fn migrate_with_delete() { + let mut deps = mock_dependencies_with_balance(&coins(123456, "gold")); + + // store some sample data + deps.storage.set(b"foo", b"bar"); + deps.storage.set(b"key2", b"data2"); + deps.storage.set(b"key3", b"cool stuff"); + let cnt = deps.storage.range(None, None, Order::Ascending).count(); + assert_eq!(cnt, 3); + + // migrate all of the data in one go + let msg = MigrateMsg { + payout: "user".to_string(), + delete: 100, + }; + migrate(deps.as_mut(), mock_env(), msg).unwrap(); + + // no more data + let cnt = deps.storage.range(None, None, Order::Ascending).count(); + assert_eq!(cnt, 0); + } + + #[test] + fn execute_cleans_up_data() { + let mut deps = mock_dependencies_with_balance(&coins(123456, "gold")); + + // store some sample data + deps.storage.set(b"foo", b"bar"); + deps.storage.set(b"key2", b"data2"); + deps.storage.set(b"key3", b"cool stuff"); + let cnt = deps.storage.range(None, None, Order::Ascending).count(); + assert_eq!(cnt, 3); + + // change the verifier via migrate + let payout = String::from("someone else"); + let msg = MigrateMsg { payout, delete: 0 }; + let _res = migrate(deps.as_mut(), mock_env(), msg).unwrap(); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info("anon", &[]), + ExecuteMsg::Cleanup { limit: Some(2) }, + ) + .unwrap(); + assert_eq!(first_attr(res.attributes, "deleted_entries").unwrap(), "2"); + + // One item should be left + let cnt = deps.storage.range(None, None, Order::Ascending).count(); + assert_eq!(cnt, 1); + + let res = execute( + deps.as_mut(), + mock_env(), + mock_info("anon", &[]), + ExecuteMsg::Cleanup { limit: Some(2) }, + ) + .unwrap(); + assert_eq!(first_attr(res.attributes, "deleted_entries").unwrap(), "1"); - // check there is no data in storage + // Now all are gone let cnt = deps.storage.range(None, None, Order::Ascending).count(); - assert_eq!(0, cnt); + assert_eq!(cnt, 0); } } diff --git a/contracts/burner/src/msg.rs b/contracts/burner/src/msg.rs index f94800423..f8d7f4558 100644 --- a/contracts/burner/src/msg.rs +++ b/contracts/burner/src/msg.rs @@ -2,9 +2,27 @@ use cosmwasm_schema::cw_serde; #[cw_serde] pub struct MigrateMsg { + /// The address we send all remaining balance to pub payout: String, + /// Optional amount of items to delete in this call. + /// If it is not provided, nothing will be deleted. + /// You can delete further items in a subsequent execute call. + #[serde(default)] + pub delete: u32, } /// A placeholder where we don't take any input #[cw_serde] pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + /// Cleans up the given number of state elements. + /// Call this multiple times to increamentally clean up state. + Cleanup { + /// The number of state elements to delete. + /// + /// Set this to None for unlimited cleanup (if your state is small or you are feeling YOLO) + limit: Option, + }, +} diff --git a/contracts/burner/tests/integration.rs b/contracts/burner/tests/integration.rs index 8f30c2cca..c783a6fa3 100644 --- a/contracts/burner/tests/integration.rs +++ b/contracts/burner/tests/integration.rs @@ -17,10 +17,10 @@ //! }); //! 4. Anywhere you see query(&deps, ...) you must replace it with query(&mut deps, ...) -use cosmwasm_std::{coins, BankMsg, ContractResult, Order, Response, SubMsg}; -use cosmwasm_vm::testing::{instantiate, migrate, mock_env, mock_info, mock_instance}; +use cosmwasm_std::{coins, Attribute, BankMsg, ContractResult, Order, Response, SubMsg}; +use cosmwasm_vm::testing::{execute, instantiate, migrate, mock_env, mock_info, mock_instance}; -use burner::msg::{InstantiateMsg, MigrateMsg}; +use burner::msg::{ExecuteMsg, InstantiateMsg, MigrateMsg}; use cosmwasm_vm::Storage; // This line will test the output of cargo wasm @@ -28,6 +28,17 @@ static WASM: &[u8] = include_bytes!("../target/wasm32-unknown-unknown/release/bu // You can uncomment this line instead to test productionified build from rust-optimizer // static WASM: &[u8] = include_bytes!("../contract.wasm"); +/// Gets the value of the first attribute with the given key +fn first_attr(data: impl AsRef<[Attribute]>, search_key: &str) -> Option { + data.as_ref().iter().find_map(|a| { + if a.key == search_key { + Some(a.value.clone()) + } else { + None + } + }) +} + #[test] fn instantiate_fails() { let mut deps = mock_instance(WASM, &[]); @@ -44,25 +55,14 @@ fn instantiate_fails() { } #[test] -fn migrate_cleans_up_data() { +fn migrate_sends_funds() { let mut deps = mock_instance(WASM, &coins(123456, "gold")); - // store some sample data - deps.with_storage(|storage| { - storage.set(b"foo", b"bar").0.unwrap(); - storage.set(b"key2", b"data2").0.unwrap(); - storage.set(b"key3", b"cool stuff").0.unwrap(); - let iter_id = storage.scan(None, None, Order::Ascending).0.unwrap(); - let cnt = storage.all(iter_id).0.unwrap().len(); - assert_eq!(3, cnt); - Ok(()) - }) - .unwrap(); - // change the verifier via migrate let payout = String::from("someone else"); let msg = MigrateMsg { payout: payout.clone(), + delete: 0, }; let res: Response = migrate(&mut deps, mock_env(), msg).unwrap(); // check payout @@ -75,12 +75,61 @@ fn migrate_cleans_up_data() { amount: coins(123456, "gold"), }), ); +} + +#[test] +fn execute_cleans_up_data() { + let mut deps = mock_instance(WASM, &coins(123456, "gold")); + + // store some sample data + deps.with_storage(|storage| { + storage.set(b"foo", b"bar").0.unwrap(); + storage.set(b"key2", b"data2").0.unwrap(); + storage.set(b"key3", b"cool stuff").0.unwrap(); + let iter_id = storage.scan(None, None, Order::Ascending).0.unwrap(); + let cnt = storage.all(iter_id).0.unwrap().len(); + assert_eq!(cnt, 3); + Ok(()) + }) + .unwrap(); + + // change the verifier via migrate + let payout = String::from("someone else"); + let msg = MigrateMsg { payout, delete: 0 }; + let _res: Response = migrate(&mut deps, mock_env(), msg).unwrap(); + + let res: Response = execute( + &mut deps, + mock_env(), + mock_info("anon", &[]), + ExecuteMsg::Cleanup { limit: Some(2) }, + ) + .unwrap(); + assert_eq!(first_attr(res.attributes, "deleted_entries").unwrap(), "2"); + + // One item should be left + deps.with_storage(|storage| { + let iter_id = storage.scan(None, None, Order::Ascending).0.unwrap(); + let cnt = storage.all(iter_id).0.unwrap().len(); + assert_eq!(cnt, 1); + Ok(()) + }) + .unwrap(); + + let res: Response = execute( + &mut deps, + mock_env(), + mock_info("anon", &[]), + ExecuteMsg::Cleanup { limit: Some(2) }, + ) + .unwrap(); + assert_eq!(first_attr(res.attributes, "deleted_entries").unwrap(), "1"); // check there is no data in storage deps.with_storage(|storage| { let iter_id = storage.scan(None, None, Order::Ascending).0.unwrap(); let cnt = storage.all(iter_id).0.unwrap().len(); - assert_eq!(0, cnt); + assert_eq!(cnt, 0); Ok(()) }) .unwrap(); diff --git a/contracts/crypto-verify/.cargo/config b/contracts/crypto-verify/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/crypto-verify/.cargo/config +++ b/contracts/crypto-verify/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/crypto-verify/Cargo.lock b/contracts/crypto-verify/Cargo.lock index 903284102..1e05ea5d6 100644 --- a/contracts/crypto-verify/Cargo.lock +++ b/contracts/crypto-verify/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,57 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -150,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -162,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -177,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -192,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -212,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -220,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -228,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -265,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -332,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -363,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -417,14 +447,13 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "hex", "hex-literal", "rlp", "schemars", "serde", - "sha2 0.10.6", + "sha2 0.10.8", "sha3", ] @@ -443,9 +472,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -453,33 +482,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -493,7 +535,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -507,20 +549,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -534,7 +577,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -550,14 +593,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -577,20 +622,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -618,28 +662,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -648,20 +692,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -673,27 +708,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -713,30 +773,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -747,13 +798,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -773,7 +821,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -783,57 +831,59 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] name = "keccak" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3afef3b6eff9ce9d8ff9b3601125eec7f0c8cbac7abd14f355d053fa56c98768" +checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" dependencies = [ "cpufeatures", ] @@ -852,49 +902,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -907,42 +933,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -953,42 +979,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -997,22 +1001,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1027,7 +1044,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1044,9 +1061,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1068,18 +1085,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1097,9 +1120,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1107,33 +1130,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1149,58 +1171,52 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1215,15 +1231,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustc-hex" @@ -1231,23 +1241,17 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" - [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1257,21 +1261,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1281,9 +1285,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1295,40 +1299,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1339,14 +1345,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1387,46 +1393,58 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "sha3" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "keccak", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1439,22 +1457,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1462,53 +1485,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1516,53 +1544,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1582,9 +1624,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1592,24 +1634,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1617,92 +1682,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1714,16 +1771,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1733,184 +1790,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1941,45 +1892,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/crypto-verify/Cargo.toml b/contracts/crypto-verify/Cargo.toml index 0661d6c48..e31fe6242 100644 --- a/contracts/crypto-verify/Cargo.toml +++ b/contracts/crypto-verify/Cargo.toml @@ -34,7 +34,6 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } cosmwasm-std = { path = "../../packages/std", features = ["iterator"] } -cosmwasm-storage = { path = "../../packages/storage", features = ["iterator"] } hex = "0.4" rlp = "0.5" schemars = "0.8.3" diff --git a/contracts/crypto-verify/schema/raw/instantiate.json b/contracts/crypto-verify/schema/raw/instantiate.json new file mode 100644 index 000000000..1352613d5 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/instantiate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/crypto-verify/schema/raw/query.json b/contracts/crypto-verify/schema/raw/query.json new file mode 100644 index 000000000..dbb6e9937 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/query.json @@ -0,0 +1,268 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Cosmos format (secp256k1 verification scheme).", + "type": "object", + "required": [ + "verify_cosmos_signature" + ], + "properties": { + "verify_cosmos_signature": { + "type": "object", + "required": [ + "message", + "public_key", + "signature" + ], + "properties": { + "message": { + "description": "Message to verify.", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "public_key": { + "description": "Serialized compressed (33 bytes) or uncompressed (65 bytes) public key.", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "signature": { + "description": "Serialized signature. Cosmos format (64 bytes).", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Ethereum text verification (compatible to the eth_sign RPC/web3 enpoint). This cannot be used to verify transaction.\n\nSee https://web3js.readthedocs.io/en/v1.2.0/web3-eth.html#sign", + "type": "object", + "required": [ + "verify_ethereum_text" + ], + "properties": { + "verify_ethereum_text": { + "type": "object", + "required": [ + "message", + "signature", + "signer_address" + ], + "properties": { + "message": { + "description": "Message to verify. This will be wrapped in the standard container `\"\\x19Ethereum Signed Message:\\n\" + len(message) + message` before verification.", + "type": "string" + }, + "signature": { + "description": "Serialized signature. Fixed length format (64 bytes `r` and `s` plus the one byte `v`).", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "signer_address": { + "description": "Signer address. This is matched case insensitive, so you can provide checksummed and non-checksummed addresses. Checksums are not validated.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verify_ethereum_transaction" + ], + "properties": { + "verify_ethereum_transaction": { + "type": "object", + "required": [ + "chain_id", + "data", + "from", + "gas_limit", + "gas_price", + "nonce", + "r", + "s", + "to", + "v", + "value" + ], + "properties": { + "chain_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "from": { + "description": "Ethereum address in hex format (42 characters, starting with 0x)", + "type": "string" + }, + "gas_limit": { + "$ref": "#/definitions/Uint128" + }, + "gas_price": { + "$ref": "#/definitions/Uint128" + }, + "nonce": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "r": { + "$ref": "#/definitions/Binary" + }, + "s": { + "$ref": "#/definitions/Binary" + }, + "to": { + "description": "Ethereum address in hex format (42 characters, starting with 0x)", + "type": "string" + }, + "v": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "value": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Tendermint format (ed25519 verification scheme).", + "type": "object", + "required": [ + "verify_tendermint_signature" + ], + "properties": { + "verify_tendermint_signature": { + "type": "object", + "required": [ + "message", + "public_key", + "signature" + ], + "properties": { + "message": { + "description": "Message to verify.", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "public_key": { + "description": "Serialized public key. Tendermint format (32 bytes).", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "signature": { + "description": "Serialized signature. Tendermint format (64 bytes).", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Tendermint format (batch ed25519 verification scheme).", + "type": "object", + "required": [ + "verify_tendermint_batch" + ], + "properties": { + "verify_tendermint_batch": { + "type": "object", + "required": [ + "messages", + "public_keys", + "signatures" + ], + "properties": { + "messages": { + "description": "Messages to verify.", + "type": "array", + "items": { + "$ref": "#/definitions/Binary" + } + }, + "public_keys": { + "description": "Serialized public keys. Tendermint format (32 bytes).", + "type": "array", + "items": { + "$ref": "#/definitions/Binary" + } + }, + "signatures": { + "description": "Serialized signatures. Tendermint format (64 bytes).", + "type": "array", + "items": { + "$ref": "#/definitions/Binary" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns a list of supported verification schemes. No pagination - this is a short list.", + "type": "object", + "required": [ + "list_verification_schemes" + ], + "properties": { + "list_verification_schemes": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/crypto-verify/schema/raw/response_to_list_verification_schemes.json b/contracts/crypto-verify/schema/raw/response_to_list_verification_schemes.json new file mode 100644 index 000000000..26fa42ab4 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/response_to_list_verification_schemes.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ListVerificationsResponse", + "type": "object", + "required": [ + "verification_schemes" + ], + "properties": { + "verification_schemes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false +} diff --git a/contracts/crypto-verify/schema/raw/response_to_verify_cosmos_signature.json b/contracts/crypto-verify/schema/raw/response_to_verify_cosmos_signature.json new file mode 100644 index 000000000..a2cdc3461 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/response_to_verify_cosmos_signature.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifyResponse", + "type": "object", + "required": [ + "verifies" + ], + "properties": { + "verifies": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/contracts/crypto-verify/schema/raw/response_to_verify_ethereum_text.json b/contracts/crypto-verify/schema/raw/response_to_verify_ethereum_text.json new file mode 100644 index 000000000..a2cdc3461 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/response_to_verify_ethereum_text.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifyResponse", + "type": "object", + "required": [ + "verifies" + ], + "properties": { + "verifies": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/contracts/crypto-verify/schema/raw/response_to_verify_ethereum_transaction.json b/contracts/crypto-verify/schema/raw/response_to_verify_ethereum_transaction.json new file mode 100644 index 000000000..a2cdc3461 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/response_to_verify_ethereum_transaction.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifyResponse", + "type": "object", + "required": [ + "verifies" + ], + "properties": { + "verifies": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/contracts/crypto-verify/schema/raw/response_to_verify_tendermint_batch.json b/contracts/crypto-verify/schema/raw/response_to_verify_tendermint_batch.json new file mode 100644 index 000000000..a2cdc3461 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/response_to_verify_tendermint_batch.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifyResponse", + "type": "object", + "required": [ + "verifies" + ], + "properties": { + "verifies": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/contracts/crypto-verify/schema/raw/response_to_verify_tendermint_signature.json b/contracts/crypto-verify/schema/raw/response_to_verify_tendermint_signature.json new file mode 100644 index 000000000..a2cdc3461 --- /dev/null +++ b/contracts/crypto-verify/schema/raw/response_to_verify_tendermint_signature.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifyResponse", + "type": "object", + "required": [ + "verifies" + ], + "properties": { + "verifies": { + "type": "boolean" + } + }, + "additionalProperties": false +} diff --git a/contracts/crypto-verify/examples/schema.rs b/contracts/crypto-verify/src/bin/schema.rs similarity index 100% rename from contracts/crypto-verify/examples/schema.rs rename to contracts/crypto-verify/src/bin/schema.rs diff --git a/contracts/crypto-verify/src/contract.rs b/contracts/crypto-verify/src/contract.rs index 17d11b8a7..b2917a90c 100644 --- a/contracts/crypto-verify/src/contract.rs +++ b/contracts/crypto-verify/src/contract.rs @@ -396,7 +396,7 @@ mod tests { source: RecoverPubkeyError::UnknownErr { .. }, .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/contracts/crypto-verify/src/ethereum.rs b/contracts/crypto-verify/src/ethereum.rs index b47fe4933..f6958a023 100644 --- a/contracts/crypto-verify/src/ethereum.rs +++ b/contracts/crypto-verify/src/ethereum.rs @@ -19,7 +19,7 @@ pub fn verify_transaction( ) -> StdResult { let sign_bytes = serialize_unsigned_transaction(to, nonce, gas, gas_price, value, data, chain_id); - let hash = Keccak256::digest(&sign_bytes); + let hash = Keccak256::digest(sign_bytes); let mut rs: Vec = Vec::with_capacity(64); rs.resize(32 - r.len(), 0); // Left pad r to 32 bytes rs.extend_from_slice(r); @@ -88,8 +88,7 @@ pub fn get_recovery_param_with_chain_id(v: u64, chain_id: u64) -> StdResult match recovery { 0 | 1 => Ok(recovery as u8), _ => Err(StdError::generic_err(format!( - "Calculated recovery parameter must be 0 or 1 but is {}.", - recovery + "Calculated recovery parameter must be 0 or 1 but is {recovery}." ))), } } diff --git a/contracts/cyberpunk/.cargo/config b/contracts/cyberpunk/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/cyberpunk/.cargo/config +++ b/contracts/cyberpunk/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/cyberpunk/Cargo.lock b/contracts/cyberpunk/Cargo.lock index c7360e402..b4bad366c 100644 --- a/contracts/cyberpunk/Cargo.lock +++ b/contracts/cyberpunk/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", @@ -30,9 +30,9 @@ dependencies = [ [[package]] name = "arrayref" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] name = "arrayvec" @@ -40,6 +40,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -48,24 +54,24 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" @@ -73,11 +79,17 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" + [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -85,6 +97,24 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2b_simd" version = "0.5.11" @@ -92,7 +122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" dependencies = [ "arrayref", - "arrayvec", + "arrayvec 0.5.2", "constant_time_eq", ] @@ -107,51 +137,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -167,9 +213,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "constant_time_eq" @@ -185,22 +231,22 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", "libc", "scopeguard", - "windows-sys", + "windows-sys 0.33.0", ] [[package]] name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -215,7 +261,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -235,14 +281,15 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ - "base64", + "base64 0.21.5", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -251,36 +298,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ - "bitflags", + "bitflags 1.3.2", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -288,65 +328,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec 0.7.4", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -355,29 +413,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -386,37 +440,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -453,17 +501,17 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "rust-argon2", + "tempfile", "thiserror", ] [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -471,33 +519,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -511,7 +572,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -525,20 +586,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -546,13 +608,13 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "byteorder", "lazy_static", "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -568,14 +630,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -595,20 +659,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -636,28 +699,38 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -668,18 +741,15 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "1.8.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -691,27 +761,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -731,30 +826,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -765,13 +851,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -785,7 +868,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -795,50 +878,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -855,49 +940,31 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" - -[[package]] -name = "libloading" -version = "0.7.4" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "log" -version = "0.4.17" +name = "linux-raw-sys" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" [[package]] -name = "loupe" -version = "0.1.3" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", + "autocfg", + "scopeguard", ] [[package]] -name = "loupe-derive" -version = "0.1.3" +name = "log" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -910,42 +977,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -956,42 +1023,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -1000,22 +1045,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1030,7 +1088,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1047,9 +1105,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1071,18 +1129,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1100,9 +1164,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1110,33 +1174,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1146,64 +1209,58 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", "mach", "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1212,7 +1269,7 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" dependencies = [ - "base64", + "base64 0.13.1", "blake2b_simd", "constant_time_eq", "crossbeam-utils", @@ -1220,33 +1277,34 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] -name = "rustc-hash" -version = "1.1.0" +name = "rustix" +version = "0.38.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1256,21 +1314,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1280,9 +1338,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1294,40 +1352,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1338,14 +1398,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1386,36 +1446,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1428,76 +1500,99 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" -version = "0.12.5" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "tempfile" -version = "3.3.0" +version = "3.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" dependencies = [ "cfg-if", "fastrand", - "libc", "redox_syscall", - "remove_dir_all", - "winapi", + "rustix", + "windows-sys 0.48.0", ] [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1505,53 +1600,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1571,9 +1680,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1581,24 +1690,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1606,92 +1738,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1703,16 +1827,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1722,184 +1846,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1930,45 +1948,120 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/cyberpunk/Cargo.toml b/contracts/cyberpunk/Cargo.toml index b4cdca0d3..c2db096f2 100644 --- a/contracts/cyberpunk/Cargo.toml +++ b/contracts/cyberpunk/Cargo.toml @@ -30,10 +30,10 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } -cosmwasm-std = { path = "../../packages/std", default-features = false, features = ["abort"] } +cosmwasm-std = { path = "../../packages/std", default-features = false, features = ["abort", "cosmwasm_1_3"] } rust-argon2 = "0.8" -thiserror = "1.0" +thiserror = "1.0.26" [dev-dependencies] -cosmwasm-storage = { path = "../../packages/storage", default-features = false } cosmwasm-vm = { path = "../../packages/vm", default-features = false } +tempfile = "3.1.0" diff --git a/contracts/cyberpunk/schema/cyberpunk.json b/contracts/cyberpunk/schema/cyberpunk.json index 9439d3055..6f5f207d1 100644 --- a/contracts/cyberpunk/schema/cyberpunk.json +++ b/contracts/cyberpunk/schema/cyberpunk.json @@ -44,6 +44,114 @@ }, "additionalProperties": false }, + { + "description": "Infinite loop to burn cpu cycles (only run when metering is enabled)", + "type": "object", + "required": [ + "cpu_loop" + ], + "properties": { + "cpu_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop making storage calls (to test when their limit hits)", + "type": "object", + "required": [ + "storage_loop" + ], + "properties": { + "storage_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop reading and writing memory", + "type": "object", + "required": [ + "memory_loop" + ], + "properties": { + "memory_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop sending message to itself", + "type": "object", + "required": [ + "message_loop" + ], + "properties": { + "message_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Allocate large amounts of memory without consuming much gas", + "type": "object", + "required": [ + "allocate_large_memory" + ], + "properties": { + "allocate_large_memory": { + "type": "object", + "required": [ + "pages" + ], + "properties": { + "pages": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Trigger a panic to ensure framework handles gracefully", + "type": "object", + "required": [ + "panic" + ], + "properties": { + "panic": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In contrast to Panic, this does not use the panic handler.\n\nFrom : \"Generates the unreachable instruction, which causes an unconditional trap.\"", + "type": "object", + "required": [ + "unreachable" + ], + "properties": { + "unreachable": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "description": "Returns the env for testing", "type": "object", @@ -57,6 +165,20 @@ } }, "additionalProperties": false + }, + { + "description": "Does a bit of work and calls debug", + "type": "object", + "required": [ + "debug" + ], + "properties": { + "debug": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, @@ -77,12 +199,198 @@ } }, "additionalProperties": false + }, + { + "description": "Queries `AllDenomMetadata` from the bank module repeatedly and returns all entries", + "type": "object", + "required": [ + "denoms" + ], + "properties": { + "denoms": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Queries `DenomMetadata` from the bank module and returns the result", + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ] }, "migrate": null, "sudo": null, "responses": { + "denom": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DenomMetadata", + "description": "Replicates the cosmos-sdk bank module Metadata type", + "type": "object", + "required": [ + "base", + "denom_units", + "description", + "display", + "name", + "symbol", + "uri", + "uri_hash" + ], + "properties": { + "base": { + "type": "string" + }, + "denom_units": { + "type": "array", + "items": { + "$ref": "#/definitions/DenomUnit" + } + }, + "description": { + "type": "string" + }, + "display": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "uri_hash": { + "type": "string" + } + }, + "definitions": { + "DenomUnit": { + "description": "Replicates the cosmos-sdk bank module DenomUnit type", + "type": "object", + "required": [ + "aliases", + "denom", + "exponent" + ], + "properties": { + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "denom": { + "type": "string" + }, + "exponent": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + } + } + }, + "denoms": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_DenomMetadata", + "type": "array", + "items": { + "$ref": "#/definitions/DenomMetadata" + }, + "definitions": { + "DenomMetadata": { + "description": "Replicates the cosmos-sdk bank module Metadata type", + "type": "object", + "required": [ + "base", + "denom_units", + "description", + "display", + "name", + "symbol", + "uri", + "uri_hash" + ], + "properties": { + "base": { + "type": "string" + }, + "denom_units": { + "type": "array", + "items": { + "$ref": "#/definitions/DenomUnit" + } + }, + "description": { + "type": "string" + }, + "display": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "uri_hash": { + "type": "string" + } + } + }, + "DenomUnit": { + "description": "Replicates the cosmos-sdk bank module DenomUnit type", + "type": "object", + "required": [ + "aliases", + "denom", + "exponent" + ], + "properties": { + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "denom": { + "type": "string" + }, + "exponent": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + } + } + }, "mirror_env": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "Env", @@ -133,7 +441,7 @@ "minimum": 0.0 }, "time": { - "description": "Absolute time of the block creation in seconds since the UNIX epoch (00:00:00 on 1970-01-01 UTC).\n\nThe source of this is the [BFT Time in Tendermint](https://github.com/tendermint/tendermint/blob/58dc1726/spec/consensus/bft-time.md), which has the same nanosecond precision as the `Timestamp` type.\n\n# Examples\n\nUsing chrono:\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; # extern crate chrono; use chrono::NaiveDateTime; let seconds = env.block.time.seconds(); let nsecs = env.block.time.subsec_nanos(); let dt = NaiveDateTime::from_timestamp(seconds as i64, nsecs as u32); ```\n\nCreating a simple millisecond-precision timestamp (as used in JavaScript):\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; let millis = env.block.time.nanos() / 1_000_000; ```", + "description": "Absolute time of the block creation in seconds since the UNIX epoch (00:00:00 on 1970-01-01 UTC).\n\nThe source of this is the [BFT Time](https://github.com/Finschia/ostracon/blob/main/spec/README.md#consensus-protocol), which has the same nanosecond precision as the `Timestamp` type.\n\n# Examples\n\nUsing chrono:\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; # extern crate chrono; use chrono::NaiveDateTime; let seconds = env.block.time.seconds(); let nsecs = env.block.time.subsec_nanos(); let dt = NaiveDateTime::from_timestamp(seconds as i64, nsecs as u32); ```\n\nCreating a simple millisecond-precision timestamp (as used in JavaScript):\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; let millis = env.block.time.nanos() / 1_000_000; ```", "allOf": [ { "$ref": "#/definitions/Timestamp" diff --git a/contracts/cyberpunk/schema/raw/execute.json b/contracts/cyberpunk/schema/raw/execute.json new file mode 100644 index 000000000..8ea521b97 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/execute.json @@ -0,0 +1,174 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Hashes some data. Uses CPU and memory, but no external calls.", + "type": "object", + "required": [ + "argon2" + ], + "properties": { + "argon2": { + "type": "object", + "required": [ + "mem_cost", + "time_cost" + ], + "properties": { + "mem_cost": { + "description": "The amount of memory requested (KB).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "time_cost": { + "description": "The number of passes.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop to burn cpu cycles (only run when metering is enabled)", + "type": "object", + "required": [ + "cpu_loop" + ], + "properties": { + "cpu_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop making storage calls (to test when their limit hits)", + "type": "object", + "required": [ + "storage_loop" + ], + "properties": { + "storage_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop reading and writing memory", + "type": "object", + "required": [ + "memory_loop" + ], + "properties": { + "memory_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop sending message to itself", + "type": "object", + "required": [ + "message_loop" + ], + "properties": { + "message_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Allocate large amounts of memory without consuming much gas", + "type": "object", + "required": [ + "allocate_large_memory" + ], + "properties": { + "allocate_large_memory": { + "type": "object", + "required": [ + "pages" + ], + "properties": { + "pages": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Trigger a panic to ensure framework handles gracefully", + "type": "object", + "required": [ + "panic" + ], + "properties": { + "panic": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "In contrast to Panic, this does not use the panic handler.\n\nFrom : \"Generates the unreachable instruction, which causes an unconditional trap.\"", + "type": "object", + "required": [ + "unreachable" + ], + "properties": { + "unreachable": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the env for testing", + "type": "object", + "required": [ + "mirror_env" + ], + "properties": { + "mirror_env": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Does a bit of work and calls debug", + "type": "object", + "required": [ + "debug" + ], + "properties": { + "debug": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/cyberpunk/schema/raw/instantiate.json b/contracts/cyberpunk/schema/raw/instantiate.json new file mode 100644 index 000000000..5f6dfaf43 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/instantiate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" +} diff --git a/contracts/cyberpunk/schema/raw/migrate.json b/contracts/cyberpunk/schema/raw/migrate.json new file mode 100644 index 000000000..8e7af5fe3 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/migrate.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Hashes some data. Uses CPU and memory, but no external calls.", + "type": "object", + "required": [ + "argon2" + ], + "properties": { + "argon2": { + "type": "object", + "required": [ + "mem_cost", + "time_cost" + ], + "properties": { + "mem_cost": { + "description": "The amount of memory requested (KB).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "time_cost": { + "description": "The number of passes.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the env for testing", + "type": "object", + "required": [ + "mirror_env" + ], + "properties": { + "mirror_env": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/cyberpunk/schema/raw/query.json b/contracts/cyberpunk/schema/raw/query.json new file mode 100644 index 000000000..47b493442 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/query.json @@ -0,0 +1,56 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns the env for testing", + "type": "object", + "required": [ + "mirror_env" + ], + "properties": { + "mirror_env": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Queries `AllDenomMetadata` from the bank module repeatedly and returns all entries", + "type": "object", + "required": [ + "denoms" + ], + "properties": { + "denoms": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Queries `DenomMetadata` from the bank module and returns the result", + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/cyberpunk/schema/raw/response_to_denom.json b/contracts/cyberpunk/schema/raw/response_to_denom.json new file mode 100644 index 000000000..b541da804 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/response_to_denom.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "DenomMetadata", + "description": "Replicates the cosmos-sdk bank module Metadata type", + "type": "object", + "required": [ + "base", + "denom_units", + "description", + "display", + "name", + "symbol", + "uri", + "uri_hash" + ], + "properties": { + "base": { + "type": "string" + }, + "denom_units": { + "type": "array", + "items": { + "$ref": "#/definitions/DenomUnit" + } + }, + "description": { + "type": "string" + }, + "display": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "uri_hash": { + "type": "string" + } + }, + "definitions": { + "DenomUnit": { + "description": "Replicates the cosmos-sdk bank module DenomUnit type", + "type": "object", + "required": [ + "aliases", + "denom", + "exponent" + ], + "properties": { + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "denom": { + "type": "string" + }, + "exponent": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + } + } +} diff --git a/contracts/cyberpunk/schema/raw/response_to_denoms.json b/contracts/cyberpunk/schema/raw/response_to_denoms.json new file mode 100644 index 000000000..e8fcd9a16 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/response_to_denoms.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Array_of_DenomMetadata", + "type": "array", + "items": { + "$ref": "#/definitions/DenomMetadata" + }, + "definitions": { + "DenomMetadata": { + "description": "Replicates the cosmos-sdk bank module Metadata type", + "type": "object", + "required": [ + "base", + "denom_units", + "description", + "display", + "name", + "symbol", + "uri", + "uri_hash" + ], + "properties": { + "base": { + "type": "string" + }, + "denom_units": { + "type": "array", + "items": { + "$ref": "#/definitions/DenomUnit" + } + }, + "description": { + "type": "string" + }, + "display": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "uri": { + "type": "string" + }, + "uri_hash": { + "type": "string" + } + } + }, + "DenomUnit": { + "description": "Replicates the cosmos-sdk bank module DenomUnit type", + "type": "object", + "required": [ + "aliases", + "denom", + "exponent" + ], + "properties": { + "aliases": { + "type": "array", + "items": { + "type": "string" + } + }, + "denom": { + "type": "string" + }, + "exponent": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + } + } +} diff --git a/contracts/cyberpunk/schema/raw/response_to_mirror_env.json b/contracts/cyberpunk/schema/raw/response_to_mirror_env.json new file mode 100644 index 000000000..050e62b90 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/response_to_mirror_env.json @@ -0,0 +1,98 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Env", + "type": "object", + "required": [ + "block", + "contract" + ], + "properties": { + "block": { + "$ref": "#/definitions/BlockInfo" + }, + "contract": { + "$ref": "#/definitions/ContractInfo" + }, + "transaction": { + "description": "Information on the transaction this message was executed in. The field is unset when the `MsgExecuteContract`/`MsgInstantiateContract`/`MsgMigrateContract` is not executed as part of a transaction.", + "anyOf": [ + { + "$ref": "#/definitions/TransactionInfo" + }, + { + "type": "null" + } + ] + } + }, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "BlockInfo": { + "type": "object", + "required": [ + "chain_id", + "height", + "time" + ], + "properties": { + "chain_id": { + "type": "string" + }, + "height": { + "description": "The height of a block is the number of blocks preceding it in the blockchain.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "time": { + "description": "Absolute time of the block creation in seconds since the UNIX epoch (00:00:00 on 1970-01-01 UTC).\n\nThe source of this is the [BFT Time](https://github.com/Finschia/ostracon/blob/main/spec/README.md#consensus-protocol), which has the same nanosecond precision as the `Timestamp` type.\n\n# Examples\n\nUsing chrono:\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; # extern crate chrono; use chrono::NaiveDateTime; let seconds = env.block.time.seconds(); let nsecs = env.block.time.subsec_nanos(); let dt = NaiveDateTime::from_timestamp(seconds as i64, nsecs as u32); ```\n\nCreating a simple millisecond-precision timestamp (as used in JavaScript):\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; let millis = env.block.time.nanos() / 1_000_000; ```", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + } + }, + "ContractInfo": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "$ref": "#/definitions/Addr" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "TransactionInfo": { + "type": "object", + "required": [ + "index" + ], + "properties": { + "index": { + "description": "The position of this transaction in the block. The first transaction has index 0.\n\nThis allows you to get a unique transaction indentifier in this chain using the pair (`env.block.height`, `env.transaction.index`).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/cyberpunk/schema/raw/sudo.json b/contracts/cyberpunk/schema/raw/sudo.json new file mode 100644 index 000000000..8e7af5fe3 --- /dev/null +++ b/contracts/cyberpunk/schema/raw/sudo.json @@ -0,0 +1,52 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Hashes some data. Uses CPU and memory, but no external calls.", + "type": "object", + "required": [ + "argon2" + ], + "properties": { + "argon2": { + "type": "object", + "required": [ + "mem_cost", + "time_cost" + ], + "properties": { + "mem_cost": { + "description": "The amount of memory requested (KB).", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "time_cost": { + "description": "The number of passes.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns the env for testing", + "type": "object", + "required": [ + "mirror_env" + ], + "properties": { + "mirror_env": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/cyberpunk/examples/schema.rs b/contracts/cyberpunk/src/bin/schema.rs similarity index 100% rename from contracts/cyberpunk/examples/schema.rs rename to contracts/cyberpunk/src/bin/schema.rs diff --git a/contracts/cyberpunk/src/contract.rs b/contracts/cyberpunk/src/contract.rs index 7ea42967a..0374a06a8 100644 --- a/contracts/cyberpunk/src/contract.rs +++ b/contracts/cyberpunk/src/contract.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ - entry_point, to_binary, Deps, DepsMut, Empty, Env, MessageInfo, QueryResponse, Response, - StdError, StdResult, + entry_point, to_binary, Api, DenomMetadata, Deps, DepsMut, Empty, Env, MessageInfo, + PageRequest, QueryResponse, Response, StdError, StdResult, WasmMsg, }; use crate::errors::ContractError; @@ -8,20 +8,17 @@ use crate::msg::{ExecuteMsg, QueryMsg}; #[entry_point] pub fn instantiate( - deps: DepsMut, + _deps: DepsMut, _env: Env, _info: MessageInfo, _msg: Empty, ) -> Result { - deps.api.debug("here we go 🚀"); - - // This adds some unrelated event attribute for testing purposes - Ok(Response::new().add_attribute("Let the", "hacking begin")) + Ok(Response::default()) } #[entry_point] pub fn execute( - _deps: DepsMut, + deps: DepsMut, env: Env, _info: MessageInfo, msg: ExecuteMsg, @@ -32,54 +29,267 @@ pub fn execute( Argon2 { mem_cost, time_cost, - } => execute::argon2(mem_cost, time_cost), - MirrorEnv {} => execute::mirror_env(env), + } => execute_argon2(mem_cost, time_cost), + CpuLoop {} => execute_cpu_loop(), + StorageLoop {} => execute_storage_loop(deps), + MemoryLoop {} => execute_memory_loop(), + MessageLoop {} => execute_message_loop(env), + AllocateLargeMemory { pages } => execute_allocate_large_memory(pages), + Panic {} => execute_panic(), + Unreachable {} => execute_unreachable(), + MirrorEnv {} => execute_mirror_env(env), + Debug {} => execute_debug(deps.api), } } -mod execute { - use super::*; +fn execute_argon2(mem_cost: u32, time_cost: u32) -> Result { + let password = b"password"; + let salt = b"othersalt"; + let config = argon2::Config { + variant: argon2::Variant::Argon2i, + version: argon2::Version::Version13, + mem_cost, + time_cost, + lanes: 4, + thread_mode: argon2::ThreadMode::Sequential, + secret: &[], + ad: &[], + hash_length: 32, + }; + let hash = argon2::hash_encoded(password, salt, &config) + .map_err(|e| StdError::generic_err(format!("hash_encoded errored: {e}")))?; + // let matches = argon2::verify_encoded(&hash, password).unwrap(); + // assert!(matches); + Ok(Response::new().set_data(hash.into_bytes())) + //Ok(Response::new()) +} + +fn execute_cpu_loop() -> Result { + let mut counter = 0u64; + loop { + counter += 1; + if counter >= 9_000_000_000 { + counter = 0; + } + } +} + +fn execute_storage_loop(deps: DepsMut) -> Result { + let mut test_case = 0u64; + loop { + deps.storage + .set(b"test.key", test_case.to_string().as_bytes()); + test_case += 1; + } +} + +fn execute_memory_loop() -> Result { + let mut data = vec![1usize]; + loop { + // add one element + data.push((*data.last().expect("must not be empty")) + 1); + } +} - pub fn argon2(mem_cost: u32, time_cost: u32) -> Result { - let password = b"password"; - let salt = b"othersalt"; +fn execute_message_loop(env: Env) -> Result { + let resp = Response::new().add_message(WasmMsg::Execute { + contract_addr: env.contract.address.into(), + msg: to_binary(&ExecuteMsg::MessageLoop {})?, + funds: vec![], + }); + Ok(resp) +} + +#[allow(unused_variables)] +fn execute_allocate_large_memory(pages: u32) -> Result { + // We create memory pages explicitely since Rust's default allocator seems to be clever enough + // to not grow memory for unused capacity like `Vec::::with_capacity(100 * 1024 * 1024)`. + // Even with std::alloc::alloc the memory did now grow beyond 1.5 MiB. + + #[cfg(target_arch = "wasm32")] + { + use core::arch::wasm32; + let old_size = wasm32::memory_grow(0, pages as usize); + if old_size == usize::max_value() { + return Err(StdError::generic_err("memory.grow failed").into()); + } + Ok(Response::new().set_data((old_size as u32).to_be_bytes())) + } + + #[cfg(not(target_arch = "wasm32"))] + Err(StdError::generic_err("Unsupported architecture").into()) +} + +fn execute_panic() -> Result { + // Uncomment your favourite panic case + + // panicked at 'This page intentionally faulted', src/contract.rs:53:5 + panic!("This page intentionally faulted"); + + // panicked at 'oh no (a = 3)', src/contract.rs:56:5 + // let a = 3; + // panic!("oh no (a = {a})"); + + // panicked at 'attempt to subtract with overflow', src/contract.rs:59:13 + // #[allow(arithmetic_overflow)] + // let _ = 5u32 - 8u32; + + // panicked at 'no entry found for key', src/contract.rs:62:13 + // let map = std::collections::HashMap::::new(); + // let _ = map["foo"]; +} + +fn execute_unreachable() -> Result { + #[cfg(target_arch = "wasm32")] + core::arch::wasm32::unreachable(); + + #[cfg(not(target_arch = "wasm32"))] + Err(StdError::generic_err("Unsupported architecture").into()) +} + +fn execute_mirror_env(env: Env) -> Result { + Ok(Response::new().set_data(to_binary(&env)?)) +} + +fn execute_debug(api: &dyn Api) -> Result { + api.debug("Hey, ho – let's go"); + + let password = b"password"; + let salt = b"othersalt"; + + for r in 1..10 { + api.debug(&format!("Round {r} starting")); let config = argon2::Config { variant: argon2::Variant::Argon2i, version: argon2::Version::Version13, - mem_cost, - time_cost, + mem_cost: 32, + time_cost: r, lanes: 4, thread_mode: argon2::ThreadMode::Sequential, secret: &[], ad: &[], hash_length: 32, }; - let hash = argon2::hash_encoded(password, salt, &config) - .map_err(|e| StdError::generic_err(format!("hash_encoded errored: {}", e)))?; - // let matches = argon2::verify_encoded(&hash, password).unwrap(); - // assert!(matches); - Ok(Response::new().set_data(hash.into_bytes())) - //Ok(Response::new()) + let _hash = argon2::hash_encoded(password, salt, &config).unwrap(); + api.debug(&format!("Round {r} done")); } - pub fn mirror_env(env: Env) -> Result { - Ok(Response::new().set_data(to_binary(&env)?)) - } + api.debug("Work completed, bye"); + Ok(Response::default()) } #[entry_point] -pub fn query(_deps: Deps, env: Env, msg: QueryMsg) -> StdResult { +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult { use QueryMsg::*; match msg { - MirrorEnv {} => to_binary(&query::mirror_env(env)), + MirrorEnv {} => to_binary(&query_mirror_env(env)), + Denoms {} => to_binary(&query_denoms(deps)?), + Denom { denom } => to_binary(&query_denom(deps, denom)?), + } +} + +fn query_mirror_env(env: Env) -> Env { + env +} + +fn query_denoms(deps: Deps) -> StdResult> { + const PAGE_SIZE: u32 = 10; + let mut next_key = None; + let mut all_metadata = Vec::new(); + loop { + let page = deps.querier.query_all_denom_metadata(PageRequest { + key: next_key, + limit: PAGE_SIZE, + reverse: false, + })?; + + let len = page.metadata.len() as u32; + all_metadata.extend(page.metadata); + next_key = page.next_key; + + if next_key.is_none() || len < PAGE_SIZE { + break; + } } + + Ok(all_metadata) +} + +fn query_denom(deps: Deps, denom: String) -> StdResult { + deps.querier.query_denom_metadata(denom) } -mod query { +#[cfg(test)] +mod tests { use super::*; + use cosmwasm_std::testing::{ + mock_dependencies, mock_env, mock_info, MockApi, MockQuerier, MockStorage, + }; + use cosmwasm_std::{from_binary, DenomMetadata, DenomUnit, OwnedDeps}; + + fn setup() -> OwnedDeps { + let mut deps = mock_dependencies(); + let msg = Empty {}; + let info = mock_info("creator", &[]); + let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(0, res.messages.len()); + deps + } + + #[test] + fn instantiate_works() { + setup(); + } + + #[test] + fn debug_works() { + let mut deps = setup(); + + let msg = ExecuteMsg::Debug {}; + execute(deps.as_mut(), mock_env(), mock_info("caller", &[]), msg).unwrap(); + } + + #[test] + fn query_denoms_works() { + let mut deps = setup(); + + deps.querier.set_denom_metadata( + &(0..98) + .map(|i| DenomMetadata { + symbol: format!("FOO{i}"), + name: "Foo".to_string(), + description: "Foo coin".to_string(), + denom_units: vec![DenomUnit { + denom: "ufoo".to_string(), + exponent: 8, + aliases: vec!["microfoo".to_string(), "foobar".to_string()], + }], + display: "FOO".to_string(), + base: format!("ufoo{i}"), + uri: "https://foo.bar".to_string(), + uri_hash: "foo".to_string(), + }) + .collect::>(), + ); + + let symbols: Vec = + from_binary(&query(deps.as_ref(), mock_env(), QueryMsg::Denoms {}).unwrap()).unwrap(); + + assert_eq!(symbols.len(), 98); + + let denom: DenomMetadata = from_binary( + &query( + deps.as_ref(), + mock_env(), + QueryMsg::Denom { + denom: "ufoo0".to_string(), + }, + ) + .unwrap(), + ) + .unwrap(); - pub fn mirror_env(env: Env) -> Env { - env + assert_eq!(denom.symbol, "FOO0"); } } diff --git a/contracts/cyberpunk/src/msg.rs b/contracts/cyberpunk/src/msg.rs index 98a03b0b7..c02b51872 100644 --- a/contracts/cyberpunk/src/msg.rs +++ b/contracts/cyberpunk/src/msg.rs @@ -9,8 +9,27 @@ pub enum ExecuteMsg { /// The number of passes. time_cost: u32, }, + /// Infinite loop to burn cpu cycles (only run when metering is enabled) + CpuLoop {}, + /// Infinite loop making storage calls (to test when their limit hits) + StorageLoop {}, + /// Infinite loop reading and writing memory + MemoryLoop {}, + /// Infinite loop sending message to itself + MessageLoop {}, + /// Allocate large amounts of memory without consuming much gas + AllocateLargeMemory { pages: u32 }, + /// Trigger a panic to ensure framework handles gracefully + Panic {}, + /// In contrast to Panic, this does not use the panic handler. + /// + /// From : + /// "Generates the unreachable instruction, which causes an unconditional trap." + Unreachable {}, /// Returns the env for testing MirrorEnv {}, + /// Does a bit of work and calls debug + Debug {}, } #[cw_serde] @@ -19,4 +38,12 @@ pub enum QueryMsg { /// Returns the env for testing #[returns(cosmwasm_std::Env)] MirrorEnv {}, + + /// Queries `AllDenomMetadata` from the bank module repeatedly and returns all entries + #[returns(Vec)] + Denoms {}, + + /// Queries `DenomMetadata` from the bank module and returns the result + #[returns(cosmwasm_std::DenomMetadata)] + Denom { denom: String }, } diff --git a/contracts/cyberpunk/tests/integration.rs b/contracts/cyberpunk/tests/integration.rs index 3de369d23..8abdc74f5 100644 --- a/contracts/cyberpunk/tests/integration.rs +++ b/contracts/cyberpunk/tests/integration.rs @@ -21,6 +21,9 @@ use cosmwasm_std::{from_binary, Empty, Env, Response}; use cosmwasm_vm::testing::{ execute, instantiate, mock_env, mock_info, mock_instance, mock_instance_with_gas_limit, query, }; +use std::io::Write; +use std::time::SystemTime; +use tempfile::NamedTempFile; use cyberpunk::msg::{ExecuteMsg, QueryMsg}; @@ -49,8 +52,87 @@ fn execute_argon2() { // Note: the exact gas usage depends on the Rust version used to compile Wasm, // which we only fix when using rust-optimizer, not integration tests. let expected = 8635688250000; // +/- 20% - assert!(gas_used > expected * 80 / 100, "Gas used: {}", gas_used); - assert!(gas_used < expected * 120 / 100, "Gas used: {}", gas_used); + assert!(gas_used > expected * 80 / 100, "Gas used: {gas_used}"); + assert!(gas_used < expected * 120 / 100, "Gas used: {gas_used}"); +} + +// Test with +// cargo integration-test debug_works -- --nocapture +#[test] +fn debug_works() { + let mut deps = mock_instance_with_gas_limit(WASM, 100_000_000_000_000); + + let _res: Response = + instantiate(&mut deps, mock_env(), mock_info("admin", &[]), Empty {}).unwrap(); + + let msg = ExecuteMsg::Debug {}; + let _res: Response = execute(&mut deps, mock_env(), mock_info("caller", &[]), msg).unwrap(); + + let start = SystemTime::now(); + deps.set_debug_handler(move |msg, info| { + let gas = info.gas_remaining; + let runtime = SystemTime::now().duration_since(start).unwrap().as_micros(); + eprintln!("{msg} (gas: {gas}, runtime: {runtime}µs)"); + }); + + let msg = ExecuteMsg::Debug {}; + let _res: Response = execute(&mut deps, mock_env(), mock_info("caller", &[]), msg).unwrap(); + + eprintln!("Unsetting debug handler. From here nothing is printed anymore."); + deps.unset_debug_handler(); + + let msg = ExecuteMsg::Debug {}; + let _res: Response = execute(&mut deps, mock_env(), mock_info("caller", &[]), msg).unwrap(); +} + +// Test with +// cargo integration-test debug_timing -- --nocapture +#[test] +fn debug_timing() { + let mut deps = mock_instance_with_gas_limit(WASM, 100_000_000_000_000); + + let _res: Response = + instantiate(&mut deps, mock_env(), mock_info("admin", &[]), Empty {}).unwrap(); + + let mut last_time = None; + deps.set_debug_handler(move |msg, _info| { + if let Some(last_time) = last_time { + let diff = SystemTime::now() + .duration_since(last_time) + .unwrap_or_default() + .as_micros(); + eprintln!("{msg} (time since last debug: {diff}µs)"); + } else { + eprintln!("{msg}"); + } + + last_time = Some(SystemTime::now()); + }); + + let msg = ExecuteMsg::Debug {}; + let _res: Response = execute(&mut deps, mock_env(), mock_info("caller", &[]), msg).unwrap(); +} + +#[test] +fn debug_file() { + let mut deps = mock_instance_with_gas_limit(WASM, 100_000_000_000_000); + + let _res: Response = + instantiate(&mut deps, mock_env(), mock_info("admin", &[]), Empty {}).unwrap(); + + let temp_file = NamedTempFile::new().unwrap(); + let (mut temp_file, temp_path) = temp_file.into_parts(); + + deps.set_debug_handler(move |msg, _info| { + writeln!(temp_file, "{msg}").unwrap(); + }); + + let msg = ExecuteMsg::Debug {}; + let _res: Response = execute(&mut deps, mock_env(), mock_info("caller", &[]), msg).unwrap(); + + // check if file contains the expected output + let file_content = std::fs::read_to_string(temp_path).unwrap(); + assert!(file_content.contains("Round 9 done")); } #[test] diff --git a/contracts/floaty/.cargo/config b/contracts/floaty/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/floaty/.cargo/config +++ b/contracts/floaty/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/floaty/Cargo.lock b/contracts/floaty/Cargo.lock index e56b6c506..10871f95b 100644 --- a/contracts/floaty/Cargo.lock +++ b/contracts/floaty/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -259,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -326,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -357,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -420,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -430,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -470,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -484,20 +533,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -511,7 +561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -527,14 +577,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -554,20 +606,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -595,28 +646,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -625,20 +676,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -650,7 +692,6 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "schemars", "serde", @@ -663,27 +704,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -703,30 +769,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -737,13 +794,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -757,7 +811,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -767,50 +821,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -827,49 +883,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -882,42 +914,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -928,42 +960,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -972,22 +982,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1002,7 +1025,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1019,9 +1042,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1043,18 +1066,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1072,9 +1101,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1082,33 +1111,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1124,89 +1152,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1216,21 +1226,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1240,9 +1250,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1254,40 +1264,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1298,14 +1310,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1346,36 +1358,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1388,22 +1412,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1411,53 +1440,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1465,53 +1499,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1531,9 +1579,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1541,24 +1589,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1566,92 +1637,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1663,16 +1726,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1682,184 +1745,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1890,45 +1847,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/floaty/Cargo.toml b/contracts/floaty/Cargo.toml index e16a12643..0aee91625 100644 --- a/contracts/floaty/Cargo.toml +++ b/contracts/floaty/Cargo.toml @@ -35,8 +35,7 @@ cosmwasm-schema = { path = "../../packages/schema" } cosmwasm-std = { path = "../../packages/std" } schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } -thiserror = "1.0" +thiserror = "1.0.26" [dev-dependencies] -cosmwasm-storage = { path = "../../packages/storage" } cosmwasm-vm = { path = "../../packages/vm", default-features = false, features = ["iterator"] } diff --git a/contracts/floaty/schema/raw/execute.json b/contracts/floaty/schema/raw/execute.json new file mode 100644 index 000000000..76967fd17 --- /dev/null +++ b/contracts/floaty/schema/raw/execute.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Releasing all funds in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.", + "type": "object", + "required": [ + "release" + ], + "properties": { + "release": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/floaty/schema/raw/instantiate.json b/contracts/floaty/schema/raw/instantiate.json new file mode 100644 index 000000000..8639103d3 --- /dev/null +++ b/contracts/floaty/schema/raw/instantiate.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "beneficiary", + "verifier" + ], + "properties": { + "beneficiary": { + "type": "string" + }, + "verifier": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/floaty/schema/raw/migrate.json b/contracts/floaty/schema/raw/migrate.json new file mode 100644 index 000000000..76967fd17 --- /dev/null +++ b/contracts/floaty/schema/raw/migrate.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Releasing all funds in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.", + "type": "object", + "required": [ + "release" + ], + "properties": { + "release": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/floaty/schema/raw/query.json b/contracts/floaty/schema/raw/query.json new file mode 100644 index 000000000..b96c3dfb8 --- /dev/null +++ b/contracts/floaty/schema/raw/query.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "returns a human-readable representation of the verifier use to ensure query path works in integration tests", + "type": "object", + "required": [ + "verifier" + ], + "properties": { + "verifier": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "This returns cosmwasm_std::AllBalanceResponse to demo use of the querier", + "type": "object", + "required": [ + "other_balance" + ], + "properties": { + "other_balance": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/floaty/schema/raw/response_to_other_balance.json b/contracts/floaty/schema/raw/response_to_other_balance.json new file mode 100644 index 000000000..20f0a47f1 --- /dev/null +++ b/contracts/floaty/schema/raw/response_to_other_balance.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllBalanceResponse", + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "description": "Returns all non-zero coins held by this account.", + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + }, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/floaty/schema/raw/response_to_verifier.json b/contracts/floaty/schema/raw/response_to_verifier.json new file mode 100644 index 000000000..fb04c86d6 --- /dev/null +++ b/contracts/floaty/schema/raw/response_to_verifier.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifierResponse", + "type": "object", + "required": [ + "verifier" + ], + "properties": { + "verifier": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/floaty/schema/raw/sudo.json b/contracts/floaty/schema/raw/sudo.json new file mode 100644 index 000000000..76967fd17 --- /dev/null +++ b/contracts/floaty/schema/raw/sudo.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Releasing all funds in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.", + "type": "object", + "required": [ + "release" + ], + "properties": { + "release": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/floaty/examples/schema.rs b/contracts/floaty/src/bin/schema.rs similarity index 100% rename from contracts/floaty/examples/schema.rs rename to contracts/floaty/src/bin/schema.rs diff --git a/contracts/hackatom/.cargo/config b/contracts/hackatom/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/hackatom/.cargo/config +++ b/contracts/hackatom/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/hackatom/Cargo.lock b/contracts/hackatom/Cargo.lock index a1268101b..ca1919229 100644 --- a/contracts/hackatom/Cargo.lock +++ b/contracts/hackatom/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -259,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -326,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -357,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -420,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -430,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -470,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -484,20 +533,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -511,7 +561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -527,14 +577,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -554,20 +606,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -595,28 +646,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -625,20 +676,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -650,27 +692,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -690,15 +757,15 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", @@ -711,23 +778,13 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "schemars", "serde", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -738,13 +795,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -758,7 +812,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -768,50 +822,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -828,49 +884,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -883,42 +915,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -929,42 +961,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -973,22 +983,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1003,7 +1026,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1020,9 +1043,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1044,18 +1067,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1073,9 +1102,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1083,33 +1112,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1125,89 +1153,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1217,21 +1227,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1241,9 +1251,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1255,40 +1265,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1299,14 +1311,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1347,36 +1359,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1389,22 +1413,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1412,53 +1441,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1466,53 +1500,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1532,9 +1580,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1542,24 +1590,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1567,92 +1638,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1664,16 +1727,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1683,184 +1746,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1891,45 +1848,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/hackatom/Cargo.toml b/contracts/hackatom/Cargo.toml index 1a91f1100..240bdb147 100644 --- a/contracts/hackatom/Cargo.toml +++ b/contracts/hackatom/Cargo.toml @@ -36,8 +36,7 @@ cosmwasm-std = { path = "../../packages/std", default-features = false, features schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } sha2 = "0.10" -thiserror = "1.0" +thiserror = "1.0.26" [dev-dependencies] -cosmwasm-storage = { path = "../../packages/storage", default-features = false } cosmwasm-vm = { path = "../../packages/vm", default-features = false } diff --git a/contracts/hackatom/schema/raw/execute.json b/contracts/hackatom/schema/raw/execute.json new file mode 100644 index 000000000..a82fdeef2 --- /dev/null +++ b/contracts/hackatom/schema/raw/execute.json @@ -0,0 +1,128 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Releasing all funds in the contract to the beneficiary. This is the only \"proper\" action of this demo contract.", + "type": "object", + "required": [ + "release" + ], + "properties": { + "release": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop to burn cpu cycles (only run when metering is enabled)", + "type": "object", + "required": [ + "cpu_loop" + ], + "properties": { + "cpu_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop making storage calls (to test when their limit hits)", + "type": "object", + "required": [ + "storage_loop" + ], + "properties": { + "storage_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop reading and writing memory", + "type": "object", + "required": [ + "memory_loop" + ], + "properties": { + "memory_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Infinite loop sending message to itself", + "type": "object", + "required": [ + "message_loop" + ], + "properties": { + "message_loop": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Allocate large amounts of memory without consuming much gas", + "type": "object", + "required": [ + "allocate_large_memory" + ], + "properties": { + "allocate_large_memory": { + "type": "object", + "required": [ + "pages" + ], + "properties": { + "pages": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Trigger a panic to ensure framework handles gracefully", + "type": "object", + "required": [ + "panic" + ], + "properties": { + "panic": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Starting with CosmWasm 0.10, some API calls return user errors back to the contract. This triggers such user errors, ensuring the transaction does not fail in the backend.", + "type": "object", + "required": [ + "user_errors_in_api_calls" + ], + "properties": { + "user_errors_in_api_calls": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/hackatom/schema/raw/instantiate.json b/contracts/hackatom/schema/raw/instantiate.json new file mode 100644 index 000000000..8639103d3 --- /dev/null +++ b/contracts/hackatom/schema/raw/instantiate.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "beneficiary", + "verifier" + ], + "properties": { + "beneficiary": { + "type": "string" + }, + "verifier": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/hackatom/schema/raw/migrate.json b/contracts/hackatom/schema/raw/migrate.json new file mode 100644 index 000000000..2696e3ac2 --- /dev/null +++ b/contracts/hackatom/schema/raw/migrate.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "description": "MigrateMsg allows a privileged contract administrator to run a migration on the contract. In this (demo) case it is just migrating from one hackatom code to the same code, but taking advantage of the migration step to set a new validator.\n\nNote that the contract doesn't enforce permissions here, this is done by blockchain logic (in the future by blockchain governance)", + "type": "object", + "required": [ + "verifier" + ], + "properties": { + "verifier": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/hackatom/schema/raw/query.json b/contracts/hackatom/schema/raw/query.json new file mode 100644 index 000000000..dfd58202b --- /dev/null +++ b/contracts/hackatom/schema/raw/query.json @@ -0,0 +1,86 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "returns a human-readable representation of the verifier use to ensure query path works in integration tests", + "type": "object", + "required": [ + "verifier" + ], + "properties": { + "verifier": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "This returns cosmwasm_std::AllBalanceResponse to demo use of the querier", + "type": "object", + "required": [ + "other_balance" + ], + "properties": { + "other_balance": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Recurse will execute a query into itself up to depth-times and return Each step of the recursion may perform some extra work to test gas metering (`work` rounds of sha256 on contract). Now that we have Env, we can auto-calculate the address to recurse into", + "type": "object", + "required": [ + "recurse" + ], + "properties": { + "recurse": { + "type": "object", + "required": [ + "depth", + "work" + ], + "properties": { + "depth": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "work": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "GetInt returns a hardcoded u32 value", + "type": "object", + "required": [ + "get_int" + ], + "properties": { + "get_int": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/hackatom/schema/raw/response_to_get_int.json b/contracts/hackatom/schema/raw/response_to_get_int.json new file mode 100644 index 000000000..018fd695e --- /dev/null +++ b/contracts/hackatom/schema/raw/response_to_get_int.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "IntResponse", + "type": "object", + "required": [ + "int" + ], + "properties": { + "int": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/hackatom/schema/raw/response_to_other_balance.json b/contracts/hackatom/schema/raw/response_to_other_balance.json new file mode 100644 index 000000000..20f0a47f1 --- /dev/null +++ b/contracts/hackatom/schema/raw/response_to_other_balance.json @@ -0,0 +1,38 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllBalanceResponse", + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "description": "Returns all non-zero coins held by this account.", + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + }, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/hackatom/schema/raw/response_to_recurse.json b/contracts/hackatom/schema/raw/response_to_recurse.json new file mode 100644 index 000000000..3d50847ef --- /dev/null +++ b/contracts/hackatom/schema/raw/response_to_recurse.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RecurseResponse", + "type": "object", + "required": [ + "hashed" + ], + "properties": { + "hashed": { + "description": "hashed is the result of running sha256 \"work+1\" times on the contract's human address", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } +} diff --git a/contracts/hackatom/schema/raw/response_to_verifier.json b/contracts/hackatom/schema/raw/response_to_verifier.json new file mode 100644 index 000000000..fb04c86d6 --- /dev/null +++ b/contracts/hackatom/schema/raw/response_to_verifier.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "VerifierResponse", + "type": "object", + "required": [ + "verifier" + ], + "properties": { + "verifier": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/hackatom/schema/raw/sudo.json b/contracts/hackatom/schema/raw/sudo.json new file mode 100644 index 000000000..716b3296a --- /dev/null +++ b/contracts/hackatom/schema/raw/sudo.json @@ -0,0 +1,56 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "SudoMsg", + "description": "SudoMsg is only exposed for internal finschia-sdk modules to call. This is showing how we can expose \"admin\" functionality than can not be called by external users or contracts, but only trusted (native/Go) code in the blockchain", + "oneOf": [ + { + "type": "object", + "required": [ + "steal_funds" + ], + "properties": { + "steal_funds": { + "type": "object", + "required": [ + "amount", + "recipient" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "recipient": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/hackatom/examples/schema.rs b/contracts/hackatom/src/bin/schema.rs similarity index 100% rename from contracts/hackatom/examples/schema.rs rename to contracts/hackatom/src/bin/schema.rs diff --git a/contracts/hackatom/src/contract.rs b/contracts/hackatom/src/contract.rs index 8365b78b5..6de12ab53 100644 --- a/contracts/hackatom/src/contract.rs +++ b/contracts/hackatom/src/contract.rs @@ -189,21 +189,19 @@ fn do_user_errors_in_api_calls(api: &dyn Api) -> Result { StdError::GenericErr { .. } => {} err => { return Err(StdError::generic_err(format!( - "Unexpected error in do_user_errors_in_api_calls: {:?}", - err + "Unexpected error in do_user_errors_in_api_calls: {err:?}" )) .into()) } } - let invalid_bech32 = - "bn9hhssomeltvhzgvuqkwjkpwxojfuigltwedayzxljucefikuieillowaticksoistqoynmgcnj219a"; - match api.addr_canonicalize(invalid_bech32).unwrap_err() { + let too_long = + "bn9hhssomeltvhzgvuqkwjkpwxojfuigltwedayzxljucefikuieillowaticksoistqoynmgcnj219aewfwefwwegwg"; + match api.addr_canonicalize(too_long).unwrap_err() { StdError::GenericErr { .. } => {} err => { return Err(StdError::generic_err(format!( - "Unexpected error in do_user_errors_in_api_calls: {:?}", - err + "Unexpected error in do_user_errors_in_api_calls: {err:?}" )) .into()) } @@ -216,8 +214,7 @@ fn do_user_errors_in_api_calls(api: &dyn Api) -> Result { StdError::GenericErr { .. } => {} err => { return Err(StdError::generic_err(format!( - "Unexpected error in do_user_errors_in_api_calls: {:?}", - err + "Unexpected error in do_user_errors_in_api_calls: {err:?}" )) .into()) } @@ -228,8 +225,7 @@ fn do_user_errors_in_api_calls(api: &dyn Api) -> Result { StdError::GenericErr { .. } => {} err => { return Err(StdError::generic_err(format!( - "Unexpected error in do_user_errors_in_api_calls: {:?}", - err + "Unexpected error in do_user_errors_in_api_calls: {err:?}" )) .into()) } @@ -240,8 +236,7 @@ fn do_user_errors_in_api_calls(api: &dyn Api) -> Result { StdError::GenericErr { .. } => {} err => { return Err(StdError::generic_err(format!( - "Unexpected error in do_user_errors_in_api_calls: {:?}", - err + "Unexpected error in do_user_errors_in_api_calls: {err:?}" )) .into()) } diff --git a/contracts/hackatom/tests/integration.rs b/contracts/hackatom/tests/integration.rs index 84bdf5315..10f77d091 100644 --- a/contracts/hackatom/tests/integration.rs +++ b/contracts/hackatom/tests/integration.rs @@ -407,7 +407,7 @@ fn execute_allocate_large_memory() { // which we only fix when using rust-optimizer, not integration tests. assert_approx_eq!(gas_used, 4413600000, "0.2"); let used = deps.memory_pages(); - assert_eq!(used, pages_before + 48, "Memory used: {} pages", used); + assert_eq!(used, pages_before + 48, "Memory used: {used} pages"); pages_before += 48; // Grow by 1600 pages (100 MiB) @@ -425,10 +425,10 @@ fn execute_allocate_large_memory() { // Note: the exact gas usage depends on the Rust version used to compile Wasm, // which we only fix when using rust-optimizer, not integration tests. let expected = 4859700000; // +/- 20% - assert!(gas_used > expected * 80 / 100, "Gas used: {}", gas_used); - assert!(gas_used < expected * 120 / 100, "Gas used: {}", gas_used); + assert!(gas_used > expected * 80 / 100, "Gas used: {gas_used}"); + assert!(gas_used < expected * 120 / 100, "Gas used: {gas_used}"); let used = deps.memory_pages(); - assert_eq!(used, pages_before, "Memory used: {} pages", used); + assert_eq!(used, pages_before, "Memory used: {used} pages"); } #[test] @@ -458,7 +458,7 @@ fn execute_panic() { ); assert!(msg.contains("contract.rs:"), "Must contain file and line"); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/contracts/ibc-reflect-send/.cargo/config b/contracts/ibc-reflect-send/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/ibc-reflect-send/.cargo/config +++ b/contracts/ibc-reflect-send/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/ibc-reflect-send/Cargo.lock b/contracts/ibc-reflect-send/Cargo.lock index d90b797f8..970cf0c26 100644 --- a/contracts/ibc-reflect-send/Cargo.lock +++ b/contracts/ibc-reflect-send/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -259,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -326,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -357,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -420,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -430,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -470,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -484,20 +533,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -511,7 +561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -527,14 +577,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -554,20 +606,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -595,28 +646,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -625,20 +676,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -650,27 +692,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -690,30 +757,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -724,13 +782,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -744,7 +799,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -753,7 +808,6 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "schemars", "serde", @@ -766,50 +820,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -826,49 +882,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -881,42 +913,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -927,42 +959,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -971,22 +981,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1001,7 +1024,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1018,9 +1041,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1042,18 +1065,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1071,9 +1100,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1081,33 +1110,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1123,89 +1151,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1215,21 +1225,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1239,9 +1249,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1253,40 +1263,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1297,14 +1309,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1345,36 +1357,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1387,22 +1411,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1410,53 +1439,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1464,53 +1498,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1530,9 +1578,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1540,24 +1588,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1565,92 +1636,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1662,16 +1725,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1681,184 +1744,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1889,45 +1846,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/ibc-reflect-send/Cargo.toml b/contracts/ibc-reflect-send/Cargo.toml index 396f36b01..dcbde4a4f 100644 --- a/contracts/ibc-reflect-send/Cargo.toml +++ b/contracts/ibc-reflect-send/Cargo.toml @@ -34,7 +34,6 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } cosmwasm-std = { path = "../../packages/std", features = ["iterator", "staking", "stargate"] } -cosmwasm-storage = { path = "../../packages/storage", features = ["iterator"] } schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/ibc-reflect-send/examples/schema.rs b/contracts/ibc-reflect-send/examples/schema.rs deleted file mode 100644 index 2f8a8d3e7..000000000 --- a/contracts/ibc-reflect-send/examples/schema.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::env::current_dir; - -use cosmwasm_schema::{export_schema, schema_for, write_api}; - -use ibc_reflect_send::ibc_msg::PacketMsg; -use ibc_reflect_send::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; - -fn main() { - // Clear & write standard API - write_api! { - instantiate: InstantiateMsg, - execute: ExecuteMsg, - query: QueryMsg, - } - - // Schemas for inter-contract communication - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - export_schema(&schema_for!(PacketMsg), &out_dir); -} diff --git a/contracts/ibc-reflect-send/schema/ibc-reflect-send.json b/contracts/ibc-reflect-send/schema/ibc-reflect-send.json index 35dd74583..bfd1a75ab 100644 --- a/contracts/ibc-reflect-send/schema/ibc-reflect-send.json +++ b/contracts/ibc-reflect-send/schema/ibc-reflect-send.json @@ -357,6 +357,7 @@ "type": "object" }, "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", "oneOf": [ { "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", @@ -378,7 +379,12 @@ "minimum": 0.0 }, "vote": { - "$ref": "#/definitions/VoteOption" + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] } } } @@ -415,7 +421,7 @@ ] }, "channel_id": { - "description": "exisiting channel to send the tokens over", + "description": "existing channel to send the tokens over", "type": "string" }, "timeout": { @@ -533,7 +539,7 @@ "minimum": 0.0 }, "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", "type": "integer", "format": "uint64", "minimum": 0.0 @@ -690,7 +696,7 @@ "additionalProperties": false }, { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", "type": "object", "required": [ "instantiate" @@ -723,7 +729,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { diff --git a/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_balances.json b/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_balances.json new file mode 100644 index 000000000..4bde7573d --- /dev/null +++ b/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_balances.json @@ -0,0 +1,71 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AcknowledgementMsgBalances", + "description": "A custom acknowledgement type. The success type `T` depends on the PacketMsg variant.\n\nThis could be refactored to use [StdAck] at some point. However, it has a different success variant name (\"ok\" vs. \"result\") and a JSON payload instead of a binary payload.\n\n[StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512", + "oneOf": [ + { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "$ref": "#/definitions/BalancesResponse" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BalancesResponse": { + "description": "This is the success response we send on ack for PacketMsg::Balance. Just acknowledge success or error", + "type": "object", + "required": [ + "account", + "balances" + ], + "properties": { + "account": { + "type": "string" + }, + "balances": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_dispatch.json b/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_dispatch.json new file mode 100644 index 000000000..5c010f5bd --- /dev/null +++ b/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_dispatch.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AcknowledgementMsgDispatch", + "description": "A custom acknowledgement type. The success type `T` depends on the PacketMsg variant.\n\nThis could be refactored to use [StdAck] at some point. However, it has a different success variant name (\"ok\" vs. \"result\") and a JSON payload instead of a binary payload.\n\n[StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512", + "oneOf": [ + { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "type": "null" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_who_am_i.json b/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_who_am_i.json new file mode 100644 index 000000000..e4ad97424 --- /dev/null +++ b/contracts/ibc-reflect-send/schema/ibc/acknowledgement_msg_who_am_i.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AcknowledgementMsgWhoAmI", + "description": "A custom acknowledgement type. The success type `T` depends on the PacketMsg variant.\n\nThis could be refactored to use [StdAck] at some point. However, it has a different success variant name (\"ok\" vs. \"result\") and a JSON payload instead of a binary payload.\n\n[StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512", + "oneOf": [ + { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "$ref": "#/definitions/WhoAmIResponse" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "WhoAmIResponse": { + "description": "This is the success response we send on ack for PacketMsg::WhoAmI. Return the caller's account address on the remote chain", + "type": "object", + "required": [ + "account" + ], + "properties": { + "account": { + "type": "string" + } + } + } + } +} diff --git a/contracts/ibc-reflect-send/schema/ibc/packet_msg.json b/contracts/ibc-reflect-send/schema/ibc/packet_msg.json new file mode 100644 index 000000000..6813122ab --- /dev/null +++ b/contracts/ibc-reflect-send/schema/ibc/packet_msg.json @@ -0,0 +1,772 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PacketMsg", + "description": "This is the message we send over the IBC channel", + "oneOf": [ + { + "type": "object", + "required": [ + "dispatch" + ], + "properties": { + "dispatch": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "who_am_i" + ], + "properties": { + "who_am_i": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "balances" + ], + "properties": { + "balances": { + "type": "object" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto.", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "existing channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto.", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L79-L88). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L110-L119). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L93-L103). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto.", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L71-L82). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L90-L100). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/ibc-reflect-send/schema/raw/execute.json b/contracts/ibc-reflect-send/schema/raw/execute.json new file mode 100644 index 000000000..3218ca8cf --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/execute.json @@ -0,0 +1,823 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Changes the admin", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "send_msgs" + ], + "properties": { + "send_msgs": { + "type": "object", + "required": [ + "channel_id", + "msgs" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "check_remote_balance" + ], + "properties": { + "check_remote_balance": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "If you sent funds to this contract, it will attempt to ibc transfer them to the account on the remote side of this channel. If we don't have the address yet, this fails.", + "type": "object", + "required": [ + "send_funds" + ], + "properties": { + "send_funds": { + "type": "object", + "required": [ + "reflect_channel_id", + "transfer_channel_id" + ], + "properties": { + "reflect_channel_id": { + "description": "The channel id we use above to talk with the reflect contract", + "type": "string" + }, + "transfer_channel_id": { + "description": "The channel to use for ibctransfer. This is bound to a different port and handled by a different module. It should connect to the same chain as the reflect_channel_id does", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto.", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "existing channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto.", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L79-L88). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L110-L119). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L93-L103). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto.", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L71-L82). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L90-L100). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/ibc-reflect-send/schema/raw/instantiate.json b/contracts/ibc-reflect-send/schema/raw/instantiate.json new file mode 100644 index 000000000..4eb2ede31 --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/instantiate.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "This needs no info. Owner of the contract is whoever signed the InstantiateMsg.", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/ibc-reflect-send/schema/packet_msg.json b/contracts/ibc-reflect-send/schema/raw/migrate.json similarity index 91% rename from contracts/ibc-reflect-send/schema/packet_msg.json rename to contracts/ibc-reflect-send/schema/raw/migrate.json index d49111754..e9b7d2101 100644 --- a/contracts/ibc-reflect-send/schema/packet_msg.json +++ b/contracts/ibc-reflect-send/schema/raw/migrate.json @@ -1,27 +1,53 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PacketMsg", - "description": "This is the message we send over the IBC channel", + "title": "ExecuteMsg", "oneOf": [ { + "description": "Changes the admin", "type": "object", "required": [ - "dispatch" + "update_admin" ], "properties": { - "dispatch": { + "update_admin": { "type": "object", "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "send_msgs" + ], + "properties": { + "send_msgs": { + "type": "object", + "required": [ + "channel_id", "msgs" ], "properties": { + "channel_id": { + "type": "string" + }, "msgs": { "type": "array", "items": { "$ref": "#/definitions/CosmosMsg_for_Empty" } } - } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -29,23 +55,48 @@ { "type": "object", "required": [ - "who_am_i" + "check_remote_balance" ], "properties": { - "who_am_i": { - "type": "object" + "check_remote_balance": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false }, { + "description": "If you sent funds to this contract, it will attempt to ibc transfer them to the account on the remote side of this channel. If we don't have the address yet, this fails.", "type": "object", "required": [ - "balances" + "send_funds" ], "properties": { - "balances": { - "type": "object" + "send_funds": { + "type": "object", + "required": [ + "reflect_channel_id", + "transfer_channel_id" + ], + "properties": { + "reflect_channel_id": { + "description": "The channel id we use above to talk with the reflect contract", + "type": "string" + }, + "transfer_channel_id": { + "description": "The channel to use for ibctransfer. This is bound to a different port and handled by a different module. It should connect to the same chain as the reflect_channel_id does", + "type": "string" + } + }, + "additionalProperties": false } }, "additionalProperties": false @@ -628,7 +679,7 @@ "additionalProperties": false }, { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/wasmd/blob/v0.2.0/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", "type": "object", "required": [ "instantiate" @@ -763,4 +814,4 @@ ] } } -} +} \ No newline at end of file diff --git a/contracts/ibc-reflect-send/schema/raw/query.json b/contracts/ibc-reflect-send/schema/raw/query.json new file mode 100644 index 000000000..05a60cc1b --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/query.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list_accounts" + ], + "properties": { + "list_accounts": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "account" + ], + "properties": { + "account": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/ibc-reflect-send/schema/raw/response_to_account.json b/contracts/ibc-reflect-send/schema/raw/response_to_account.json new file mode 100644 index 000000000..3b022b2f5 --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/response_to_account.json @@ -0,0 +1,70 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AccountInfo", + "type": "object", + "required": [ + "channel_id", + "last_update_time", + "remote_balance" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "last_update_time": { + "description": "last block balance was updated (0 is never)", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "remote_addr": { + "description": "in normal cases, it should be set, but there is a delay between binding the channel and making a query and in that time it is empty", + "type": [ + "string", + "null" + ] + }, + "remote_balance": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/ibc-reflect-send/schema/raw/response_to_admin.json b/contracts/ibc-reflect-send/schema/raw/response_to_admin.json new file mode 100644 index 000000000..627be7a02 --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/response_to_admin.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AdminResponse", + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/ibc-reflect-send/schema/raw/response_to_list_accounts.json b/contracts/ibc-reflect-send/schema/raw/response_to_list_accounts.json new file mode 100644 index 000000000..bb03b416b --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/response_to_list_accounts.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ListAccountsResponse", + "type": "object", + "required": [ + "accounts" + ], + "properties": { + "accounts": { + "type": "array", + "items": { + "$ref": "#/definitions/AccountInfo" + } + } + }, + "additionalProperties": false, + "definitions": { + "AccountInfo": { + "type": "object", + "required": [ + "channel_id", + "last_update_time", + "remote_balance" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "last_update_time": { + "description": "last block balance was updated (0 is never)", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "remote_addr": { + "description": "in normal cases, it should be set, but there is a delay between binding the channel and making a query and in that time it is empty", + "type": [ + "string", + "null" + ] + }, + "remote_balance": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + }, + "additionalProperties": false + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/ibc-reflect-send/schema/raw/sudo.json b/contracts/ibc-reflect-send/schema/raw/sudo.json new file mode 100644 index 000000000..a382cb2aa --- /dev/null +++ b/contracts/ibc-reflect-send/schema/raw/sudo.json @@ -0,0 +1,817 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Changes the admin", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "send_msgs" + ], + "properties": { + "send_msgs": { + "type": "object", + "required": [ + "channel_id", + "msgs" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "check_remote_balance" + ], + "properties": { + "check_remote_balance": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "If you sent funds to this contract, it will attempt to ibc transfer them to the account on the remote side of this channel. If we don't have the address yet, this fails.", + "type": "object", + "required": [ + "send_funds" + ], + "properties": { + "send_funds": { + "type": "object", + "required": [ + "reflect_channel_id", + "transfer_channel_id" + ], + "properties": { + "reflect_channel_id": { + "description": "The channel id we use above to talk with the reflect contract", + "type": "string" + }, + "transfer_channel_id": { + "description": "The channel to use for ibctransfer. This is bound to a different port and handled by a different module. It should connect to the same chain as the reflect_channel_id does", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_Empty": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/Empty" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Empty": { + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" + }, + "GovMsg": { + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/VoteOption" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/ibc-reflect-send/src/bin/schema.rs b/contracts/ibc-reflect-send/src/bin/schema.rs new file mode 100644 index 000000000..cb7ea0716 --- /dev/null +++ b/contracts/ibc-reflect-send/src/bin/schema.rs @@ -0,0 +1,38 @@ +use std::env::current_dir; + +use cosmwasm_schema::{export_schema, export_schema_with_title, schema_for, write_api}; + +use ibc_reflect_send::ibc_msg::{ + AcknowledgementMsg, BalancesResponse, DispatchResponse, PacketMsg, WhoAmIResponse, +}; +use ibc_reflect_send::msg::{ExecuteMsg, InstantiateMsg, QueryMsg}; + +fn main() { + // Clear & write standard API + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + query: QueryMsg, + } + + // Schemas for inter-contract communication + let mut out_dir = current_dir().unwrap(); + out_dir.push("schema"); + out_dir.push("ibc"); + export_schema(&schema_for!(PacketMsg), &out_dir); + export_schema_with_title( + &schema_for!(AcknowledgementMsg), + &out_dir, + "AcknowledgementMsgBalances", + ); + export_schema_with_title( + &schema_for!(AcknowledgementMsg), + &out_dir, + "AcknowledgementMsgDispatch", + ); + export_schema_with_title( + &schema_for!(AcknowledgementMsg), + &out_dir, + "AcknowledgementMsgWhoAmI", + ); +} diff --git a/contracts/ibc-reflect-send/src/contract.rs b/contracts/ibc-reflect-send/src/contract.rs index 3784fc57c..50d074f3a 100644 --- a/contracts/ibc-reflect-send/src/contract.rs +++ b/contracts/ibc-reflect-send/src/contract.rs @@ -1,6 +1,6 @@ use cosmwasm_std::{ - entry_point, to_binary, CosmosMsg, Deps, DepsMut, Env, IbcMsg, MessageInfo, Order, - QueryResponse, Response, StdError, StdResult, + entry_point, to_binary, CosmosMsg, Deps, DepsMut, Env, IbcMsg, MessageInfo, QueryResponse, + Response, StdError, StdResult, }; use crate::ibc::PACKET_LIFETIME; @@ -9,7 +9,7 @@ use crate::msg::{ AccountInfo, AccountResponse, AdminResponse, ExecuteMsg, InstantiateMsg, ListAccountsResponse, QueryMsg, }; -use crate::state::{accounts, accounts_read, config, config_read, Config}; +use crate::state::{load_account, load_config, range_accounts, save_config, Config}; #[entry_point] pub fn instantiate( @@ -20,7 +20,7 @@ pub fn instantiate( ) -> StdResult { // we store the reflect_id for creating accounts later let cfg = Config { admin: info.sender }; - config(deps.storage).save(&cfg)?; + save_config(deps.storage, &cfg)?; Ok(Response::new().add_attribute("action", "instantiate")) } @@ -48,12 +48,12 @@ pub fn handle_update_admin( new_admin: String, ) -> StdResult { // auth check - let mut cfg = config(deps.storage).load()?; + let mut cfg = load_config(deps.storage)?; if info.sender != cfg.admin { return Err(StdError::generic_err("Only admin may set new admin")); } cfg.admin = deps.api.addr_validate(&new_admin)?; - config(deps.storage).save(&cfg)?; + save_config(deps.storage, &cfg)?; Ok(Response::new() .add_attribute("action", "handle_update_admin") @@ -68,12 +68,12 @@ pub fn handle_send_msgs( msgs: Vec, ) -> StdResult { // auth check - let cfg = config(deps.storage).load()?; + let cfg = load_config(deps.storage)?; if info.sender != cfg.admin { return Err(StdError::generic_err("Only admin may send messages")); } // ensure the channel exists (not found if not registered) - accounts(deps.storage).load(channel_id.as_bytes())?; + load_account(deps.storage, &channel_id)?; // construct a packet to send let packet = PacketMsg::Dispatch { msgs }; @@ -96,12 +96,12 @@ pub fn handle_check_remote_balance( channel_id: String, ) -> StdResult { // auth check - let cfg = config(deps.storage).load()?; + let cfg = load_config(deps.storage)?; if info.sender != cfg.admin { return Err(StdError::generic_err("Only admin may send messages")); } // ensure the channel exists (not found if not registered) - accounts(deps.storage).load(channel_id.as_bytes())?; + load_account(deps.storage, &channel_id)?; // construct a packet to send let packet = PacketMsg::Balances {}; @@ -141,7 +141,7 @@ pub fn handle_send_funds( } // load remote account - let data = accounts(deps.storage).load(reflect_channel_id.as_bytes())?; + let data = load_account(deps.storage, &reflect_channel_id)?; let remote_addr = match data.remote_addr { Some(addr) => addr, None => { @@ -175,16 +175,14 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } fn query_account(deps: Deps, channel_id: String) -> StdResult { - let account = accounts_read(deps.storage).load(channel_id.as_bytes())?; + let account = load_account(deps.storage, &channel_id)?; Ok(account.into()) } fn query_list_accounts(deps: Deps) -> StdResult { - let accounts: StdResult> = accounts_read(deps.storage) - .range(None, None, Order::Ascending) + let accounts: StdResult> = range_accounts(deps.storage) .map(|r| { - let (k, account) = r?; - let channel_id = String::from_utf8(k)?; + let (channel_id, account) = r?; Ok(AccountInfo::convert(channel_id, account)) }) .collect(); @@ -194,7 +192,7 @@ fn query_list_accounts(deps: Deps) -> StdResult { } fn query_admin(deps: Deps) -> StdResult { - let Config { admin } = config_read(deps.storage).load()?; + let Config { admin } = load_config(deps.storage)?; Ok(AdminResponse { admin: admin.into(), }) diff --git a/contracts/ibc-reflect-send/src/ibc.rs b/contracts/ibc-reflect-send/src/ibc.rs index dca8cbf78..634fed3e8 100644 --- a/contracts/ibc-reflect-send/src/ibc.rs +++ b/contracts/ibc-reflect-send/src/ibc.rs @@ -1,13 +1,13 @@ use cosmwasm_std::{ entry_point, from_slice, to_binary, DepsMut, Env, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcMsg, IbcOrder, IbcPacketAckMsg, - IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, StdError, StdResult, + IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, Never, StdError, StdResult, }; use crate::ibc_msg::{ AcknowledgementMsg, BalancesResponse, DispatchResponse, PacketMsg, WhoAmIResponse, }; -use crate::state::{accounts, AccountData}; +use crate::state::{may_load_account, remove_account, save_account, AccountData}; pub const IBC_APP_VERSION: &str = "ibc-reflect-v1"; @@ -25,16 +25,14 @@ pub fn ibc_channel_open(_deps: DepsMut, _env: Env, msg: IbcChannelOpenMsg) -> St } if channel.version.as_str() != IBC_APP_VERSION { return Err(StdError::generic_err(format!( - "Must set version to `{}`", - IBC_APP_VERSION + "Must set version to `{IBC_APP_VERSION}`" ))); } if let Some(counter_version) = msg.counterparty_version() { if counter_version != IBC_APP_VERSION { return Err(StdError::generic_err(format!( - "Counterparty version must be `{}`", - IBC_APP_VERSION + "Counterparty version must be `{IBC_APP_VERSION}`" ))); } } @@ -55,7 +53,7 @@ pub fn ibc_channel_connect( // create an account holder the channel exists (not found if not registered) let data = AccountData::default(); - accounts(deps.storage).save(channel_id.as_bytes(), &data)?; + save_account(deps.storage, channel_id, &data)?; // construct a packet to send let packet = PacketMsg::WhoAmI {}; @@ -82,7 +80,7 @@ pub fn ibc_channel_close( // remove the channel let channel_id = &channel.endpoint.channel_id; - accounts(deps.storage).remove(channel_id.as_bytes()); + remove_account(deps.storage, channel_id); Ok(IbcBasicResponse::new() .add_attribute("action", "ibc_close") @@ -95,7 +93,7 @@ pub fn ibc_packet_receive( _deps: DepsMut, _env: Env, _packet: IbcPacketReceiveMsg, -) -> StdResult { +) -> Result { Ok(IbcReceiveResponse::new() .set_ack(b"{}") .add_attribute("action", "ibc_packet_ack")) @@ -148,25 +146,22 @@ fn acknowledge_who_am_i( // ignore errors (but mention in log) let WhoAmIResponse { account } = match ack { AcknowledgementMsg::Ok(res) => res, - AcknowledgementMsg::Err(e) => { + AcknowledgementMsg::Error(e) => { return Ok(IbcBasicResponse::new() .add_attribute("action", "acknowledge_who_am_i") .add_attribute("error", e)) } }; - - accounts(deps.storage).update(caller.as_bytes(), |acct| -> StdResult<_> { - match acct { - Some(mut acct) => { - // set the account the first time - if acct.remote_addr.is_none() { - acct.remote_addr = Some(account); - } - Ok(acct) + match may_load_account(deps.storage, &caller)? { + Some(mut acct) => { + // set the account the first time + if acct.remote_addr.is_none() { + acct.remote_addr = Some(account); } - None => Err(StdError::generic_err("no account to update")), + save_account(deps.storage, &caller, &acct)?; } - })?; + None => return Err(StdError::generic_err("no account to update")), + } Ok(IbcBasicResponse::new().add_attribute("action", "acknowledge_who_am_i")) } @@ -181,33 +176,34 @@ fn acknowledge_balances( // ignore errors (but mention in log) let BalancesResponse { account, balances } = match ack { AcknowledgementMsg::Ok(res) => res, - AcknowledgementMsg::Err(e) => { + AcknowledgementMsg::Error(e) => { return Ok(IbcBasicResponse::new() .add_attribute("action", "acknowledge_balances") .add_attribute("error", e)) } }; - accounts(deps.storage).update(caller.as_bytes(), |acct| -> StdResult<_> { - match acct { - Some(acct) => { - if let Some(old_addr) = acct.remote_addr { - if old_addr != account { - return Err(StdError::generic_err(format!( - "remote account changed from {} to {}", - old_addr, account - ))); - } + match may_load_account(deps.storage, &caller)? { + Some(acct) => { + if let Some(old_addr) = acct.remote_addr { + if old_addr != account { + return Err(StdError::generic_err(format!( + "remote account changed from {old_addr} to {account}" + ))); } - Ok(AccountData { + } + save_account( + deps.storage, + &caller, + &AccountData { last_update_time: env.block.time, remote_addr: Some(account), remote_balance: balances, - }) - } - None => Err(StdError::generic_err("no account to update")), + }, + )?; } - })?; + None => return Err(StdError::generic_err("no account to update")), + } Ok(IbcBasicResponse::new().add_attribute("action", "acknowledge_balances")) } @@ -266,7 +262,7 @@ mod tests { channel_id: packet_channel, .. }) => assert_eq!(packet_channel.as_str(), channel_id), - o => panic!("Unexpected message: {:?}", o), + o => panic!("Unexpected message: {o:?}"), }; } @@ -363,7 +359,7 @@ mod tests { msg.original_packet.data = data; msg } - o => panic!("Unexpected message: {:?}", o), + o => panic!("Unexpected message: {o:?}"), }; let res = ibc_packet_ack(deps.as_mut(), mock_env(), msg).unwrap(); // no actions expected, but let's check the events to see it was dispatched properly @@ -421,7 +417,7 @@ mod tests { assert!(timeout.block().is_none()); assert!(timeout.timestamp().is_some()); } - o => panic!("unexpected message: {:?}", o), + o => panic!("unexpected message: {o:?}"), } } } diff --git a/contracts/ibc-reflect-send/src/ibc_msg.rs b/contracts/ibc-reflect-send/src/ibc_msg.rs index d395388c3..ca6041218 100644 --- a/contracts/ibc-reflect-send/src/ibc_msg.rs +++ b/contracts/ibc-reflect-send/src/ibc_msg.rs @@ -1,4 +1,5 @@ -use cosmwasm_std::{Coin, ContractResult, CosmosMsg}; +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Coin, CosmosMsg}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -11,9 +12,35 @@ pub enum PacketMsg { Balances {}, } -/// All IBC acknowledgements are wrapped in `ContractResult`. -/// The success value depends on the PacketMsg variant. -pub type AcknowledgementMsg = ContractResult; +/// A custom acknowledgement type. +/// The success type `T` depends on the PacketMsg variant. +/// +/// This could be refactored to use [StdAck] at some point. However, +/// it has a different success variant name ("ok" vs. "result") and +/// a JSON payload instead of a binary payload. +/// +/// [StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512 +#[cw_serde] +pub enum AcknowledgementMsg { + Ok(S), + Error(String), +} + +impl AcknowledgementMsg { + pub fn unwrap(self) -> S { + match self { + AcknowledgementMsg::Ok(data) => data, + AcknowledgementMsg::Error(err) => panic!("{}", err), + } + } + + pub fn unwrap_err(self) -> String { + match self { + AcknowledgementMsg::Ok(_) => panic!("not an error"), + AcknowledgementMsg::Error(err) => err, + } + } +} /// This is the success response we send on ack for PacketMsg::Dispatch. /// Just acknowledge success or error diff --git a/contracts/ibc-reflect-send/src/state.rs b/contracts/ibc-reflect-send/src/state.rs index a44d66b1d..062ff187e 100644 --- a/contracts/ibc-reflect-send/src/state.rs +++ b/contracts/ibc-reflect-send/src/state.rs @@ -1,13 +1,16 @@ use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, Coin, Storage, Timestamp}; -use cosmwasm_storage::{ - bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton, - Singleton, +use cosmwasm_std::{ + from_slice, + storage_keys::{namespace_with_key, to_length_prefixed}, + to_vec, Addr, Coin, Order, StdError, StdResult, Storage, Timestamp, }; pub const KEY_CONFIG: &[u8] = b"config"; +/// accounts is lookup of channel_id to reflect contract pub const PREFIX_ACCOUNTS: &[u8] = b"accounts"; +/// Upper bound for ranging over accounts +const PREFIX_ACCOUNTS_UPPER_BOUND: &[u8] = b"accountt"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub struct Config { @@ -27,19 +30,52 @@ pub struct AccountData { pub remote_balance: Vec, } -/// accounts is lookup of channel_id to reflect contract -pub fn accounts(storage: &mut dyn Storage) -> Bucket { - bucket(storage, PREFIX_ACCOUNTS) +pub fn may_load_account(storage: &dyn Storage, id: &str) -> StdResult> { + storage + .get(&namespace_with_key(&[PREFIX_ACCOUNTS], id.as_bytes())) + .map(|v| from_slice(&v)) + .transpose() +} + +pub fn load_account(storage: &dyn Storage, id: &str) -> StdResult { + may_load_account(storage, id)?.ok_or_else(|| StdError::not_found(format!("account {id}"))) +} + +pub fn save_account(storage: &mut dyn Storage, id: &str, account: &AccountData) -> StdResult<()> { + storage.set( + &namespace_with_key(&[PREFIX_ACCOUNTS], id.as_bytes()), + &to_vec(account)?, + ); + Ok(()) +} + +pub fn remove_account(storage: &mut dyn Storage, id: &str) { + storage.remove(&namespace_with_key(&[PREFIX_ACCOUNTS], id.as_bytes())); } -pub fn accounts_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, PREFIX_ACCOUNTS) +pub fn range_accounts( + storage: &dyn Storage, +) -> impl Iterator> + '_ { + let prefix = to_length_prefixed(PREFIX_ACCOUNTS); + let upper_bound = to_length_prefixed(PREFIX_ACCOUNTS_UPPER_BOUND); + storage + .range(Some(&prefix), Some(&upper_bound), Order::Ascending) + .map(|(key, val)| { + Ok(( + String::from_utf8(key[PREFIX_ACCOUNTS.len() + 2..].to_vec())?, + from_slice(&val)?, + )) + }) } -pub fn config(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_CONFIG) +pub fn load_config(storage: &dyn Storage) -> StdResult { + storage + .get(&to_length_prefixed(KEY_CONFIG)) + .ok_or_else(|| StdError::not_found("config")) + .and_then(|v| from_slice(&v)) } -pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, KEY_CONFIG) +pub fn save_config(storage: &mut dyn Storage, item: &Config) -> StdResult<()> { + storage.set(&to_length_prefixed(KEY_CONFIG), &to_vec(item)?); + Ok(()) } diff --git a/contracts/ibc-reflect-send/tests/integration.rs b/contracts/ibc-reflect-send/tests/integration.rs index c0c2977b8..21d5c9535 100644 --- a/contracts/ibc-reflect-send/tests/integration.rs +++ b/contracts/ibc-reflect-send/tests/integration.rs @@ -72,7 +72,7 @@ fn connect(deps: &mut Instance, channel_id: & channel_id: packet_channel, .. }) => assert_eq!(packet_channel.as_str(), channel_id), - o => panic!("Unexpected message: {:?}", o), + o => panic!("Unexpected message: {o:?}"), }; } @@ -183,7 +183,7 @@ fn dispatch_message_send_and_ack() { msg.original_packet.data = data; msg } - o => panic!("Unexpected message: {:?}", o), + o => panic!("Unexpected message: {o:?}"), }; let res: IbcBasicResponse = ibc_packet_ack(&mut deps, mock_env(), msg).unwrap(); // no actions expected, but let's check the events to see it was dispatched properly @@ -241,6 +241,6 @@ fn send_remote_funds() { assert!(timeout.block().is_none()); assert!(timeout.timestamp().is_some()); } - o => panic!("unexpected message: {:?}", o), + o => panic!("unexpected message: {o:?}"), } } diff --git a/contracts/ibc-reflect/.cargo/config b/contracts/ibc-reflect/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/ibc-reflect/.cargo/config +++ b/contracts/ibc-reflect/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/ibc-reflect/Cargo.lock b/contracts/ibc-reflect/Cargo.lock index d250860e6..71dbd710d 100644 --- a/contracts/ibc-reflect/Cargo.lock +++ b/contracts/ibc-reflect/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -259,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -326,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -357,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -420,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -430,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -470,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -484,20 +533,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -511,7 +561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -527,14 +577,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -554,20 +606,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -595,28 +646,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -625,20 +676,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -650,27 +692,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -690,30 +757,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -724,13 +782,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -744,7 +799,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -753,7 +808,6 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "schemars", "serde", @@ -766,50 +820,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -826,49 +882,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -881,42 +913,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -927,42 +959,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -971,22 +981,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1001,7 +1024,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1018,9 +1041,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1042,18 +1065,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1071,9 +1100,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1081,33 +1110,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1123,89 +1151,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1215,21 +1225,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1239,9 +1249,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1253,40 +1263,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1297,14 +1309,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1345,36 +1357,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1387,22 +1411,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1410,53 +1439,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1464,53 +1498,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1530,9 +1578,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1540,24 +1588,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1565,92 +1636,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1662,16 +1725,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1681,184 +1744,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1889,45 +1846,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/ibc-reflect/Cargo.toml b/contracts/ibc-reflect/Cargo.toml index ca0b44bd3..ead27d372 100644 --- a/contracts/ibc-reflect/Cargo.toml +++ b/contracts/ibc-reflect/Cargo.toml @@ -34,7 +34,6 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } cosmwasm-std = { path = "../../packages/std", features = ["iterator", "ibc3"] } -cosmwasm-storage = { path = "../../packages/storage", features = ["iterator"] } schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/ibc-reflect/schema/acknowledgement_msg_dispatch.json b/contracts/ibc-reflect/schema/acknowledgement_msg_dispatch.json deleted file mode 100644 index e89f54b65..000000000 --- a/contracts/ibc-reflect/schema/acknowledgement_msg_dispatch.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AcknowledgementMsgDispatch", - "description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```", - "oneOf": [ - { - "type": "object", - "required": [ - "ok" - ], - "properties": { - "ok": { - "type": "null" - } - }, - "additionalProperties": false - }, - { - "description": "An error type that every custom error created by contract developers can be converted to. This could potientially have more structure, but String is the easiest.", - "type": "object", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - } - }, - "additionalProperties": false - } - ] -} diff --git a/contracts/ibc-reflect/schema/acknowledgement_msg_who_am_i.json b/contracts/ibc-reflect/schema/acknowledgement_msg_who_am_i.json deleted file mode 100644 index 57c0933f8..000000000 --- a/contracts/ibc-reflect/schema/acknowledgement_msg_who_am_i.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "AcknowledgementMsgWhoAmI", - "description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```", - "oneOf": [ - { - "type": "object", - "required": [ - "ok" - ], - "properties": { - "ok": { - "$ref": "#/definitions/WhoAmIResponse" - } - }, - "additionalProperties": false - }, - { - "description": "An error type that every custom error created by contract developers can be converted to. This could potientially have more structure, but String is the easiest.", - "type": "object", - "required": [ - "error" - ], - "properties": { - "error": { - "type": "string" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "WhoAmIResponse": { - "description": "This is the success response we send on ack for PacketMsg::WhoAmI. Return the caller's account address on the remote chain", - "type": "object", - "required": [ - "account" - ], - "properties": { - "account": { - "type": "string" - } - }, - "additionalProperties": false - } - } -} diff --git a/contracts/ibc-reflect/schema/acknowledgement_msg_balances.json b/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_balances.json similarity index 59% rename from contracts/ibc-reflect/schema/acknowledgement_msg_balances.json rename to contracts/ibc-reflect/schema/ibc/acknowledgement_msg_balances.json index 20e956cd3..b181c2855 100644 --- a/contracts/ibc-reflect/schema/acknowledgement_msg_balances.json +++ b/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_balances.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "AcknowledgementMsgBalances", - "description": "This is the final result type that is created and serialized in a contract for every init/execute/migrate call. The VM then deserializes this type to distinguish between successful and failed executions.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let response: Response = Response::default(); let result: ContractResult = ContractResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"messages\":[],\"attributes\":[],\"events\":[],\"data\":null}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, ContractResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result: ContractResult = ContractResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```", + "description": "A custom acknowledgement type. The success type `T` depends on the PacketMsg variant.\n\nThis could be refactored to use [StdAck] at some point. However, it has a different success variant name (\"ok\" vs. \"result\") and a JSON payload instead of a binary payload.\n\n[StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512", "oneOf": [ { "type": "object", @@ -16,7 +16,6 @@ "additionalProperties": false }, { - "description": "An error type that every custom error created by contract developers can be converted to. This could potientially have more structure, but String is the easiest.", "type": "object", "required": [ "error" diff --git a/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_dispatch.json b/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_dispatch.json new file mode 100644 index 000000000..5c010f5bd --- /dev/null +++ b/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_dispatch.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AcknowledgementMsgDispatch", + "description": "A custom acknowledgement type. The success type `T` depends on the PacketMsg variant.\n\nThis could be refactored to use [StdAck] at some point. However, it has a different success variant name (\"ok\" vs. \"result\") and a JSON payload instead of a binary payload.\n\n[StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512", + "oneOf": [ + { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "type": "null" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_who_am_i.json b/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_who_am_i.json new file mode 100644 index 000000000..f706c655d --- /dev/null +++ b/contracts/ibc-reflect/schema/ibc/acknowledgement_msg_who_am_i.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AcknowledgementMsgWhoAmI", + "description": "A custom acknowledgement type. The success type `T` depends on the PacketMsg variant.\n\nThis could be refactored to use [StdAck] at some point. However, it has a different success variant name (\"ok\" vs. \"result\") and a JSON payload instead of a binary payload.\n\n[StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512", + "oneOf": [ + { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "$ref": "#/definitions/WhoAmIResponse" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + }, + "additionalProperties": false + } + ], + "definitions": { + "WhoAmIResponse": { + "description": "This is the success response we send on ack for PacketMsg::WhoAmI. Return the caller's account address on the remote chain", + "type": "object", + "required": [ + "account" + ], + "properties": { + "account": { + "type": "string" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/ibc-reflect/schema/packet_msg.json b/contracts/ibc-reflect/schema/ibc/packet_msg.json similarity index 84% rename from contracts/ibc-reflect/schema/packet_msg.json rename to contracts/ibc-reflect/schema/ibc/packet_msg.json index 58dabd857..f1f6f8d66 100644 --- a/contracts/ibc-reflect/schema/packet_msg.json +++ b/contracts/ibc-reflect/schema/ibc/packet_msg.json @@ -51,6 +51,64 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "panic" + ], + "properties": { + "panic": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "return_err" + ], + "properties": { + "return_err": { + "type": "object", + "required": [ + "text" + ], + "properties": { + "text": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "return_msgs" + ], + "properties": { + "return_msgs": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_Empty" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { @@ -224,6 +282,7 @@ "type": "object" }, "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", "oneOf": [ { "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", @@ -245,7 +304,12 @@ "minimum": 0.0 }, "vote": { - "$ref": "#/definitions/VoteOption" + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] } } } @@ -282,7 +346,7 @@ ] }, "channel_id": { - "description": "exisiting channel to send the tokens over", + "description": "existing channel to send the tokens over", "type": "string" }, "timeout": { @@ -400,7 +464,7 @@ "minimum": 0.0 }, "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", "type": "integer", "format": "uint64", "minimum": 0.0 @@ -473,7 +537,7 @@ "additionalProperties": false }, { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", "type": "object", "required": [ "instantiate" @@ -506,7 +570,7 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { diff --git a/contracts/ibc-reflect/schema/raw/instantiate.json b/contracts/ibc-reflect/schema/raw/instantiate.json new file mode 100644 index 000000000..1320f1a0b --- /dev/null +++ b/contracts/ibc-reflect/schema/raw/instantiate.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "Just needs to know the code_id of a reflect contract to spawn sub-accounts", + "type": "object", + "required": [ + "reflect_code_id" + ], + "properties": { + "reflect_code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/ibc-reflect/schema/raw/migrate.json b/contracts/ibc-reflect/schema/raw/migrate.json new file mode 100644 index 000000000..2bba95824 --- /dev/null +++ b/contracts/ibc-reflect/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" +} diff --git a/contracts/ibc-reflect/schema/raw/query.json b/contracts/ibc-reflect/schema/raw/query.json new file mode 100644 index 000000000..2fb7b34e6 --- /dev/null +++ b/contracts/ibc-reflect/schema/raw/query.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Returns (reflect) account that is attached to this channel, or none.", + "type": "object", + "required": [ + "account" + ], + "properties": { + "account": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Returns all (channel, reflect_account) pairs. No pagination - this is a test contract", + "type": "object", + "required": [ + "list_accounts" + ], + "properties": { + "list_accounts": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/ibc-reflect/schema/raw/response_to_account.json b/contracts/ibc-reflect/schema/raw/response_to_account.json new file mode 100644 index 000000000..84edc87b9 --- /dev/null +++ b/contracts/ibc-reflect/schema/raw/response_to_account.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AccountResponse", + "type": "object", + "properties": { + "account": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false +} diff --git a/contracts/ibc-reflect/schema/raw/response_to_list_accounts.json b/contracts/ibc-reflect/schema/raw/response_to_list_accounts.json new file mode 100644 index 000000000..22591bd06 --- /dev/null +++ b/contracts/ibc-reflect/schema/raw/response_to_list_accounts.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ListAccountsResponse", + "type": "object", + "required": [ + "accounts" + ], + "properties": { + "accounts": { + "type": "array", + "items": { + "$ref": "#/definitions/AccountInfo" + } + } + }, + "additionalProperties": false, + "definitions": { + "AccountInfo": { + "type": "object", + "required": [ + "account", + "channel_id" + ], + "properties": { + "account": { + "type": "string" + }, + "channel_id": { + "type": "string" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/ibc-reflect/examples/schema.rs b/contracts/ibc-reflect/src/bin/schema.rs similarity index 97% rename from contracts/ibc-reflect/examples/schema.rs rename to contracts/ibc-reflect/src/bin/schema.rs index 74b340838..5103b778f 100644 --- a/contracts/ibc-reflect/examples/schema.rs +++ b/contracts/ibc-reflect/src/bin/schema.rs @@ -19,6 +19,7 @@ fn main() { // Schemas for inter-contract communication let mut out_dir = current_dir().unwrap(); out_dir.push("schema"); + out_dir.push("ibc"); export_schema(&schema_for!(PacketMsg), &out_dir); export_schema_with_title( &schema_for!(AcknowledgementMsg), diff --git a/contracts/ibc-reflect/src/contract.rs b/contracts/ibc-reflect/src/contract.rs index a43e58146..1af5d90e9 100644 --- a/contracts/ibc-reflect/src/contract.rs +++ b/contracts/ibc-reflect/src/contract.rs @@ -2,16 +2,20 @@ use cosmwasm_std::{ entry_point, from_slice, to_binary, wasm_execute, BankMsg, Binary, CosmosMsg, Deps, DepsMut, Empty, Env, Event, Ibc3ChannelOpenResponse, IbcBasicResponse, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcOrder, IbcPacketAckMsg, - IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Order, + IbcPacketReceiveMsg, IbcPacketTimeoutMsg, IbcReceiveResponse, MessageInfo, Never, QueryResponse, Reply, Response, StdError, StdResult, SubMsg, SubMsgResponse, SubMsgResult, WasmMsg, }; use crate::msg::{ AccountInfo, AccountResponse, AcknowledgementMsg, BalancesResponse, DispatchResponse, - InstantiateMsg, ListAccountsResponse, PacketMsg, QueryMsg, ReflectExecuteMsg, WhoAmIResponse, + InstantiateMsg, ListAccountsResponse, PacketMsg, QueryMsg, ReflectExecuteMsg, + ReturnMsgsResponse, WhoAmIResponse, +}; +use crate::state::{ + load_account, load_item, may_load_account, range_accounts, remove_account, save_account, + save_item, Config, KEY_CONFIG, KEY_PENDING_CHANNEL, }; -use crate::state::{accounts, accounts_read, config, pending_channel, Config}; pub const IBC_APP_VERSION: &str = "ibc-reflect-v1"; pub const RECEIVE_DISPATCH_ID: u64 = 1234; @@ -28,7 +32,7 @@ pub fn instantiate( let cfg = Config { reflect_code_id: msg.reflect_code_id, }; - config(deps.storage).save(&cfg)?; + save_item(deps.storage, KEY_CONFIG, &cfg)?; Ok(Response::new().add_attribute("action", "instantiate")) } @@ -59,8 +63,8 @@ fn parse_contract_from_event(events: Vec) -> Option { pub fn handle_init_callback(deps: DepsMut, response: SubMsgResponse) -> StdResult { // we use storage to pass info from the caller to the reply - let id = pending_channel(deps.storage).load()?; - pending_channel(deps.storage).remove(); + let id: String = load_item(deps.storage, KEY_PENDING_CHANNEL)?; + deps.storage.remove(KEY_PENDING_CHANNEL); // parse contract info from events let contract_addr = match parse_contract_from_event(response.events) { @@ -72,14 +76,14 @@ pub fn handle_init_callback(deps: DepsMut, response: SubMsgResponse) -> StdResul // store id -> contract_addr if it is empty // id comes from: `let chan_id = msg.endpoint.channel_id;` in `ibc_channel_connect` - accounts(deps.storage).update(id.as_bytes(), |val| -> StdResult<_> { - match val { - Some(_) => Err(StdError::generic_err( + match may_load_account(deps.storage, &id)? { + Some(_) => { + return Err(StdError::generic_err( "Cannot register over an existing channel", - )), - None => Ok(contract_addr), + )) } - })?; + None => save_account(deps.storage, &id, &contract_addr)?, + } Ok(Response::new().add_attribute("action", "execute_init_callback")) } @@ -93,20 +97,19 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } pub fn query_account(deps: Deps, channel_id: String) -> StdResult { - let account = accounts_read(deps.storage).load(channel_id.as_bytes())?; + let account = load_account(deps.storage, &channel_id)?; Ok(AccountResponse { account: Some(account.into()), }) } pub fn query_list_accounts(deps: Deps) -> StdResult { - let accounts: StdResult> = accounts_read(deps.storage) - .range(None, None, Order::Ascending) + let accounts: StdResult> = range_accounts(deps.storage) .map(|item| { let (key, account) = item?; Ok(AccountInfo { account: account.into(), - channel_id: String::from_utf8(key)?, + channel_id: key, }) }) .collect(); @@ -133,8 +136,7 @@ pub fn ibc_channel_open( if let Some(counter_version) = msg.counterparty_version() { if counter_version != IBC_APP_VERSION { return Err(StdError::generic_err(format!( - "Counterparty version must be `{}`", - IBC_APP_VERSION + "Counterparty version must be `{IBC_APP_VERSION}`" ))); } } @@ -153,7 +155,7 @@ pub fn ibc_channel_connect( msg: IbcChannelConnectMsg, ) -> StdResult { let channel = msg.channel(); - let cfg = config(deps.storage).load()?; + let cfg: Config = load_item(deps.storage, KEY_CONFIG)?; let chan_id = &channel.endpoint.channel_id; let msg = WasmMsg::Instantiate { @@ -161,12 +163,12 @@ pub fn ibc_channel_connect( code_id: cfg.reflect_code_id, msg: b"{}".into(), funds: vec![], - label: format!("ibc-reflect-{}", chan_id), + label: format!("ibc-reflect-{chan_id}"), }; let msg = SubMsg::reply_on_success(msg, INIT_CALLBACK_ID); // store the channel id for the reply handler - pending_channel(deps.storage).save(chan_id)?; + save_item(deps.storage, KEY_PENDING_CHANNEL, chan_id)?; Ok(IbcBasicResponse::new() .add_submessage(msg) @@ -186,8 +188,8 @@ pub fn ibc_channel_close( let channel = msg.channel(); // get contract address and remove lookup let channel_id = channel.endpoint.channel_id.as_str(); - let reflect_addr = accounts(deps.storage).load(channel_id.as_bytes())?; - accounts(deps.storage).remove(channel_id.as_bytes()); + let reflect_addr = load_account(deps.storage, channel_id)?; + remove_account(deps.storage, channel_id); // transfer current balance if any (steal the money) let amount = deps.querier.query_all_balances(&reflect_addr)?; @@ -222,7 +224,7 @@ pub fn migrate(_deps: DepsMut, _env: Env, _msg: Empty) -> StdResult { // this encode an error or error message into a proper acknowledgement to the recevier fn encode_ibc_error(msg: impl Into) -> Binary { // this cannot error, unwrap to keep the interface simple - to_binary(&AcknowledgementMsg::<()>::Err(msg.into())).unwrap() + to_binary(&AcknowledgementMsg::<()>::Error(msg.into())).unwrap() } #[entry_point] @@ -233,7 +235,7 @@ pub fn ibc_packet_receive( deps: DepsMut, _env: Env, msg: IbcPacketReceiveMsg, -) -> StdResult { +) -> Result { // put this in a closure so we can convert all error responses into acknowledgements (|| { let packet = msg.packet; @@ -244,12 +246,15 @@ pub fn ibc_packet_receive( PacketMsg::Dispatch { msgs } => receive_dispatch(deps, caller, msgs), PacketMsg::WhoAmI {} => receive_who_am_i(deps, caller), PacketMsg::Balances {} => receive_balances(deps, caller), + PacketMsg::Panic {} => execute_panic(), + PacketMsg::ReturnErr { text } => execute_error(text), + PacketMsg::ReturnMsgs { msgs } => execute_return_msgs(msgs), } })() .or_else(|e| { // we try to capture all app-level errors and convert them into // acknowledgement packets that contain an error code. - let acknowledgement = encode_ibc_error(format!("invalid packet: {}", e)); + let acknowledgement = encode_ibc_error(format!("invalid packet: {e}")); Ok(IbcReceiveResponse::new() .set_ack(acknowledgement) .add_event(Event::new("ibc").add_attribute("packet", "receive"))) @@ -258,7 +263,7 @@ pub fn ibc_packet_receive( // processes PacketMsg::WhoAmI variant fn receive_who_am_i(deps: DepsMut, caller: String) -> StdResult { - let account = accounts(deps.storage).load(caller.as_bytes())?; + let account = load_account(deps.storage, &caller)?; let response = WhoAmIResponse { account: account.into(), }; @@ -271,7 +276,7 @@ fn receive_who_am_i(deps: DepsMut, caller: String) -> StdResult StdResult { - let account = accounts(deps.storage).load(caller.as_bytes())?; + let account = load_account(deps.storage, &caller)?; let balances = deps.querier.query_all_balances(&account)?; let response = BalancesResponse { account: account.into(), @@ -291,7 +296,7 @@ fn receive_dispatch( msgs: Vec, ) -> StdResult { // what is the reflect contract here - let reflect_addr = accounts(deps.storage).load(caller.as_bytes())?; + let reflect_addr = load_account(deps.storage, &caller)?; // let them know we're fine let acknowledgement = to_binary(&AcknowledgementMsg::::Ok(()))?; @@ -308,6 +313,23 @@ fn receive_dispatch( .add_attribute("action", "receive_dispatch")) } +fn execute_panic() -> StdResult { + panic!("This page intentionally faulted"); +} + +fn execute_error(text: String) -> StdResult { + Err(StdError::generic_err(text)) +} + +fn execute_return_msgs(msgs: Vec) -> StdResult { + let acknowledgement = to_binary(&AcknowledgementMsg::::Ok(()))?; + + Ok(IbcReceiveResponse::new() + .set_ack(acknowledgement) + .add_messages(msgs) + .add_attribute("action", "receive_dispatch")) +} + #[entry_point] /// never should be called as we do not send packets pub fn ibc_packet_ack( @@ -527,7 +549,7 @@ mod tests { let ack: AcknowledgementMsg = from_slice(&res.acknowledgement).unwrap(); assert_eq!( ack.unwrap_err(), - "invalid packet: cosmwasm_std::addresses::Addr not found" + "invalid packet: account channel-123 not found" ); // register the channel @@ -576,7 +598,7 @@ mod tests { assert_eq!(0, res.messages.len()); // acknowledgement is an error let ack: AcknowledgementMsg = from_slice(&res.acknowledgement).unwrap(); - assert_eq!(ack.unwrap_err(), "invalid packet: Error parsing into type ibc_reflect::msg::PacketMsg: unknown variant `reflect_code_id`, expected one of `dispatch`, `who_am_i`, `balances`"); + assert_eq!(ack.unwrap_err(), "invalid packet: Error parsing into type ibc_reflect::msg::PacketMsg: unknown variant `reflect_code_id`, expected one of `dispatch`, `who_am_i`, `balances`, `panic`, `return_err`, `return_msgs`"); } #[test] diff --git a/contracts/ibc-reflect/src/msg.rs b/contracts/ibc-reflect/src/msg.rs index 9e9551be0..6f72005f1 100644 --- a/contracts/ibc-reflect/src/msg.rs +++ b/contracts/ibc-reflect/src/msg.rs @@ -1,5 +1,5 @@ use cosmwasm_schema::{cw_serde, QueryResponses}; -use cosmwasm_std::{Coin, ContractResult, CosmosMsg}; +use cosmwasm_std::{Coin, CosmosMsg}; /// Just needs to know the code_id of a reflect contract to spawn sub-accounts #[cw_serde] @@ -46,11 +46,40 @@ pub enum PacketMsg { Dispatch { msgs: Vec }, WhoAmI {}, Balances {}, + Panic {}, + ReturnErr { text: String }, + ReturnMsgs { msgs: Vec }, } -/// All acknowledgements are wrapped in `ContractResult`. -/// The success value depends on the PacketMsg variant. -pub type AcknowledgementMsg = ContractResult; +/// A custom acknowledgement type. +/// The success type `T` depends on the PacketMsg variant. +/// +/// This could be refactored to use [StdAck] at some point. However, +/// it has a different success variant name ("ok" vs. "result") and +/// a JSON payload instead of a binary payload. +/// +/// [StdAck]: https://github.com/CosmWasm/cosmwasm/issues/1512 +#[cw_serde] +pub enum AcknowledgementMsg { + Ok(S), + Error(String), +} + +impl AcknowledgementMsg { + pub fn unwrap(self) -> S { + match self { + AcknowledgementMsg::Ok(data) => data, + AcknowledgementMsg::Error(err) => panic!("{}", err), + } + } + + pub fn unwrap_err(self) -> String { + match self { + AcknowledgementMsg::Ok(_) => panic!("not an error"), + AcknowledgementMsg::Error(err) => err, + } + } +} /// This is the success response we send on ack for PacketMsg::Dispatch. /// Just acknowledge success or error @@ -70,3 +99,7 @@ pub struct BalancesResponse { pub account: String, pub balances: Vec, } + +/// This is the success response we send on ack for PacketMsg::ReturnMsgs. +/// Just acknowledge success or error +pub type ReturnMsgsResponse = (); diff --git a/contracts/ibc-reflect/src/state.rs b/contracts/ibc-reflect/src/state.rs index 9b0bbfe52..bbb1fdaaa 100644 --- a/contracts/ibc-reflect/src/state.rs +++ b/contracts/ibc-reflect/src/state.rs @@ -1,39 +1,70 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use std::any::type_name; -use cosmwasm_std::{Addr, Storage}; -use cosmwasm_storage::{ - bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton, - Singleton, +use cosmwasm_std::{ + from_slice, + storage_keys::{namespace_with_key, to_length_prefixed}, + to_vec, Addr, Order, StdError, StdResult, Storage, }; +use schemars::JsonSchema; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; pub const KEY_CONFIG: &[u8] = b"config"; pub const KEY_PENDING_CHANNEL: &[u8] = b"pending"; pub const PREFIX_ACCOUNTS: &[u8] = b"accounts"; +/// Upper bound for ranging over accounts +const PREFIX_ACCOUNTS_UPPER_BOUND: &[u8] = b"accountt"; #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct Config { pub reflect_code_id: u64, } -/// accounts is lookup of channel_id to reflect contract -pub fn accounts(storage: &mut dyn Storage) -> Bucket { - bucket(storage, PREFIX_ACCOUNTS) +pub fn may_load_account(storage: &dyn Storage, id: &str) -> StdResult> { + storage + .get(&namespace_with_key(&[PREFIX_ACCOUNTS], id.as_bytes())) + .map(|v| from_slice(&v)) + .transpose() +} + +pub fn load_account(storage: &dyn Storage, id: &str) -> StdResult { + may_load_account(storage, id)?.ok_or_else(|| StdError::not_found(format!("account {id}"))) +} + +pub fn save_account(storage: &mut dyn Storage, id: &str, account: &Addr) -> StdResult<()> { + storage.set( + &namespace_with_key(&[PREFIX_ACCOUNTS], id.as_bytes()), + &to_vec(account)?, + ); + Ok(()) } -pub fn accounts_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, PREFIX_ACCOUNTS) +pub fn remove_account(storage: &mut dyn Storage, id: &str) { + storage.remove(&namespace_with_key(&[PREFIX_ACCOUNTS], id.as_bytes())); } -pub fn config(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_CONFIG) +pub fn range_accounts( + storage: &dyn Storage, +) -> impl Iterator> + '_ { + let prefix = to_length_prefixed(PREFIX_ACCOUNTS); + let upper_bound = to_length_prefixed(PREFIX_ACCOUNTS_UPPER_BOUND); + storage + .range(Some(&prefix), Some(&upper_bound), Order::Ascending) + .map(|(key, val)| { + Ok(( + String::from_utf8(key[PREFIX_ACCOUNTS.len() + 2..].to_vec())?, + from_slice(&val)?, + )) + }) } -pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, KEY_CONFIG) +pub fn load_item(storage: &dyn Storage, key: &[u8]) -> StdResult { + storage + .get(&to_length_prefixed(key)) + .ok_or_else(|| StdError::not_found(type_name::())) + .and_then(|v| from_slice(&v)) } -/// pending_channel is used to pass info from ibc_channel_connect to the reply handler -pub fn pending_channel(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_PENDING_CHANNEL) +pub fn save_item(storage: &mut dyn Storage, key: &[u8], item: &T) -> StdResult<()> { + storage.set(&to_length_prefixed(key), &to_vec(item)?); + Ok(()) } diff --git a/contracts/ibc-reflect/tests/integration.rs b/contracts/ibc-reflect/tests/integration.rs index d28e3369a..9f1e994fc 100644 --- a/contracts/ibc-reflect/tests/integration.rs +++ b/contracts/ibc-reflect/tests/integration.rs @@ -236,7 +236,7 @@ fn handle_dispatch_packet() { from_slice(&res.acknowledgement, DESERIALIZATION_LIMIT).unwrap(); assert_eq!( ack.unwrap_err(), - "invalid packet: cosmwasm_std::addresses::Addr not found" + "invalid packet: account channel-123 not found" ); // register the channel @@ -287,5 +287,5 @@ fn handle_dispatch_packet() { // acknowledgement is an error let ack: AcknowledgementMsg = from_slice(&res.acknowledgement, DESERIALIZATION_LIMIT).unwrap(); - assert_eq!(ack.unwrap_err(), "invalid packet: Error parsing into type ibc_reflect::msg::PacketMsg: unknown variant `reflect_code_id`, expected one of `dispatch`, `who_am_i`, `balances`"); + assert_eq!(ack.unwrap_err(), "invalid packet: Error parsing into type ibc_reflect::msg::PacketMsg: unknown variant `reflect_code_id`, expected one of `dispatch`, `who_am_i`, `balances`, `panic`, `return_err`, `return_msgs`"); } diff --git a/contracts/query-queue/Cargo.lock b/contracts/query-queue/Cargo.lock index d8375d75c..ce198e78c 100644 --- a/contracts/query-queue/Cargo.lock +++ b/contracts/query-queue/Cargo.lock @@ -28,6 +28,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -45,21 +51,21 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -91,6 +109,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" version = "3.11.1" @@ -99,23 +123,24 @@ checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -124,6 +149,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "cc" version = "1.0.78" @@ -144,9 +175,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -186,7 +217,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -206,7 +237,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -214,6 +245,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,8 +254,8 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.6", "thiserror", - "uint", "uuid", ] @@ -233,13 +265,14 @@ version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", @@ -260,56 +293,74 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -317,6 +368,12 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + [[package]] name = "crc32fast" version = "1.3.2" @@ -369,17 +426,11 @@ 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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -430,7 +481,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -441,14 +492,27 @@ checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.105", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -462,7 +526,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -481,6 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] @@ -503,7 +568,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -519,14 +584,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ "der", + "digest 0.10.6", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -552,13 +619,12 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", "digest 0.10.6", "ff", "generic-array", @@ -587,7 +653,7 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -608,7 +674,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -617,20 +683,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -642,12 +699,36 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" @@ -656,6 +737,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -688,9 +770,9 @@ checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", @@ -699,21 +781,18 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hermit-abi" @@ -746,23 +825,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] @@ -782,14 +861,16 @@ dependencies = [ [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", + "once_cell", "sha2 0.10.6", + "signature", ] [[package]] @@ -811,13 +892,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "autocfg", + "scopeguard", ] [[package]] @@ -829,27 +910,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "mach" version = "0.3.2" @@ -876,18 +936,18 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -917,18 +977,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" version = "0.30.0" @@ -940,9 +988,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -951,10 +999,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -964,9 +1025,9 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -981,7 +1042,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.105", "version_check", ] @@ -998,9 +1059,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1022,7 +1083,7 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1038,13 +1099,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1084,21 +1151,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1114,58 +1182,52 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1174,18 +1236,6 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" - [[package]] name = "ryu" version = "1.0.11" @@ -1213,7 +1263,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.105", ] [[package]] @@ -1230,9 +1280,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" dependencies = [ "base16ct", "der", @@ -1253,20 +1303,22 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] @@ -1277,7 +1329,7 @@ checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1288,7 +1340,7 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1347,14 +1399,26 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.6", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" version = "1.10.0" @@ -1363,9 +1427,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1377,12 +1441,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "subtle" version = "2.4.1" @@ -1401,45 +1459,63 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "syn" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "tempfile" -version = "3.3.0" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" version = "0.1.37" @@ -1447,7 +1523,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1461,7 +1536,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1480,16 +1555,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" @@ -1497,11 +1566,31 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1540,10 +1629,33 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.105", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.83" @@ -1562,7 +1674,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1575,73 +1687,65 @@ checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1653,16 +1757,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1672,184 +1776,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.105", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1880,43 +1878,109 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" version = "1.5.7" diff --git a/contracts/queue/.cargo/config b/contracts/queue/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/queue/.cargo/config +++ b/contracts/queue/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/queue/Cargo.lock b/contracts/queue/Cargo.lock index 3cd51b911..d37444497 100644 --- a/contracts/queue/Cargo.lock +++ b/contracts/queue/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,8 +257,8 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] @@ -233,17 +268,18 @@ version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -251,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -318,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -349,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -412,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -422,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -462,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -476,20 +533,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -503,7 +561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -519,14 +577,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -546,20 +606,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -587,28 +646,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -617,20 +676,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -642,27 +692,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -682,30 +757,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -716,13 +782,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -736,7 +799,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -746,50 +809,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -806,49 +871,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -861,42 +902,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -907,42 +948,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" -version = "0.28.4" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - -[[package]] -name = "object" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -951,22 +970,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -981,7 +1013,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -998,9 +1030,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1022,7 +1054,7 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1038,13 +1070,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1062,9 +1100,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1072,33 +1110,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1114,89 +1151,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1206,21 +1225,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1230,9 +1249,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1244,40 +1263,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1288,14 +1309,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1336,36 +1357,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1378,22 +1411,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1401,53 +1439,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1455,53 +1498,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1521,9 +1578,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1531,24 +1588,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1556,92 +1636,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1653,16 +1725,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1672,184 +1744,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1880,45 +1846,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", ] +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/queue/Cargo.toml b/contracts/queue/Cargo.toml index 5743c2dac..b37c1f79e 100644 --- a/contracts/queue/Cargo.toml +++ b/contracts/queue/Cargo.toml @@ -34,7 +34,8 @@ library = [] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } -cosmwasm-std = { path = "../../packages/std", features = ["iterator"] } +# cosmwasm_1_4 is enabled here for more efficient `range_keys` and `range_values` +cosmwasm-std = { path = "../../packages/std", features = ["iterator", "cosmwasm_1_4"] } schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } diff --git a/contracts/queue/schema/raw/execute.json b/contracts/queue/schema/raw/execute.json new file mode 100644 index 000000000..187720973 --- /dev/null +++ b/contracts/queue/schema/raw/execute.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "enqueue" + ], + "properties": { + "enqueue": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "dequeue" + ], + "properties": { + "dequeue": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/queue/schema/raw/instantiate.json b/contracts/queue/schema/raw/instantiate.json new file mode 100644 index 000000000..1352613d5 --- /dev/null +++ b/contracts/queue/schema/raw/instantiate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/queue/schema/raw/migrate.json b/contracts/queue/schema/raw/migrate.json new file mode 100644 index 000000000..7fbe8c570 --- /dev/null +++ b/contracts/queue/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/queue/schema/raw/query.json b/contracts/queue/schema/raw/query.json new file mode 100644 index 000000000..3c61d5fc5 --- /dev/null +++ b/contracts/queue/schema/raw/query.json @@ -0,0 +1,82 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "count" + ], + "properties": { + "count": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "sum" + ], + "properties": { + "sum": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reducer" + ], + "properties": { + "reducer": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "list" + ], + "properties": { + "list": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Opens the given number of iterators for no reason other than testing. Returns and `Empty` response.", + "type": "object", + "required": [ + "open_iterators" + ], + "properties": { + "open_iterators": { + "type": "object", + "required": [ + "count" + ], + "properties": { + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/queue/schema/raw/response_to_count.json b/contracts/queue/schema/raw/response_to_count.json new file mode 100644 index 000000000..cf6f1c3cd --- /dev/null +++ b/contracts/queue/schema/raw/response_to_count.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CountResponse", + "type": "object", + "required": [ + "count" + ], + "properties": { + "count": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/queue/schema/raw/response_to_list.json b/contracts/queue/schema/raw/response_to_list.json new file mode 100644 index 000000000..e4da63779 --- /dev/null +++ b/contracts/queue/schema/raw/response_to_list.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ListResponse", + "type": "object", + "required": [ + "early", + "empty", + "late" + ], + "properties": { + "early": { + "description": "List all IDs lower than 0x20", + "type": "array", + "items": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "empty": { + "description": "List an empty range, both bounded", + "type": "array", + "items": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "late": { + "description": "List all IDs starting from 0x20", + "type": "array", + "items": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + } + }, + "additionalProperties": false +} diff --git a/contracts/queue/schema/raw/response_to_open_iterators.json b/contracts/queue/schema/raw/response_to_open_iterators.json new file mode 100644 index 000000000..ad4ff226d --- /dev/null +++ b/contracts/queue/schema/raw/response_to_open_iterators.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Empty", + "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", + "type": "object" +} diff --git a/contracts/queue/schema/raw/response_to_reducer.json b/contracts/queue/schema/raw/response_to_reducer.json new file mode 100644 index 000000000..612b4029a --- /dev/null +++ b/contracts/queue/schema/raw/response_to_reducer.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ReducerResponse", + "type": "object", + "required": [ + "counters" + ], + "properties": { + "counters": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "type": "integer", + "format": "int32" + }, + { + "type": "integer", + "format": "int32" + } + ], + "maxItems": 2, + "minItems": 2 + } + } + }, + "additionalProperties": false +} diff --git a/contracts/queue/schema/raw/response_to_sum.json b/contracts/queue/schema/raw/response_to_sum.json new file mode 100644 index 000000000..c8133fe4e --- /dev/null +++ b/contracts/queue/schema/raw/response_to_sum.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "SumResponse", + "type": "object", + "required": [ + "sum" + ], + "properties": { + "sum": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false +} diff --git a/contracts/queue/schema/raw/sudo.json b/contracts/queue/schema/raw/sudo.json new file mode 100644 index 000000000..187720973 --- /dev/null +++ b/contracts/queue/schema/raw/sudo.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "enqueue" + ], + "properties": { + "enqueue": { + "type": "object", + "required": [ + "value" + ], + "properties": { + "value": { + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "dequeue" + ], + "properties": { + "dequeue": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/queue/examples/schema.rs b/contracts/queue/src/bin/schema.rs similarity index 100% rename from contracts/queue/examples/schema.rs rename to contracts/queue/src/bin/schema.rs diff --git a/contracts/queue/src/contract.rs b/contracts/queue/src/contract.rs index 381ed0fcd..63c1769ec 100644 --- a/contracts/queue/src/contract.rs +++ b/contracts/queue/src/contract.rs @@ -42,11 +42,11 @@ fn handle_enqueue(deps: DepsMut, value: i32) -> StdResult { fn enqueue(storage: &mut dyn Storage, value: i32) -> StdResult<()> { // find the last element in the queue and extract key - let last_item = storage.range(None, None, Order::Descending).next(); + let last_item = storage.range_keys(None, None, Order::Descending).next(); let new_key = match last_item { None => FIRST_KEY, - Some((key, _value)) => { + Some(key) => { let last_key = u32::from_be_bytes(key.try_into().unwrap()); (last_key + 1).to_be_bytes() } @@ -76,8 +76,7 @@ pub fn migrate(deps: DepsMut, _env: Env, _msg: MigrateMsg) -> StdResult = deps .storage - .range(None, None, Order::Ascending) - .map(|(key, _)| key) + .range_keys(None, None, Order::Ascending) .collect(); for key in keys { deps.storage.remove(&key); @@ -102,15 +101,18 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } fn query_count(deps: Deps) -> CountResponse { - let count = deps.storage.range(None, None, Order::Ascending).count() as u32; + let count = deps + .storage + .range_keys(None, None, Order::Ascending) + .count() as u32; CountResponse { count } } fn query_sum(deps: Deps) -> StdResult { let values: StdResult> = deps .storage - .range(None, None, Order::Ascending) - .map(|(_, v)| from_slice(&v)) + .range_values(None, None, Order::Ascending) + .map(|v| from_slice(&v)) .collect(); let sum = values?.iter().fold(0, |s, v| s + v.value); Ok(SumResponse { sum }) @@ -121,17 +123,17 @@ fn query_reducer(deps: Deps) -> StdResult { // val: StdResult for val in deps .storage - .range(None, None, Order::Ascending) - .map(|(_, v)| from_slice::(&v)) + .range_values(None, None, Order::Ascending) + .map(|v| from_slice::(&v)) { // this returns error on parse error let my_val = val?.value; // now, let's do second iterator let sum: i32 = deps .storage - .range(None, None, Order::Ascending) + .range_values(None, None, Order::Ascending) // get value. ignore parse errors, just count as 0 - .map(|(_, v)| { + .map(|v| { from_slice::(&v) .map(|v| v.value) .expect("error in item") @@ -149,18 +151,18 @@ fn query_list(deps: Deps) -> ListResponse { const THRESHOLD: [u8; 4] = [0x00, 0x00, 0x00, 0x20]; let empty: Vec = deps .storage - .range(Some(&THRESHOLD), Some(&THRESHOLD), Order::Ascending) - .map(|(k, _)| u32::from_be_bytes(k.try_into().unwrap())) + .range_keys(Some(&THRESHOLD), Some(&THRESHOLD), Order::Ascending) + .map(|k| u32::from_be_bytes(k.try_into().unwrap())) .collect(); let early: Vec = deps .storage - .range(None, Some(&THRESHOLD), Order::Ascending) - .map(|(k, _)| u32::from_be_bytes(k.try_into().unwrap())) + .range_keys(None, Some(&THRESHOLD), Order::Ascending) + .map(|k| u32::from_be_bytes(k.try_into().unwrap())) .collect(); let late: Vec = deps .storage - .range(Some(&THRESHOLD), None, Order::Ascending) - .map(|(k, _)| u32::from_be_bytes(k.try_into().unwrap())) + .range_keys(Some(&THRESHOLD), None, Order::Ascending) + .map(|k| u32::from_be_bytes(k.try_into().unwrap())) .collect(); ListResponse { empty, early, late } } diff --git a/contracts/reflect/.cargo/config b/contracts/reflect/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/reflect/.cargo/config +++ b/contracts/reflect/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/reflect/Cargo.lock b/contracts/reflect/Cargo.lock index 70e0e09b6..ac573e8ab 100644 --- a/contracts/reflect/Cargo.lock +++ b/contracts/reflect/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -259,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -326,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -357,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -420,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -430,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -470,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -484,20 +533,21 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -511,7 +561,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -527,14 +577,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -554,20 +606,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -595,28 +646,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -625,20 +676,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -650,27 +692,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -690,30 +757,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -724,13 +782,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -744,7 +799,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -754,50 +809,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -814,49 +871,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -869,42 +902,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -915,42 +948,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -959,22 +970,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -989,7 +1013,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1006,9 +1030,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1030,18 +1054,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1059,9 +1089,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1069,21 +1099,19 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] @@ -1094,7 +1122,6 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "schemars", "serde", @@ -1102,13 +1129,14 @@ dependencies = [ ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1124,89 +1152,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1216,21 +1226,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1240,9 +1250,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1263,20 +1273,22 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] @@ -1287,7 +1299,7 @@ checksum = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -1298,14 +1310,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" dependencies = [ "itoa", "ryu", @@ -1346,36 +1358,48 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1388,22 +1412,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1411,53 +1440,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1465,53 +1499,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1531,9 +1579,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1541,24 +1589,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1566,92 +1637,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1663,16 +1726,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1682,184 +1745,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1890,45 +1847,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/reflect/Cargo.toml b/contracts/reflect/Cargo.toml index eab872fe3..8ef7e171b 100644 --- a/contracts/reflect/Cargo.toml +++ b/contracts/reflect/Cargo.toml @@ -34,11 +34,10 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } -cosmwasm-std = { path = "../../packages/std", default-features = false, features = ["staking", "stargate", "cosmwasm_1_1"] } -cosmwasm-storage = { path = "../../packages/storage", default-features = false } +cosmwasm-std = { path = "../../packages/std", default-features = false, features = ["staking", "stargate", "cosmwasm_1_4"] } schemars = "0.8.3" serde = { version = "=1.0.103", default-features = false, features = ["derive"] } -thiserror = "1.0" +thiserror = "1.0.26" [dev-dependencies] cosmwasm-vm = { path = "../../packages/vm", default-features = false, features = ["stargate"] } diff --git a/contracts/reflect/rustfmt.toml b/contracts/reflect/rustfmt.toml deleted file mode 100644 index 11a85e6a9..000000000 --- a/contracts/reflect/rustfmt.toml +++ /dev/null @@ -1,15 +0,0 @@ -# stable -newline_style = "unix" -hard_tabs = false -tab_spaces = 4 - -# unstable... should we require `rustup run nightly cargo fmt` ? -# or just update the style guide when they are stable? -#fn_single_line = true -#format_code_in_doc_comments = true -#overflow_delimited_expr = true -#reorder_impl_items = true -#struct_field_align_threshold = 20 -#struct_lit_single_line = true -#report_todo = "Always" - diff --git a/contracts/reflect/schema/raw/execute.json b/contracts/reflect/schema/raw/execute.json new file mode 100644 index 000000000..fb4a290bf --- /dev/null +++ b/contracts/reflect/schema/raw/execute.json @@ -0,0 +1,1011 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "reflect_msg" + ], + "properties": { + "reflect_msg": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_CustomMsg" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reflect_sub_msg" + ], + "properties": { + "reflect_sub_msg": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/SubMsg_for_CustomMsg" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "change_owner" + ], + "properties": { + "change_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto.", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_CustomMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/CustomMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "CustomMsg": { + "description": "CustomMsg is an override of CosmosMsg::Custom to show this works and can be extended in the contract", + "oneOf": [ + { + "type": "object", + "required": [ + "debug" + ], + "properties": { + "debug": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "raw" + ], + "properties": { + "raw": { + "$ref": "#/definitions/Binary" + } + }, + "additionalProperties": false + } + ] + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgFundCommunityPool](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#LL69C1-L76C2). `depositor` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "fund_community_pool" + ], + "properties": { + "fund_community_pool": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "description": "The amount to spend", + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This maps directly to [MsgVoteWeighted](https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/proto/cosmos/gov/v1beta1/tx.proto#L66-L78) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote_weighted" + ], + "properties": { + "vote_weighted": { + "type": "object", + "required": [ + "options", + "proposal_id" + ], + "properties": { + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/WeightedVoteOption" + } + }, + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "existing channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ReplyOn": { + "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", + "oneOf": [ + { + "description": "Always perform a callback after SubMsg is processed", + "type": "string", + "enum": [ + "always" + ] + }, + { + "description": "Only callback if SubMsg returned an error, no callback on success case", + "type": "string", + "enum": [ + "error" + ] + }, + { + "description": "Only callback if SubMsg was successful, no callback on error case", + "type": "string", + "enum": [ + "success" + ] + }, + { + "description": "Never make a callback - this is like the original CosmosMsg semantics", + "type": "string", + "enum": [ + "never" + ] + } + ] + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto.", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L79-L88). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L110-L119). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/staking/v1beta1/tx.proto#L93-L103). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "SubMsg_for_CustomMsg": { + "description": "A submessage that will guarantee a `reply` call on success or error, depending on the `reply_on` setting. If you do not need to process the result, use regular messages instead.\n\nNote: On error the submessage execution will revert any partial state changes due to this message, but not revert any state changes in the calling contract. If this is required, it must be done manually in the `reply` entry point.", + "type": "object", + "required": [ + "id", + "msg", + "reply_on" + ], + "properties": { + "gas_limit": { + "description": "Gas limit measured in [Cosmos SDK gas](https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md).", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "id": { + "description": "An arbitrary ID chosen by the contract. This is typically used to match `Reply`s in the `reply` entry point to the submessage.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msg": { + "$ref": "#/definitions/CosmosMsg_for_CustomMsg" + }, + "reply_on": { + "$ref": "#/definitions/ReplyOn" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto.", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L71-L82). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code using a predictable address derivation algorithm implemented in [`cosmwasm_std::instantiate2_address`].\n\nThis is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). `sender` is automatically filled with the current contract's address. `fix_msg` is automatically set to false.", + "type": "object", + "required": [ + "instantiate2" + ], + "properties": { + "instantiate2": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg", + "salt" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "salt": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L90-L100). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "WeightedVoteOption": { + "type": "object", + "required": [ + "option", + "weight" + ], + "properties": { + "option": { + "$ref": "#/definitions/VoteOption" + }, + "weight": { + "$ref": "#/definitions/Decimal" + } + } + } + } +} diff --git a/contracts/reflect/schema/raw/instantiate.json b/contracts/reflect/schema/raw/instantiate.json new file mode 100644 index 000000000..1352613d5 --- /dev/null +++ b/contracts/reflect/schema/raw/instantiate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/reflect/schema/raw/migrate.json b/contracts/reflect/schema/raw/migrate.json new file mode 100644 index 000000000..1ccfba3b0 --- /dev/null +++ b/contracts/reflect/schema/raw/migrate.json @@ -0,0 +1,854 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "reflect_msg" + ], + "properties": { + "reflect_msg": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_CustomMsg" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reflect_sub_msg" + ], + "properties": { + "reflect_sub_msg": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/SubMsg_for_CustomMsg" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "change_owner" + ], + "properties": { + "change_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_CustomMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/CustomMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "CustomMsg": { + "description": "CustomMsg is an override of CosmosMsg::Custom to show this works and can be extended in the contract", + "oneOf": [ + { + "type": "object", + "required": [ + "debug" + ], + "properties": { + "debug": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "raw" + ], + "properties": { + "raw": { + "$ref": "#/definitions/Binary" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/VoteOption" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ReplyOn": { + "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", + "type": "string", + "enum": [ + "always", + "error", + "success", + "never" + ] + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "SubMsg_for_CustomMsg": { + "description": "A submessage that will guarantee a `reply` call on success or error, depending on the `reply_on` setting. If you do not need to process the result, use regular messages instead.\n\nNote: On error the submessage execution will revert any partial state changes due to this message, but not revert any state changes in the calling contract. If this is required, it must be done manually in the `reply` entry point.", + "type": "object", + "required": [ + "id", + "msg", + "reply_on" + ], + "properties": { + "gas_limit": { + "description": "Gas limit measured in [Cosmos SDK gas](https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md).", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "id": { + "description": "An arbitrary ID chosen by the contract. This is typically used to match `Reply`s in the `reply` entry point to the submessage.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msg": { + "$ref": "#/definitions/CosmosMsg_for_CustomMsg" + }, + "reply_on": { + "$ref": "#/definitions/ReplyOn" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/reflect/schema/raw/query.json b/contracts/reflect/schema/raw/query.json new file mode 100644 index 000000000..ef2199054 --- /dev/null +++ b/contracts/reflect/schema/raw/query.json @@ -0,0 +1,774 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "This will call out to SpecialQuery::Capitalized", + "type": "object", + "required": [ + "capitalized" + ], + "properties": { + "capitalized": { + "type": "object", + "required": [ + "text" + ], + "properties": { + "text": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Queries the blockchain and returns the result untouched", + "type": "object", + "required": [ + "chain" + ], + "properties": { + "chain": { + "type": "object", + "required": [ + "request" + ], + "properties": { + "request": { + "$ref": "#/definitions/QueryRequest_for_SpecialQuery" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Queries another contract and returns the data", + "type": "object", + "required": [ + "raw" + ], + "properties": { + "raw": { + "type": "object", + "required": [ + "contract", + "key" + ], + "properties": { + "contract": { + "type": "string" + }, + "key": { + "$ref": "#/definitions/Binary" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "If there was a previous ReflectSubMsg with this ID, returns cosmwasm_std::Reply", + "type": "object", + "required": [ + "sub_msg_result" + ], + "properties": { + "sub_msg_result": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankQuery": { + "oneOf": [ + { + "description": "This calls into the native bank module for querying the total supply of one denomination. It does the same as the SupplyOf call in Cosmos SDK's RPC API. Return value is of type SupplyResponse.", + "type": "object", + "required": [ + "supply" + ], + "properties": { + "supply": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This calls into the native bank module for one denomination Return value is BalanceResponse", + "type": "object", + "required": [ + "balance" + ], + "properties": { + "balance": { + "type": "object", + "required": [ + "address", + "denom" + ], + "properties": { + "address": { + "type": "string" + }, + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This calls into the native bank module for all denominations. Note that this may be much more expensive than Balance and should be avoided if possible. Return value is AllBalanceResponse.", + "type": "object", + "required": [ + "all_balances" + ], + "properties": { + "all_balances": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This calls into the native bank module for querying metadata for a specific bank token. Return value is DenomMetadataResponse", + "type": "object", + "required": [ + "denom_metadata" + ], + "properties": { + "denom_metadata": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This calls into the native bank module for querying metadata for all bank tokens that have a metadata entry. Return value is AllDenomMetadataResponse", + "type": "object", + "required": [ + "all_denom_metadata" + ], + "properties": { + "all_denom_metadata": { + "type": "object", + "properties": { + "pagination": { + "anyOf": [ + { + "$ref": "#/definitions/PageRequest" + }, + { + "type": "null" + } + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "DistributionQuery": { + "oneOf": [ + { + "description": "See ", + "type": "object", + "required": [ + "delegator_withdraw_address" + ], + "properties": { + "delegator_withdraw_address": { + "type": "object", + "required": [ + "delegator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "See ", + "type": "object", + "required": [ + "delegation_rewards" + ], + "properties": { + "delegation_rewards": { + "type": "object", + "required": [ + "delegator_address", + "validator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + }, + "validator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "See ", + "type": "object", + "required": [ + "delegation_total_rewards" + ], + "properties": { + "delegation_total_rewards": { + "type": "object", + "required": [ + "delegator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "See ", + "type": "object", + "required": [ + "delegator_validators" + ], + "properties": { + "delegator_validators": { + "type": "object", + "required": [ + "delegator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcQuery": { + "description": "These are queries to the various IBC modules to see the state of the contract's IBC connection. These will return errors if the contract is not \"ibc enabled\"", + "oneOf": [ + { + "description": "Gets the Port ID the current contract is bound to.\n\nReturns a `PortIdResponse`.", + "type": "object", + "required": [ + "port_id" + ], + "properties": { + "port_id": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "description": "Lists all channels that are bound to a given port. If `port_id` is omitted, this list all channels bound to the contract's port.\n\nReturns a `ListChannelsResponse`.", + "type": "object", + "required": [ + "list_channels" + ], + "properties": { + "list_channels": { + "type": "object", + "properties": { + "port_id": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Lists all information for a (portID, channelID) pair. If port_id is omitted, it will default to the contract's own channel. (To save a PortId{} call)\n\nReturns a `ChannelResponse`.", + "type": "object", + "required": [ + "channel" + ], + "properties": { + "channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "port_id": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "additionalProperties": false + } + ] + }, + "PageRequest": { + "description": "Simplified version of the PageRequest type for pagination from the cosmos-sdk", + "type": "object", + "required": [ + "limit", + "reverse" + ], + "properties": { + "key": { + "anyOf": [ + { + "$ref": "#/definitions/Binary" + }, + { + "type": "null" + } + ] + }, + "limit": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "reverse": { + "type": "boolean" + } + } + }, + "QueryRequest_for_SpecialQuery": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankQuery" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/SpecialQuery" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingQuery" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionQuery" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate query is encoded the same way as abci_query, with path and protobuf encoded request data. The format is defined in [ADR-21](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-021-protobuf-query-encoding.md). The response is protobuf encoded data directly without a JSON response wrapper. The caller is responsible for compiling the proper protobuf definitions for both requests and responses.", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "data", + "path" + ], + "properties": { + "data": { + "description": "this is the expected protobuf message type (not any), binary encoded", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "path": { + "description": "this is the fully qualified service path used for routing, eg. custom/cosmos_sdk.x.bank.v1.Query/QueryBalance", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcQuery" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmQuery" + } + }, + "additionalProperties": false + } + ] + }, + "SpecialQuery": { + "description": "An implementation of QueryRequest::Custom to show this works and can be extended in the contract", + "oneOf": [ + { + "type": "object", + "required": [ + "ping" + ], + "properties": { + "ping": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "capitalized" + ], + "properties": { + "capitalized": { + "type": "object", + "required": [ + "text" + ], + "properties": { + "text": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "StakingQuery": { + "oneOf": [ + { + "description": "Returns the denomination that can be bonded (if there are multiple native tokens on the chain)", + "type": "object", + "required": [ + "bonded_denom" + ], + "properties": { + "bonded_denom": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "description": "AllDelegations will return all delegations by the delegator", + "type": "object", + "required": [ + "all_delegations" + ], + "properties": { + "all_delegations": { + "type": "object", + "required": [ + "delegator" + ], + "properties": { + "delegator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Delegation will return more detailed info on a particular delegation, defined by delegator/validator pair", + "type": "object", + "required": [ + "delegation" + ], + "properties": { + "delegation": { + "type": "object", + "required": [ + "delegator", + "validator" + ], + "properties": { + "delegator": { + "type": "string" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Returns all validators in the currently active validator set.\n\nThe query response type is `AllValidatorsResponse`.", + "type": "object", + "required": [ + "all_validators" + ], + "properties": { + "all_validators": { + "type": "object" + } + }, + "additionalProperties": false + }, + { + "description": "Returns the validator at the given address. Returns None if the validator is not part of the currently active validator set.\n\nThe query response type is `ValidatorResponse`.", + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The validator's address (e.g. (e.g. cosmosvaloper1...))", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "WasmQuery": { + "oneOf": [ + { + "description": "this queries the public API of another contract at a known address (with known ABI) Return value is whatever the contract returns (caller should know), wrapped in a ContractResult that is JSON encoded.", + "type": "object", + "required": [ + "smart" + ], + "properties": { + "smart": { + "type": "object", + "required": [ + "contract_addr", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded QueryMsg struct", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "this queries the raw kv-store of the contract. returns the raw, unparsed data stored at that key, which may be an empty vector if not present", + "type": "object", + "required": [ + "raw" + ], + "properties": { + "raw": { + "type": "object", + "required": [ + "contract_addr", + "key" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "key": { + "description": "Key is the raw key used in the contracts Storage", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime", + "type": "object", + "required": [ + "contract_info" + ], + "properties": { + "contract_info": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Returns a [`CodeInfoResponse`] with metadata of the code", + "type": "object", + "required": [ + "code_info" + ], + "properties": { + "code_info": { + "type": "object", + "required": [ + "code_id" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/reflect/schema/raw/response_to_capitalized.json b/contracts/reflect/schema/raw/response_to_capitalized.json new file mode 100644 index 000000000..543a4fa4c --- /dev/null +++ b/contracts/reflect/schema/raw/response_to_capitalized.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "CapitalizedResponse", + "type": "object", + "required": [ + "text" + ], + "properties": { + "text": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/reflect/schema/raw/response_to_chain.json b/contracts/reflect/schema/raw/response_to_chain.json new file mode 100644 index 000000000..aa0adb0fc --- /dev/null +++ b/contracts/reflect/schema/raw/response_to_chain.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ChainResponse", + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/definitions/Binary" + } + }, + "additionalProperties": false, + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } +} diff --git a/contracts/reflect/schema/raw/response_to_owner.json b/contracts/reflect/schema/raw/response_to_owner.json new file mode 100644 index 000000000..d91dde149 --- /dev/null +++ b/contracts/reflect/schema/raw/response_to_owner.json @@ -0,0 +1,14 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "OwnerResponse", + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/reflect/schema/raw/response_to_raw.json b/contracts/reflect/schema/raw/response_to_raw.json new file mode 100644 index 000000000..85774defd --- /dev/null +++ b/contracts/reflect/schema/raw/response_to_raw.json @@ -0,0 +1,25 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RawResponse", + "type": "object", + "required": [ + "data" + ], + "properties": { + "data": { + "description": "The returned value of the raw query. Empty data can be the result of a non-existent key or an empty value. We cannot differentiate those two cases in cross contract queries.", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + } + } +} diff --git a/contracts/reflect/schema/raw/response_to_sub_msg_result.json b/contracts/reflect/schema/raw/response_to_sub_msg_result.json new file mode 100644 index 000000000..e7a26e26f --- /dev/null +++ b/contracts/reflect/schema/raw/response_to_sub_msg_result.json @@ -0,0 +1,119 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Reply", + "description": "The result object returned to `reply`. We always get the ID from the submessage back and then must handle success and error cases ourselves.", + "type": "object", + "required": [ + "id", + "result" + ], + "properties": { + "id": { + "description": "The ID that the contract set when emitting the `SubMsg`. Use this to identify which submessage triggered the `reply`.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "result": { + "$ref": "#/definitions/SubMsgResult" + } + }, + "definitions": { + "Attribute": { + "description": "An key value pair that is used in the context of event attributes in logs", + "type": "object", + "required": [ + "key", + "value" + ], + "properties": { + "key": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Event": { + "description": "A full [*Cosmos SDK* event].\n\nThis version uses string attributes (similar to [*Cosmos SDK* StringEvent]), which then get magically converted to bytes for Tendermint somewhere between the Rust-Go interface, JSON deserialization and the `NewEvent` call in Cosmos SDK.\n\n[*Cosmos SDK* event]: https://docs.cosmos.network/main/core/events.html [*Cosmos SDK* StringEvent]: https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/base/abci/v1beta1/abci.proto#L56-L70", + "type": "object", + "required": [ + "attributes", + "type" + ], + "properties": { + "attributes": { + "description": "The attributes to be included in the event.\n\nYou can learn more about these from [*Cosmos SDK* docs].\n\n[*Cosmos SDK* docs]: https://docs.cosmos.network/main/core/events.html", + "type": "array", + "items": { + "$ref": "#/definitions/Attribute" + } + }, + "type": { + "description": "The event type. This is renamed to \"ty\" because \"type\" is reserved in Rust. This sucks, we know.", + "type": "string" + } + } + }, + "SubMsgResponse": { + "description": "The information we get back from a successful sub message execution, with full Cosmos SDK events.", + "type": "object", + "required": [ + "events" + ], + "properties": { + "data": { + "anyOf": [ + { + "$ref": "#/definitions/Binary" + }, + { + "type": "null" + } + ] + }, + "events": { + "type": "array", + "items": { + "$ref": "#/definitions/Event" + } + } + } + }, + "SubMsgResult": { + "description": "This is the result type that is returned from a sub message execution.\n\nWe use a custom type here instead of Rust's Result because we want to be able to define the serialization, which is a public interface. Every language that compiles to Wasm and runs in the ComsWasm VM needs to create the same JSON representation.\n\nUntil version 1.0.0-beta5, `ContractResult` was used instead of this type. Once serialized, the two types are the same. However, in the Rust type system we want different types for clarity and documenation reasons.\n\n# Examples\n\nSuccess:\n\n``` # use cosmwasm_std::{to_vec, Binary, Event, SubMsgResponse, SubMsgResult}; let response = SubMsgResponse { data: Some(Binary::from_base64(\"MTIzCg==\").unwrap()), events: vec![Event::new(\"wasm\").add_attribute(\"fo\", \"ba\")], }; let result: SubMsgResult = SubMsgResult::Ok(response); assert_eq!(to_vec(&result).unwrap(), br#\"{\"ok\":{\"events\":[{\"type\":\"wasm\",\"attributes\":[{\"key\":\"fo\",\"value\":\"ba\"}]}],\"data\":\"MTIzCg==\"}}\"#); ```\n\nFailure:\n\n``` # use cosmwasm_std::{to_vec, SubMsgResult, Response}; let error_msg = String::from(\"Something went wrong\"); let result = SubMsgResult::Err(error_msg); assert_eq!(to_vec(&result).unwrap(), br#\"{\"error\":\"Something went wrong\"}\"#); ```", + "oneOf": [ + { + "type": "object", + "required": [ + "ok" + ], + "properties": { + "ok": { + "$ref": "#/definitions/SubMsgResponse" + } + }, + "additionalProperties": false + }, + { + "description": "An error type that every custom error created by contract developers can be converted to. This could potientially have more structure, but String is the easiest.", + "type": "object", + "required": [ + "error" + ], + "properties": { + "error": { + "type": "string" + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/reflect/schema/raw/sudo.json b/contracts/reflect/schema/raw/sudo.json new file mode 100644 index 000000000..1ccfba3b0 --- /dev/null +++ b/contracts/reflect/schema/raw/sudo.json @@ -0,0 +1,854 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "reflect_msg" + ], + "properties": { + "reflect_msg": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/CosmosMsg_for_CustomMsg" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "reflect_sub_msg" + ], + "properties": { + "reflect_sub_msg": { + "type": "object", + "required": [ + "msgs" + ], + "properties": { + "msgs": { + "type": "array", + "items": { + "$ref": "#/definitions/SubMsg_for_CustomMsg" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "change_owner" + ], + "properties": { + "change_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "BankMsg": { + "description": "The message types of the bank module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto", + "oneOf": [ + { + "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "send" + ], + "properties": { + "send": { + "type": "object", + "required": [ + "amount", + "to_address" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "to_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", + "type": "object", + "required": [ + "burn" + ], + "properties": { + "burn": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false + } + ] + }, + "Binary": { + "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "CosmosMsg_for_CustomMsg": { + "oneOf": [ + { + "type": "object", + "required": [ + "bank" + ], + "properties": { + "bank": { + "$ref": "#/definitions/BankMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "custom" + ], + "properties": { + "custom": { + "$ref": "#/definitions/CustomMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "staking" + ], + "properties": { + "staking": { + "$ref": "#/definitions/StakingMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionMsg" + } + }, + "additionalProperties": false + }, + { + "description": "A Stargate message encoded the same way as a protobuf [Any](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto). This is the same structure as messages in `TxBody` from [ADR-020](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-020-protobuf-transaction-encoding.md)", + "type": "object", + "required": [ + "stargate" + ], + "properties": { + "stargate": { + "type": "object", + "required": [ + "type_url", + "value" + ], + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "$ref": "#/definitions/Binary" + } + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "ibc" + ], + "properties": { + "ibc": { + "$ref": "#/definitions/IbcMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "wasm" + ], + "properties": { + "wasm": { + "$ref": "#/definitions/WasmMsg" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "gov" + ], + "properties": { + "gov": { + "$ref": "#/definitions/GovMsg" + } + }, + "additionalProperties": false + } + ] + }, + "CustomMsg": { + "description": "CustomMsg is an override of CosmosMsg::Custom to show this works and can be extended in the contract", + "oneOf": [ + { + "type": "object", + "required": [ + "debug" + ], + "properties": { + "debug": { + "type": "string" + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "raw" + ], + "properties": { + "raw": { + "$ref": "#/definitions/Binary" + } + }, + "additionalProperties": false + } + ] + }, + "DistributionMsg": { + "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgSetWithdrawAddress](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L29-L37). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "set_withdraw_address" + ], + "properties": { + "set_withdraw_address": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "description": "The `withdraw_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgWithdrawDelegatorReward](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#L42-L50). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "withdraw_delegator_reward" + ], + "properties": { + "withdraw_delegator_reward": { + "type": "object", + "required": [ + "validator" + ], + "properties": { + "validator": { + "description": "The `validator_address`", + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "GovMsg": { + "oneOf": [ + { + "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote" + ], + "properties": { + "vote": { + "type": "object", + "required": [ + "proposal_id", + "vote" + ], + "properties": { + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "vote": { + "$ref": "#/definitions/VoteOption" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcMsg": { + "description": "These are messages in the IBC lifecycle. Only usable by IBC-enabled contracts (contracts that directly speak the IBC protocol via 6 entry points)", + "oneOf": [ + { + "description": "Sends bank tokens owned by the contract to the given address on another chain. The channel must already be established between the ibctransfer module on this chain and a matching module on the remote chain. We cannot select the port_id, this is whatever the local chain has bound the ibctransfer module to.", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "channel_id", + "timeout", + "to_address" + ], + "properties": { + "amount": { + "description": "packet data only supports one coin https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/ibc/applications/transfer/v1/transfer.proto#L11-L20", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "channel_id": { + "description": "exisiting channel to send the tokens over", + "type": "string" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + }, + "to_address": { + "description": "address on the remote chain to receive these tokens", + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sends an IBC packet with given data over the existing channel. Data should be encoded in a format defined by the channel version, and the module on the other side should know how to parse this.", + "type": "object", + "required": [ + "send_packet" + ], + "properties": { + "send_packet": { + "type": "object", + "required": [ + "channel_id", + "data", + "timeout" + ], + "properties": { + "channel_id": { + "type": "string" + }, + "data": { + "$ref": "#/definitions/Binary" + }, + "timeout": { + "description": "when packet times out, measured on remote chain", + "allOf": [ + { + "$ref": "#/definitions/IbcTimeout" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This will close an existing channel that is owned by this contract. Port is auto-assigned to the contract's IBC port", + "type": "object", + "required": [ + "close_channel" + ], + "properties": { + "close_channel": { + "type": "object", + "required": [ + "channel_id" + ], + "properties": { + "channel_id": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "IbcTimeout": { + "description": "In IBC each package must set at least one type of timeout: the timestamp or the block height. Using this rather complex enum instead of two timeout fields we ensure that at least one timeout is set.", + "type": "object", + "properties": { + "block": { + "anyOf": [ + { + "$ref": "#/definitions/IbcTimeoutBlock" + }, + { + "type": "null" + } + ] + }, + "timestamp": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + } + } + }, + "IbcTimeoutBlock": { + "description": "IBCTimeoutHeight Height is a monotonically increasing data type that can be compared against another Height for the purposes of updating and freezing clients. Ordering is (revision_number, timeout_height)", + "type": "object", + "required": [ + "height", + "revision" + ], + "properties": { + "height": { + "description": "block height after which the packet times out. the height within the given revision", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "revision": { + "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + }, + "ReplyOn": { + "description": "Use this to define when the contract gets a response callback. If you only need it for errors or success you can select just those in order to save gas.", + "type": "string", + "enum": [ + "always", + "error", + "success", + "never" + ] + }, + "StakingMsg": { + "description": "The message types of the staking module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto", + "oneOf": [ + { + "description": "This is translated to a [MsgDelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L81-L90). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "delegate" + ], + "properties": { + "delegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgUndelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L112-L121). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "undelegate" + ], + "properties": { + "undelegate": { + "type": "object", + "required": [ + "amount", + "validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This is translated to a [MsgBeginRedelegate](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0/proto/cosmos/staking/v1beta1/tx.proto#L95-L105). `delegator_address` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "redelegate" + ], + "properties": { + "redelegate": { + "type": "object", + "required": [ + "amount", + "dst_validator", + "src_validator" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Coin" + }, + "dst_validator": { + "type": "string" + }, + "src_validator": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, + "SubMsg_for_CustomMsg": { + "description": "A submessage that will guarantee a `reply` call on success or error, depending on the `reply_on` setting. If you do not need to process the result, use regular messages instead.\n\nNote: On error the submessage execution will revert any partial state changes due to this message, but not revert any state changes in the calling contract. If this is required, it must be done manually in the `reply` entry point.", + "type": "object", + "required": [ + "id", + "msg", + "reply_on" + ], + "properties": { + "gas_limit": { + "description": "Gas limit measured in [Cosmos SDK gas](https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md).", + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + }, + "id": { + "description": "An arbitrary ID chosen by the contract. This is typically used to match `Reply`s in the `reply` entry point to the submessage.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "msg": { + "$ref": "#/definitions/CosmosMsg_for_CustomMsg" + }, + "reply_on": { + "$ref": "#/definitions/ReplyOn" + } + } + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + }, + "VoteOption": { + "type": "string", + "enum": [ + "yes", + "no", + "abstain", + "no_with_veto" + ] + }, + "WasmMsg": { + "description": "The message types of the wasm module.\n\nSee https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto", + "oneOf": [ + { + "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L68-L78). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "execute" + ], + "properties": { + "execute": { + "type": "object", + "required": [ + "contract_addr", + "funds", + "msg" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "msg": { + "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L53-L71). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "instantiate" + ], + "properties": { + "instantiate": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readbale label for the contract", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/CosmWasm/wasmd/blob/v0.14.0/x/wasm/internal/types/tx.proto#L86-L96). `sender` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "migrate" + ], + "properties": { + "migrate": { + "type": "object", + "required": [ + "contract_addr", + "msg", + "new_code_id" + ], + "properties": { + "contract_addr": { + "type": "string" + }, + "msg": { + "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + }, + "new_code_id": { + "description": "the code_id of the new logic to place in the given contract", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin", + "contract_addr" + ], + "properties": { + "admin": { + "type": "string" + }, + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", + "type": "object", + "required": [ + "clear_admin" + ], + "properties": { + "clear_admin": { + "type": "object", + "required": [ + "contract_addr" + ], + "properties": { + "contract_addr": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + } + } +} diff --git a/contracts/reflect/schema/reflect.json b/contracts/reflect/schema/reflect.json index 91531835e..169f5943d 100644 --- a/contracts/reflect/schema/reflect.json +++ b/contracts/reflect/schema/reflect.json @@ -301,6 +301,10 @@ } ] }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, "DistributionMsg": { "description": "The message types of the distribution module.\n\nSee https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto", "oneOf": [ @@ -347,10 +351,36 @@ } }, "additionalProperties": false + }, + { + "description": "This is translated to a [[MsgFundCommunityPool](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#LL69C1-L76C2). `depositor` is automatically filled with the current contract's address.", + "type": "object", + "required": [ + "fund_community_pool" + ], + "properties": { + "fund_community_pool": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "description": "The amount to spend", + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + } + } + } + }, + "additionalProperties": false } ] }, "GovMsg": { + "description": "This message type allows the contract interact with the [x/gov] module in order to cast votes.\n\n[x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov\n\n## Examples\n\nCast a simple vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); use cosmwasm_std::{GovMsg, VoteOption};\n\n#[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::Vote { proposal_id: 4, vote: VoteOption::Yes, })) } ```\n\nCast a weighted vote:\n\n``` # use cosmwasm_std::{ # HexBinary, # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, # Response, QueryResponse, # }; # type ExecuteMsg = (); # #[cfg(feature = \"cosmwasm_1_2\")] use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption};\n\n# #[cfg(feature = \"cosmwasm_1_2\")] #[entry_point] pub fn execute( deps: DepsMut, env: Env, info: MessageInfo, msg: ExecuteMsg, ) -> Result { // ... Ok(Response::new().add_message(GovMsg::VoteWeighted { proposal_id: 4, options: vec![ WeightedVoteOption { option: VoteOption::Yes, weight: Decimal::percent(65), }, WeightedVoteOption { option: VoteOption::Abstain, weight: Decimal::percent(35), }, ], })) } ```", "oneOf": [ { "description": "This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address.", @@ -372,7 +402,42 @@ "minimum": 0.0 }, "vote": { - "$ref": "#/definitions/VoteOption" + "description": "The vote option.\n\nThis should be called \"option\" for consistency with Cosmos SDK. Sorry for that. See .", + "allOf": [ + { + "$ref": "#/definitions/VoteOption" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This maps directly to [MsgVoteWeighted](https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/proto/cosmos/gov/v1beta1/tx.proto#L66-L78) in the Cosmos SDK with voter set to the contract address.", + "type": "object", + "required": [ + "vote_weighted" + ], + "properties": { + "vote_weighted": { + "type": "object", + "required": [ + "options", + "proposal_id" + ], + "properties": { + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/WeightedVoteOption" + } + }, + "proposal_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 } } } @@ -409,7 +474,7 @@ ] }, "channel_id": { - "description": "exisiting channel to send the tokens over", + "description": "existing channel to send the tokens over", "type": "string" }, "timeout": { @@ -527,7 +592,7 @@ "minimum": 0.0 }, "revision": { - "description": "the version that the client is currently on (eg. after reseting the chain this could increment 1 as height drops to 0)", + "description": "the version that the client is currently on (e.g. after resetting the chain this could increment 1 as height drops to 0)", "type": "integer", "format": "uint64", "minimum": 0.0 @@ -749,7 +814,7 @@ "additionalProperties": false }, { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", + "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThe contract address is non-predictable. But it is guaranteed that when emitting the same Instantiate message multiple times, multiple instances on different addresses will be generated. See also Instantiate2.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", "type": "object", "required": [ "instantiate" @@ -782,7 +847,58 @@ } }, "label": { - "description": "A human-readbale label for the contract", + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", + "type": "string" + }, + "msg": { + "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", + "allOf": [ + { + "$ref": "#/definitions/Binary" + } + ] + } + } + } + }, + "additionalProperties": false + }, + { + "description": "Instantiates a new contracts from previously uploaded Wasm code using a predictable address derivation algorithm implemented in [`cosmwasm_std::instantiate2_address`].\n\nThis is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). `sender` is automatically filled with the current contract's address. `fix_msg` is automatically set to false.", + "type": "object", + "required": [ + "instantiate2" + ], + "properties": { + "instantiate2": { + "type": "object", + "required": [ + "code_id", + "funds", + "label", + "msg", + "salt" + ], + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + }, + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "funds": { + "type": "array", + "items": { + "$ref": "#/definitions/Coin" + } + }, + "label": { + "description": "A human-readable label for the contract.\n\nValid values should: - not be empty - not be bigger than 128 bytes (or some chain-specific limit) - not start / end with whitespace", "type": "string" }, "msg": { @@ -792,6 +908,9 @@ "$ref": "#/definitions/Binary" } ] + }, + "salt": { + "$ref": "#/definitions/Binary" } } } @@ -882,6 +1001,21 @@ "additionalProperties": false } ] + }, + "WeightedVoteOption": { + "type": "object", + "required": [ + "option", + "weight" + ], + "properties": { + "option": { + "$ref": "#/definitions/VoteOption" + }, + "weight": { + "$ref": "#/definitions/Decimal" + } + } } } }, @@ -1066,6 +1200,52 @@ } }, "additionalProperties": false + }, + { + "description": "This calls into the native bank module for querying metadata for a specific bank token. Return value is DenomMetadataResponse", + "type": "object", + "required": [ + "denom_metadata" + ], + "properties": { + "denom_metadata": { + "type": "object", + "required": [ + "denom" + ], + "properties": { + "denom": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "This calls into the native bank module for querying metadata for all bank tokens that have a metadata entry. Return value is AllDenomMetadataResponse", + "type": "object", + "required": [ + "all_denom_metadata" + ], + "properties": { + "all_denom_metadata": { + "type": "object", + "properties": { + "pagination": { + "anyOf": [ + { + "$ref": "#/definitions/PageRequest" + }, + { + "type": "null" + } + ] + } + } + } + }, + "additionalProperties": false } ] }, @@ -1073,6 +1253,98 @@ "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", "type": "string" }, + "DistributionQuery": { + "oneOf": [ + { + "description": "See ", + "type": "object", + "required": [ + "delegator_withdraw_address" + ], + "properties": { + "delegator_withdraw_address": { + "type": "object", + "required": [ + "delegator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "See ", + "type": "object", + "required": [ + "delegation_rewards" + ], + "properties": { + "delegation_rewards": { + "type": "object", + "required": [ + "delegator_address", + "validator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + }, + "validator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "See ", + "type": "object", + "required": [ + "delegation_total_rewards" + ], + "properties": { + "delegation_total_rewards": { + "type": "object", + "required": [ + "delegator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + }, + { + "description": "See ", + "type": "object", + "required": [ + "delegator_validators" + ], + "properties": { + "delegator_validators": { + "type": "object", + "required": [ + "delegator_address" + ], + "properties": { + "delegator_address": { + "type": "string" + } + } + } + }, + "additionalProperties": false + } + ] + }, "IbcQuery": { "description": "These are queries to the various IBC modules to see the state of the contract's IBC connection. These will return errors if the contract is not \"ibc enabled\"", "oneOf": [ @@ -1139,6 +1411,34 @@ } ] }, + "PageRequest": { + "description": "Simplified version of the PageRequest type for pagination from the cosmos-sdk", + "type": "object", + "required": [ + "limit", + "reverse" + ], + "properties": { + "key": { + "anyOf": [ + { + "$ref": "#/definitions/Binary" + }, + { + "type": "null" + } + ] + }, + "limit": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "reverse": { + "type": "boolean" + } + } + }, "QueryRequest_for_SpecialQuery": { "oneOf": [ { @@ -1177,6 +1477,18 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "distribution" + ], + "properties": { + "distribution": { + "$ref": "#/definitions/DistributionQuery" + } + }, + "additionalProperties": false + }, { "description": "A Stargate query is encoded the same way as abci_query, with path and protobuf encoded request data. The format is defined in [ADR-21](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-021-protobuf-query-encoding.md). The response is protobuf encoded data directly without a JSON response wrapper. The caller is responsible for compiling the proper protobuf definitions for both requests and responses.", "type": "object", @@ -1434,7 +1746,7 @@ "additionalProperties": false }, { - "description": "returns a ContractInfoResponse with metadata on the contract from the runtime", + "description": "Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime", "type": "object", "required": [ "contract_info" @@ -1453,6 +1765,29 @@ } }, "additionalProperties": false + }, + { + "description": "Returns a [`CodeInfoResponse`] with metadata of the code", + "type": "object", + "required": [ + "code_info" + ], + "properties": { + "code_info": { + "type": "object", + "required": [ + "code_id" + ], + "properties": { + "code_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + } + } + }, + "additionalProperties": false } ] } diff --git a/contracts/reflect/examples/schema.rs b/contracts/reflect/src/bin/schema.rs similarity index 100% rename from contracts/reflect/examples/schema.rs rename to contracts/reflect/src/bin/schema.rs diff --git a/contracts/reflect/src/contract.rs b/contracts/reflect/src/contract.rs index f760a9a27..2213bd4b9 100644 --- a/contracts/reflect/src/contract.rs +++ b/contracts/reflect/src/contract.rs @@ -9,7 +9,7 @@ use crate::msg::{ CapitalizedResponse, ChainResponse, CustomMsg, ExecuteMsg, InstantiateMsg, OwnerResponse, QueryMsg, RawResponse, SpecialQuery, SpecialResponse, }; -use crate::state::{config, config_read, replies, replies_read, State}; +use crate::state::{load_config, load_reply, save_config, save_reply, State}; #[entry_point] pub fn instantiate( @@ -19,7 +19,7 @@ pub fn instantiate( _msg: InstantiateMsg, ) -> StdResult> { let state = State { owner: info.sender }; - config(deps.storage).save(&state)?; + save_config(deps.storage, &state)?; Ok(Response::default()) } @@ -43,7 +43,7 @@ pub fn try_reflect( info: MessageInfo, msgs: Vec>, ) -> Result, ReflectError> { - let state = config(deps.storage).load()?; + let state = load_config(deps.storage)?; if info.sender != state.owner { return Err(ReflectError::NotCurrentOwner { @@ -67,7 +67,7 @@ pub fn try_reflect_subcall( info: MessageInfo, msgs: Vec>, ) -> Result, ReflectError> { - let state = config(deps.storage).load()?; + let state = load_config(deps.storage)?; if info.sender != state.owner { return Err(ReflectError::NotCurrentOwner { expected: state.owner.into(), @@ -91,16 +91,19 @@ pub fn try_change_owner( new_owner: String, ) -> Result, ReflectError> { let api = deps.api; - config(deps.storage).update(|mut state| { - if info.sender != state.owner { - return Err(ReflectError::NotCurrentOwner { - expected: state.owner.into(), - actual: info.sender.into(), - }); - } - state.owner = api.addr_validate(&new_owner)?; - Ok(state) - })?; + + let mut state = load_config(deps.storage)?; + + if info.sender != state.owner { + return Err(ReflectError::NotCurrentOwner { + expected: state.owner.into(), + actual: info.sender.into(), + }); + } + state.owner = api.addr_validate(&new_owner)?; + + save_config(deps.storage, &state)?; + Ok(Response::new() .add_attribute("action", "change_owner") .add_attribute("owner", new_owner)) @@ -109,8 +112,7 @@ pub fn try_change_owner( /// This just stores the result for future query #[entry_point] pub fn reply(deps: DepsMut, _env: Env, msg: Reply) -> Result { - let key = msg.id.to_be_bytes(); - replies(deps.storage).save(&key, &msg)?; + save_reply(deps.storage, msg.id, &msg)?; Ok(Response::default()) } @@ -126,7 +128,7 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult) -> StdResult { - let state = config_read(deps.storage).load()?; + let state = load_config(deps.storage)?; let resp = OwnerResponse { owner: state.owner.into(), }; @@ -134,8 +136,7 @@ fn query_owner(deps: Deps) -> StdResult { } fn query_subcall(deps: Deps, id: u64) -> StdResult { - let key = id.to_be_bytes(); - replies_read(deps.storage).load(&key) + load_reply(deps.storage, id) } fn query_capitalized(deps: Deps, text: String) -> StdResult { @@ -149,16 +150,14 @@ fn query_chain( request: &QueryRequest, ) -> StdResult { let raw = to_vec(request).map_err(|serialize_err| { - StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err)) + StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}")) })?; match deps.querier.raw_query(&raw) { SystemResult::Err(system_err) => Err(StdError::generic_err(format!( - "Querier system error: {}", - system_err + "Querier system error: {system_err}" ))), SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err(format!( - "Querier contract error: {}", - contract_err + "Querier contract error: {contract_err}" ))), SystemResult::Ok(ContractResult::Ok(value)) => Ok(ChainResponse { data: value }), } @@ -240,7 +239,7 @@ mod tests { let res = execute(deps.as_mut(), mock_env(), info, msg); match res.unwrap_err() { ReflectError::NotCurrentOwner { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -354,7 +353,7 @@ mod tests { ReflectError::Std(StdError::GenericErr { msg, .. }) => { assert!(msg.contains("human address too short")) } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } diff --git a/contracts/reflect/src/state.rs b/contracts/reflect/src/state.rs index b1d52aa3e..417c76315 100644 --- a/contracts/reflect/src/state.rs +++ b/contracts/reflect/src/state.rs @@ -1,10 +1,10 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use cosmwasm_std::{Addr, Reply, Storage}; -use cosmwasm_storage::{ - bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton, - Singleton, +use cosmwasm_std::{ + from_slice, + storage_keys::{namespace_with_key, to_length_prefixed}, + to_vec, Addr, Reply, StdError, StdResult, Storage, }; const CONFIG_KEY: &[u8] = b"config"; @@ -15,18 +15,33 @@ pub struct State { pub owner: Addr, } -pub fn config(storage: &mut dyn Storage) -> Singleton { - singleton(storage, CONFIG_KEY) +pub fn load_reply(storage: &dyn Storage, id: u64) -> StdResult { + storage + .get(&namespace_with_key(&[RESULT_PREFIX], &id.to_be_bytes())) + .ok_or_else(|| StdError::not_found(format!("reply {id}"))) + .and_then(|v| from_slice(&v)) } -pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, CONFIG_KEY) +pub fn save_reply(storage: &mut dyn Storage, id: u64, reply: &Reply) -> StdResult<()> { + storage.set( + &namespace_with_key(&[RESULT_PREFIX], &id.to_be_bytes()), + &to_vec(reply)?, + ); + Ok(()) } -pub fn replies(storage: &mut dyn Storage) -> Bucket { - bucket(storage, RESULT_PREFIX) +pub fn remove_reply(storage: &mut dyn Storage, id: u64) { + storage.remove(&namespace_with_key(&[RESULT_PREFIX], &id.to_be_bytes())); } -pub fn replies_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, RESULT_PREFIX) +pub fn load_config(storage: &dyn Storage) -> StdResult { + storage + .get(&to_length_prefixed(CONFIG_KEY)) + .ok_or_else(|| StdError::not_found("config")) + .and_then(|v| from_slice(&v)) +} + +pub fn save_config(storage: &mut dyn Storage, item: &State) -> StdResult<()> { + storage.set(&to_length_prefixed(CONFIG_KEY), &to_vec(item)?); + Ok(()) } diff --git a/contracts/staking/.cargo/config b/contracts/staking/.cargo/config index 8d4bc738b..f5174787c 100644 --- a/contracts/staking/.cargo/config +++ b/contracts/staking/.cargo/config @@ -1,6 +1,6 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" integration-test = "test --test integration" -schema = "run --example schema" +schema = "run --bin schema" diff --git a/contracts/staking/Cargo.lock b/contracts/staking/Cargo.lock index 5a1dd13bd..a5d1f152f 100644 --- a/contracts/staking/Cargo.lock +++ b/contracts/staking/Cargo.lock @@ -4,11 +4,11 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "gimli 0.27.0", + "gimli 0.28.0", ] [[package]] @@ -19,15 +19,21 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ "getrandom", "once_cell", "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -36,36 +42,36 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" -version = "1.5.3" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bitflags" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -84,51 +102,67 @@ dependencies = [ [[package]] name = "block-buffer" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" -version = "3.11.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.78" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -144,9 +178,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -156,9 +190,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "corosensei" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +checksum = "80128832c58ea9cbd041d2a759ec449224487b2c1e400453d99d244eead87a8e" dependencies = [ "autocfg", "cfg-if", @@ -171,7 +205,7 @@ dependencies = [ name = "cosmwasm-crypto" version = "1.1.9+0.8.1" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -186,7 +220,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -206,7 +240,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -214,6 +248,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,36 +257,29 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.8", "thiserror", - "uint", "uuid", ] -[[package]] -name = "cosmwasm-storage" -version = "1.1.9+0.8.1" -dependencies = [ - "cosmwasm-std", - "serde", -] - [[package]] name = "cosmwasm-vm" version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", - "sha2 0.10.6", + "sha2 0.10.8", "thiserror", "wasmer", "wasmer-middlewares", @@ -259,65 +287,83 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.5" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" dependencies = [ "libc", ] [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -326,29 +372,25 @@ dependencies = [ ] [[package]] -name = "crc32fast" -version = "1.3.2" +name = "cranelift-isle" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" [[package]] -name = "crossbeam-channel" -version = "0.5.6" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -357,37 +399,31 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.9.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -420,9 +456,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ "darling_core", "darling_macro", @@ -430,33 +466,46 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "darling_macro" -version = "0.14.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.39", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -470,7 +519,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -484,11 +533,12 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.6" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.3", + "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle", ] @@ -501,9 +551,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "dyn-clone" -version = "1.0.9" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f94fa09c2aeea5b8839e414b7b841bf429fd25b9c522116ac97ee87856d88b2" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" [[package]] name = "dynasm" @@ -517,7 +567,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -533,14 +583,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ "der", + "digest 0.10.7", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -560,20 +612,19 @@ dependencies = [ [[package]] name = "either" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", - "digest 0.10.6", + "digest 0.10.7", "ff", "generic-array", "group", @@ -601,28 +652,28 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "enumset" -version = "1.0.12" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.6.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -631,20 +682,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -656,27 +698,52 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ "cfg-if", "libc", @@ -696,30 +763,21 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", "subtle", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -730,13 +788,10 @@ dependencies = [ ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "hashbrown" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hex" @@ -750,7 +805,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", ] [[package]] @@ -760,50 +815,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] name = "js-sys" -version = "0.3.60" +version = "0.3.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" dependencies = [ "wasm-bindgen", ] [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", - "sha2 0.10.6", + "once_cell", + "sha2 0.10.8", + "signature", ] [[package]] @@ -820,49 +877,25 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "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 = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "mach" @@ -875,42 +908,42 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] [[package]] name = "memoffset" -version = "0.6.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ "autocfg", ] [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -921,42 +954,20 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" -[[package]] -name = "num_cpus" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" -version = "0.30.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239da7f290cfa979f43f85a8efeee9a8a76d0827c356d37f9d3d7254d6b537fb" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -965,22 +976,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -995,7 +1019,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.109", "version_check", ] @@ -1012,9 +1036,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1036,18 +1060,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1065,9 +1095,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -1075,33 +1105,32 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1117,89 +1146,71 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "rustc-demangle" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" [[package]] name = "schemars" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -1209,21 +1220,21 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.11" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.109", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "seahash" @@ -1233,9 +1244,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", @@ -1247,40 +1258,42 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] @@ -1291,14 +1304,14 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" dependencies = [ "itoa", "ryu", @@ -1339,30 +1352,42 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.6" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.6", + "digest 0.10.7", ] [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ - "digest 0.10.6", + "digest 0.10.7", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "snafu" @@ -1382,14 +1407,14 @@ checksum = "1508efa03c362e23817f96cde18abed596a25219a8b2c66e8db33c03543d315b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1407,7 +1432,6 @@ version = "0.0.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", - "cosmwasm-storage", "cosmwasm-vm", "schemars", "serde", @@ -1415,22 +1439,27 @@ dependencies = [ ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "subtle" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] -name = "subtle" -version = "2.4.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] name = "syn" -version = "1.0.105" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" dependencies = [ "proc-macro2", "quote", @@ -1438,53 +1467,58 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "tempfile" -version = "3.3.0" +name = "target-lexicon" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "14c39fd04924ca3a864207c66fc2cd7d22d7c016007f9ce846cbb9326331930a" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1492,53 +1526,67 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", + "tinyvec", ] [[package]] -name = "unicode-ident" -version = "1.0.5" +name = "url" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1558,9 +1606,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1568,24 +1616,47 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "wasm-bindgen-macro" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1593,92 +1664,84 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.83" +version = "0.2.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" +checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1690,16 +1753,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1709,184 +1772,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.109", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1917,45 +1874,111 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/contracts/staking/Cargo.toml b/contracts/staking/Cargo.toml index 2cb5e43fa..ff7e7f796 100644 --- a/contracts/staking/Cargo.toml +++ b/contracts/staking/Cargo.toml @@ -34,7 +34,6 @@ backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] [dependencies] cosmwasm-schema = { path = "../../packages/schema" } cosmwasm-std = { path = "../../packages/std", default-features = false, features = ["staking"] } -cosmwasm-storage = { path = "../../packages/storage", default-features = false } schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive"] } snafu = "0.6.6" diff --git a/contracts/staking/README.md b/contracts/staking/README.md index 3221f4294..5ecaa7ac7 100644 --- a/contracts/staking/README.md +++ b/contracts/staking/README.md @@ -22,7 +22,7 @@ unbonding period). To show an example of charging for such a service, we allow the contract owner to take a small exit tax, thus maybe 98% of the tokens will be unbonded and sent to the original account, and 2% of the tokens are not unbonded, but rather -transfered to the owners account. (The ownership can also be transfered). +transferred to the owners account. (The ownership can also be transferred). ## Using this project diff --git a/contracts/staking/rustfmt.toml b/contracts/staking/rustfmt.toml deleted file mode 100644 index 11a85e6a9..000000000 --- a/contracts/staking/rustfmt.toml +++ /dev/null @@ -1,15 +0,0 @@ -# stable -newline_style = "unix" -hard_tabs = false -tab_spaces = 4 - -# unstable... should we require `rustup run nightly cargo fmt` ? -# or just update the style guide when they are stable? -#fn_single_line = true -#format_code_in_doc_comments = true -#overflow_delimited_expr = true -#reorder_impl_items = true -#struct_field_align_threshold = 20 -#struct_lit_single_line = true -#report_todo = "Always" - diff --git a/contracts/staking/schema/raw/execute.json b/contracts/staking/schema/raw/execute.json new file mode 100644 index 000000000..159d67cd9 --- /dev/null +++ b/contracts/staking/schema/raw/execute.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Transfer moves the derivative token", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "recipient" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "recipient": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Bond will bond all staking tokens sent with the message and release derivative tokens", + "type": "object", + "required": [ + "bond" + ], + "properties": { + "bond": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Unbond will \"burn\" the given amount of derivative tokens and send the unbonded staking tokens to the message sender (after exit tax is deducted)", + "type": "object", + "required": [ + "unbond" + ], + "properties": { + "unbond": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the chain-defined waiting period (eg. 3 weeks)", + "type": "object", + "required": [ + "claim" + ], + "properties": { + "claim": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Reinvest will check for all accumulated rewards, withdraw them, and re-bond them to the same validator. Anyone can call this, which updates the value of the token (how much under custody).", + "type": "object", + "required": [ + "reinvest" + ], + "properties": { + "reinvest": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "_BondAllTokens can only be called by the contract itself, after all rewards have been withdrawn. This is an example of using \"callbacks\" in message flows. This can only be invoked by the contract itself as a return from Reinvest", + "type": "object", + "required": [ + "__bond_all_tokens" + ], + "properties": { + "__bond_all_tokens": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/schema/raw/instantiate.json b/contracts/staking/schema/raw/instantiate.json new file mode 100644 index 000000000..dd2545711 --- /dev/null +++ b/contracts/staking/schema/raw/instantiate.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "decimals", + "exit_tax", + "min_withdrawal", + "name", + "symbol", + "validator" + ], + "properties": { + "decimals": { + "description": "decimal places of the derivative token (for UI) TODO: does this make sense? Do we need to normalize on this? We don't even know the decimals of the native token", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "exit_tax": { + "description": "this is how much the owner takes as a cut when someone unbonds TODO", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "min_withdrawal": { + "description": "This is the minimum amount we will pull out to reinvest, as well as a minumum that can be unbonded (to avoid needless staking tx)", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "name": { + "description": "name of the derivative token (FIXME: auto-generate?)", + "type": "string" + }, + "symbol": { + "description": "symbol / ticker of the derivative token", + "type": "string" + }, + "validator": { + "description": "This is the validator that all tokens will be bonded to", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/schema/raw/migrate.json b/contracts/staking/schema/raw/migrate.json new file mode 100644 index 000000000..159d67cd9 --- /dev/null +++ b/contracts/staking/schema/raw/migrate.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Transfer moves the derivative token", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "recipient" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "recipient": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Bond will bond all staking tokens sent with the message and release derivative tokens", + "type": "object", + "required": [ + "bond" + ], + "properties": { + "bond": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Unbond will \"burn\" the given amount of derivative tokens and send the unbonded staking tokens to the message sender (after exit tax is deducted)", + "type": "object", + "required": [ + "unbond" + ], + "properties": { + "unbond": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the chain-defined waiting period (eg. 3 weeks)", + "type": "object", + "required": [ + "claim" + ], + "properties": { + "claim": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Reinvest will check for all accumulated rewards, withdraw them, and re-bond them to the same validator. Anyone can call this, which updates the value of the token (how much under custody).", + "type": "object", + "required": [ + "reinvest" + ], + "properties": { + "reinvest": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "_BondAllTokens can only be called by the contract itself, after all rewards have been withdrawn. This is an example of using \"callbacks\" in message flows. This can only be invoked by the contract itself as a return from Reinvest", + "type": "object", + "required": [ + "__bond_all_tokens" + ], + "properties": { + "__bond_all_tokens": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/schema/raw/query.json b/contracts/staking/schema/raw/query.json new file mode 100644 index 000000000..6427a6bc8 --- /dev/null +++ b/contracts/staking/schema/raw/query.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "description": "Balance shows the number of staking derivatives", + "type": "object", + "required": [ + "balance" + ], + "properties": { + "balance": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claims shows the number of tokens this address can access when they are done unbonding", + "type": "object", + "required": [ + "claims" + ], + "properties": { + "claims": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "TokenInfo shows the metadata of the token for UIs", + "type": "object", + "required": [ + "token_info" + ], + "properties": { + "token_info": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Investment shows info on total staking tokens under custody, with which validator, as well as how many derivative tokens are lists. It also shows with the exit tax.", + "type": "object", + "required": [ + "investment" + ], + "properties": { + "investment": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/staking/schema/raw/response_to_balance.json b/contracts/staking/schema/raw/response_to_balance.json new file mode 100644 index 000000000..7dcf4d4a5 --- /dev/null +++ b/contracts/staking/schema/raw/response_to_balance.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "BalanceResponse", + "type": "object", + "required": [ + "balance" + ], + "properties": { + "balance": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/schema/raw/response_to_claims.json b/contracts/staking/schema/raw/response_to_claims.json new file mode 100644 index 000000000..b393e8585 --- /dev/null +++ b/contracts/staking/schema/raw/response_to_claims.json @@ -0,0 +1,20 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ClaimsResponse", + "type": "object", + "required": [ + "claims" + ], + "properties": { + "claims": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false, + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/schema/raw/response_to_investment.json b/contracts/staking/schema/raw/response_to_investment.json new file mode 100644 index 000000000..ffa5b8122 --- /dev/null +++ b/contracts/staking/schema/raw/response_to_investment.json @@ -0,0 +1,75 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InvestmentResponse", + "type": "object", + "required": [ + "exit_tax", + "min_withdrawal", + "nominal_value", + "owner", + "staked_tokens", + "token_supply", + "validator" + ], + "properties": { + "exit_tax": { + "description": "this is how much the owner takes as a cut when someone unbonds", + "allOf": [ + { + "$ref": "#/definitions/Decimal" + } + ] + }, + "min_withdrawal": { + "description": "This is the minimum amount we will pull out to reinvest, as well as a minumum that can be unbonded (to avoid needless staking tx)", + "allOf": [ + { + "$ref": "#/definitions/Uint128" + } + ] + }, + "nominal_value": { + "$ref": "#/definitions/Decimal" + }, + "owner": { + "description": "owner created the contract and takes a cut", + "type": "string" + }, + "staked_tokens": { + "$ref": "#/definitions/Coin" + }, + "token_supply": { + "$ref": "#/definitions/Uint128" + }, + "validator": { + "description": "All tokens are bonded to this validator", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + } + }, + "Decimal": { + "description": "A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0\n\nThe greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18)", + "type": "string" + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/schema/raw/response_to_token_info.json b/contracts/staking/schema/raw/response_to_token_info.json new file mode 100644 index 000000000..76b139ecf --- /dev/null +++ b/contracts/staking/schema/raw/response_to_token_info.json @@ -0,0 +1,28 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "TokenInfoResponse", + "description": "TokenInfoResponse is info to display the derivative token in a UI", + "type": "object", + "required": [ + "decimals", + "name", + "symbol" + ], + "properties": { + "decimals": { + "description": "decimal places of the derivative token (for UI)", + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "name": { + "description": "name of the derivative token", + "type": "string" + }, + "symbol": { + "description": "symbol / ticker of the derivative token", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/staking/schema/raw/sudo.json b/contracts/staking/schema/raw/sudo.json new file mode 100644 index 000000000..159d67cd9 --- /dev/null +++ b/contracts/staking/schema/raw/sudo.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Transfer moves the derivative token", + "type": "object", + "required": [ + "transfer" + ], + "properties": { + "transfer": { + "type": "object", + "required": [ + "amount", + "recipient" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "recipient": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Bond will bond all staking tokens sent with the message and release derivative tokens", + "type": "object", + "required": [ + "bond" + ], + "properties": { + "bond": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Unbond will \"burn\" the given amount of derivative tokens and send the unbonded staking tokens to the message sender (after exit tax is deducted)", + "type": "object", + "required": [ + "unbond" + ], + "properties": { + "unbond": { + "type": "object", + "required": [ + "amount" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Claim is used to claim your native tokens that you previously \"unbonded\" after the chain-defined waiting period (eg. 3 weeks)", + "type": "object", + "required": [ + "claim" + ], + "properties": { + "claim": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Reinvest will check for all accumulated rewards, withdraw them, and re-bond them to the same validator. Anyone can call this, which updates the value of the token (how much under custody).", + "type": "object", + "required": [ + "reinvest" + ], + "properties": { + "reinvest": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "_BondAllTokens can only be called by the contract itself, after all rewards have been withdrawn. This is an example of using \"callbacks\" in message flows. This can only be invoked by the contract itself as a return from Reinvest", + "type": "object", + "required": [ + "__bond_all_tokens" + ], + "properties": { + "__bond_all_tokens": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/staking/examples/schema.rs b/contracts/staking/src/bin/schema.rs similarity index 100% rename from contracts/staking/examples/schema.rs rename to contracts/staking/src/bin/schema.rs diff --git a/contracts/staking/src/contract.rs b/contracts/staking/src/contract.rs index 558265209..19295f8ef 100644 --- a/contracts/staking/src/contract.rs +++ b/contracts/staking/src/contract.rs @@ -10,8 +10,8 @@ use crate::msg::{ TokenInfoResponse, }; use crate::state::{ - balances, balances_read, claims, claims_read, invest_info, invest_info_read, token_info, - token_info_read, total_supply, total_supply_read, InvestmentInfo, Supply, TokenInfo, + load_item, may_load_map, save_item, save_map, update_item, InvestmentInfo, Supply, TokenInfo, + KEY_INVESTMENT, KEY_TOKEN_INFO, KEY_TOTAL_SUPPLY, PREFIX_BALANCE, PREFIX_CLAIMS, }; const FALLBACK_RATIO: Decimal = Decimal::one(); @@ -37,7 +37,7 @@ pub fn instantiate( symbol: msg.symbol, decimals: msg.decimals, }; - token_info(deps.storage).save(&token)?; + save_item(deps.storage, KEY_TOKEN_INFO, &token)?; let denom = deps.querier.query_bonded_denom()?; let invest = InvestmentInfo { @@ -47,11 +47,11 @@ pub fn instantiate( validator: msg.validator, min_withdrawal: msg.min_withdrawal, }; - invest_info(deps.storage).save(&invest)?; + save_item(deps.storage, KEY_INVESTMENT, &invest)?; // set supply to 0 let supply = Supply::default(); - total_supply(deps.storage).save(&supply)?; + save_item(deps.storage, KEY_TOTAL_SUPPLY, &supply)?; Ok(Response::default()) } @@ -85,13 +85,15 @@ pub fn transfer( let rcpt_raw = deps.api.addr_canonicalize(&recipient)?; let sender_raw = deps.api.addr_canonicalize(info.sender.as_str())?; - let mut accounts = balances(deps.storage); - accounts.update(&sender_raw, |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default().checked_sub(send)?) - })?; - accounts.update(&rcpt_raw, |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default() + send) - })?; + let balance = may_load_map(deps.storage, PREFIX_BALANCE, &sender_raw)?.unwrap_or_default(); + save_map( + deps.storage, + PREFIX_BALANCE, + &sender_raw, + balance.checked_sub(send)?, + )?; + let balance = may_load_map(deps.storage, PREFIX_BALANCE, &rcpt_raw)?.unwrap_or_default(); + save_map(deps.storage, PREFIX_BALANCE, &rcpt_raw, balance + send)?; let res = Response::new() .add_attribute("action", "transfer") @@ -109,8 +111,7 @@ fn get_bonded(querier: &QuerierWrapper, contract_addr: impl Into) -> Std return Ok(Uint128::new(0)); } let denom = bonds[0].amount.denom.as_str(); - bonds.iter().fold(Ok(Uint128::new(0)), |racc, d| { - let acc = racc?; + bonds.iter().try_fold(Uint128::zero(), |acc, d| { if d.amount.denom.as_str() != denom { Err(StdError::generic_err(format!( "different denoms in bonds: '{}' vs '{}'", @@ -137,7 +138,7 @@ pub fn bond(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { let sender_raw = deps.api.addr_canonicalize(info.sender.as_str())?; // ensure we have the proper denom - let invest = invest_info_read(deps.storage).load()?; + let invest: InvestmentInfo = load_item(deps.storage, KEY_INVESTMENT)?; // payment finds the proper coin (or throws an error) let payment = info .funds @@ -149,8 +150,7 @@ pub fn bond(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { let bonded = get_bonded(&deps.querier, env.contract.address)?; // calculate to_mint and update total supply - let mut totals = total_supply(deps.storage); - let mut supply = totals.load()?; + let mut supply: Supply = load_item(deps.storage, KEY_TOTAL_SUPPLY)?; // TODO: this is just temporary check - we should use dynamic query or have a way to recover assert_bonds(&supply, bonded)?; let to_mint = if supply.issued.is_zero() || bonded.is_zero() { @@ -160,12 +160,11 @@ pub fn bond(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { }; supply.bonded = bonded + payment.amount; supply.issued += to_mint; - totals.save(&supply)?; + save_item(deps.storage, KEY_TOTAL_SUPPLY, &supply)?; // update the balance of the sender - balances(deps.storage).update(&sender_raw, |balance| -> StdResult<_> { - Ok(balance.unwrap_or_default() + to_mint) - })?; + let balance = may_load_map(deps.storage, PREFIX_BALANCE, &sender_raw)?.unwrap_or_default(); + save_map(deps.storage, PREFIX_BALANCE, &sender_raw, balance + to_mint)?; // bond them to the validator let res = Response::new() @@ -181,7 +180,7 @@ pub fn bond(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { } pub fn unbond(deps: DepsMut, env: Env, info: MessageInfo, amount: Uint128) -> StdResult { - let invest = invest_info_read(deps.storage).load()?; + let invest: InvestmentInfo = load_item(deps.storage, KEY_INVESTMENT)?; // ensure it is big enough to care if amount < invest.min_withdrawal { return Err(StdError::generic_err(format!( @@ -197,15 +196,17 @@ pub fn unbond(deps: DepsMut, env: Env, info: MessageInfo, amount: Uint128) -> St let tax = amount * invest.exit_tax; // deduct all from the account - let mut accounts = balances(deps.storage); - accounts.update(&sender_raw, |balance| -> StdResult<_> { - Ok(balance.unwrap_or_default().checked_sub(amount)?) - })?; + let balance = may_load_map(deps.storage, PREFIX_BALANCE, &sender_raw)?.unwrap_or_default(); + save_map( + deps.storage, + PREFIX_BALANCE, + &sender_raw, + balance.checked_sub(amount)?, + )?; if tax > Uint128::new(0) { // add tax to the owner - accounts.update(&owner_raw, |balance: Option| -> StdResult<_> { - Ok(balance.unwrap_or_default() + tax) - })?; + let balance = may_load_map(deps.storage, PREFIX_BALANCE, &owner_raw)?.unwrap_or_default(); + save_map(deps.storage, PREFIX_BALANCE, &owner_raw, balance + tax)?; } // re-calculate bonded to ensure we have real values @@ -214,20 +215,18 @@ pub fn unbond(deps: DepsMut, env: Env, info: MessageInfo, amount: Uint128) -> St // calculate how many native tokens this is worth and update supply let remainder = amount.checked_sub(tax)?; - let mut totals = total_supply(deps.storage); - let mut supply = totals.load()?; + let mut supply: Supply = load_item(deps.storage, KEY_TOTAL_SUPPLY)?; // TODO: this is just temporary check - we should use dynamic query or have a way to recover assert_bonds(&supply, bonded)?; let unbond = remainder.multiply_ratio(bonded, supply.issued); supply.bonded = bonded.checked_sub(unbond)?; supply.issued = supply.issued.checked_sub(remainder)?; supply.claims += unbond; - totals.save(&supply)?; + save_item(deps.storage, KEY_TOTAL_SUPPLY, &supply)?; // add a claim to this user to get their tokens after the unbonding period - claims(deps.storage).update(&sender_raw, |claim| -> StdResult<_> { - Ok(claim.unwrap_or_default() + unbond) - })?; + let claim = may_load_map(deps.storage, PREFIX_CLAIMS, &sender_raw)?.unwrap_or_default(); + save_map(deps.storage, PREFIX_CLAIMS, &sender_raw, claim + unbond)?; // unbond them let res = Response::new() @@ -244,7 +243,7 @@ pub fn unbond(deps: DepsMut, env: Env, info: MessageInfo, amount: Uint128) -> St pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult { // find how many tokens the contract has - let invest = invest_info_read(deps.storage).load()?; + let invest: InvestmentInfo = load_item(deps.storage, KEY_INVESTMENT)?; let mut balance = deps .querier .query_balance(env.contract.address, invest.bond_denom)?; @@ -256,18 +255,20 @@ pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult // check how much to send - min(balance, claims[sender]), and reduce the claim let sender_raw = deps.api.addr_canonicalize(info.sender.as_str())?; - let mut to_send = balance.amount; - claims(deps.storage).update(sender_raw.as_slice(), |claim| -> StdResult<_> { - let claim = claim.ok_or_else(|| StdError::generic_err("no claim for this address"))?; - to_send = to_send.min(claim); - Ok(claim.checked_sub(to_send)?) - })?; + let claim = may_load_map(deps.storage, PREFIX_CLAIMS, &sender_raw)? + .ok_or_else(|| StdError::generic_err("no claim for this address"))?; + let to_send = balance.amount.min(claim); + save_map( + deps.storage, + PREFIX_CLAIMS, + &sender_raw, + claim.checked_sub(to_send)?, + )?; // update total supply (lower claim) - total_supply(deps.storage).update(|mut supply| -> StdResult<_> { - supply.claims = supply.claims.checked_sub(to_send)?; - Ok(supply) - })?; + let mut supply: Supply = load_item(deps.storage, KEY_TOTAL_SUPPLY)?; + supply.claims = supply.claims.checked_sub(to_send)?; + save_item(deps.storage, KEY_TOTAL_SUPPLY, &supply)?; // transfer tokens to the sender balance.amount = to_send; @@ -287,7 +288,7 @@ pub fn claim(deps: DepsMut, env: Env, info: MessageInfo) -> StdResult /// to reinvest the new earnings (and anything else that accumulated) pub fn reinvest(deps: DepsMut, env: Env, _info: MessageInfo) -> StdResult { let contract_addr = env.contract.address; - let invest = invest_info_read(deps.storage).load()?; + let invest: InvestmentInfo = load_item(deps.storage, KEY_INVESTMENT)?; let msg = to_binary(&ExecuteMsg::_BondAllTokens {})?; // and bond them to the validator @@ -314,14 +315,14 @@ pub fn _bond_all_tokens( } // find how many tokens we have to bond - let invest = invest_info_read(deps.storage).load()?; + let invest: InvestmentInfo = load_item(deps.storage, KEY_INVESTMENT)?; let mut balance = deps .querier .query_balance(env.contract.address, &invest.bond_denom)?; // we deduct pending claims from our account balance before reinvesting. // if there is not enough funds, we just return a no-op - match total_supply(deps.storage).update(|mut supply| { + match update_item(deps.storage, KEY_TOTAL_SUPPLY, |mut supply: Supply| { balance.amount = balance.amount.checked_sub(supply.claims)?; // this just triggers the "no op" case if we don't have min_withdrawal left to reinvest balance.amount.checked_sub(invest.min_withdrawal)?; @@ -360,7 +361,7 @@ pub fn query_token_info(deps: Deps) -> StdResult { name, symbol, decimals, - } = token_info_read(deps.storage).load()?; + } = load_item(deps.storage, KEY_TOKEN_INFO)?; Ok(TokenInfoResponse { name, @@ -371,23 +372,19 @@ pub fn query_token_info(deps: Deps) -> StdResult { pub fn query_balance(deps: Deps, address: &str) -> StdResult { let address_raw = deps.api.addr_canonicalize(address)?; - let balance = balances_read(deps.storage) - .may_load(address_raw.as_slice())? - .unwrap_or_default(); + let balance = may_load_map(deps.storage, PREFIX_BALANCE, &address_raw)?.unwrap_or_default(); Ok(BalanceResponse { balance }) } pub fn query_claims(deps: Deps, address: &str) -> StdResult { let address_raw = deps.api.addr_canonicalize(address)?; - let claims = claims_read(deps.storage) - .may_load(address_raw.as_slice())? - .unwrap_or_default(); + let claims = may_load_map(deps.storage, PREFIX_CLAIMS, &address_raw)?.unwrap_or_default(); Ok(ClaimsResponse { claims }) } pub fn query_investment(deps: Deps) -> StdResult { - let invest = invest_info_read(deps.storage).load()?; - let supply = total_supply_read(deps.storage).load()?; + let invest: InvestmentInfo = load_item(deps.storage, KEY_INVESTMENT)?; + let supply: Supply = load_item(deps.storage, KEY_TOTAL_SUPPLY)?; let res = InvestmentResponse { owner: invest.owner.into(), @@ -572,7 +569,7 @@ mod tests { assert_eq!(validator.as_str(), DEFAULT_VALIDATOR); assert_eq!(amount, &coin(1000, "ustake")); } - _ => panic!("Unexpected message: {:?}", delegate), + _ => panic!("Unexpected message: {delegate:?}"), } // bob got 1000 DRV for 1000 stake at a 1.0 ratio @@ -668,7 +665,7 @@ mod tests { StakingError::Std { original: StdError::GenericErr { msg, .. }, } => assert_eq!(msg, "No ustake tokens sent"), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), }; } @@ -717,7 +714,7 @@ mod tests { StakingError::Std { original: StdError::Overflow { .. }, } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } // bob unbonds 600 tokens at 10% tax... @@ -738,7 +735,7 @@ mod tests { assert_eq!(validator.as_str(), DEFAULT_VALIDATOR); assert_eq!(amount, &coin(bobs_claim.u128(), "ustake")); } - _ => panic!("Unexpected message: {:?}", delegate), + _ => panic!("Unexpected message: {delegate:?}"), } // update the querier with new bond, lower balance diff --git a/contracts/staking/src/state.rs b/contracts/staking/src/state.rs index 99a9f3b9d..40e875db2 100644 --- a/contracts/staking/src/state.rs +++ b/contracts/staking/src/state.rs @@ -1,10 +1,12 @@ +use std::any::type_name; + use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use cosmwasm_std::{Addr, Decimal, Storage, Uint128}; -use cosmwasm_storage::{ - bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton, - Singleton, +use cosmwasm_std::{ + from_slice, + storage_keys::{namespace_with_key, to_length_prefixed}, + to_vec, Addr, CanonicalAddr, Decimal, StdError, StdResult, Storage, Uint128, }; pub const KEY_INVESTMENT: &[u8] = b"invest"; @@ -14,22 +16,30 @@ pub const KEY_TOTAL_SUPPLY: &[u8] = b"total_supply"; pub const PREFIX_BALANCE: &[u8] = b"balance"; pub const PREFIX_CLAIMS: &[u8] = b"claim"; -/// balances are state of the erc20 tokens -pub fn balances(storage: &mut dyn Storage) -> Bucket { - bucket(storage, PREFIX_BALANCE) -} - -pub fn balances_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, PREFIX_BALANCE) +pub fn may_load_map( + storage: &dyn Storage, + prefix: &[u8], + key: &CanonicalAddr, +) -> StdResult> { + storage + .get(&namespace_with_key(&[prefix], key)) + .map(|v| from_slice(&v)) + .transpose() } -/// claims are the claims to money being unbonded -pub fn claims(storage: &mut dyn Storage) -> Bucket { - bucket(storage, PREFIX_CLAIMS) +pub fn save_map( + storage: &mut dyn Storage, + prefix: &[u8], + key: &CanonicalAddr, + value: Uint128, +) -> StdResult<()> { + storage.set(&namespace_with_key(&[prefix], key), &to_vec(&value)?); + Ok(()) } -pub fn claims_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, PREFIX_CLAIMS) +pub fn load_map(storage: &dyn Storage, prefix: &[u8], key: &CanonicalAddr) -> StdResult { + may_load_map(storage, prefix, key)? + .ok_or_else(|| StdError::not_found(format!("map value for {key}"))) } /// Investment info is fixed at initialization, and is used to control the function of the contract @@ -71,26 +81,26 @@ pub struct Supply { pub claims: Uint128, } -pub fn invest_info(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_INVESTMENT) -} - -pub fn invest_info_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, KEY_INVESTMENT) -} - -pub fn token_info(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_TOKEN_INFO) -} - -pub fn token_info_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, KEY_TOKEN_INFO) +pub fn load_item(storage: &dyn Storage, key: &[u8]) -> StdResult { + storage + .get(&to_length_prefixed(key)) + .ok_or_else(|| StdError::not_found(type_name::())) + .and_then(|v| from_slice(&v)) } -pub fn total_supply(storage: &mut dyn Storage) -> Singleton { - singleton(storage, KEY_TOTAL_SUPPLY) +pub fn save_item(storage: &mut dyn Storage, key: &[u8], item: &T) -> StdResult<()> { + storage.set(&to_length_prefixed(key), &to_vec(item)?); + Ok(()) } -pub fn total_supply_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, KEY_TOTAL_SUPPLY) +pub fn update_item(storage: &mut dyn Storage, key: &[u8], action: A) -> Result +where + T: Serialize + DeserializeOwned, + A: FnOnce(T) -> Result, + E: From, +{ + let input = load_item(storage, key)?; + let output = action(input)?; + save_item(storage, key, &output)?; + Ok(output) } diff --git a/contracts/virus/.cargo/config b/contracts/virus/.cargo/config new file mode 100644 index 000000000..f5174787c --- /dev/null +++ b/contracts/virus/.cargo/config @@ -0,0 +1,6 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +integration-test = "test --test integration" +schema = "run --bin schema" diff --git a/contracts/virus/Cargo.lock b/contracts/virus/Cargo.lock new file mode 100644 index 000000000..591d75b54 --- /dev/null +++ b/contracts/virus/Cargo.lock @@ -0,0 +1,1971 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a2e47a1fbe209ee101dd6d61285226744c6c8d3c21c8dc878ba6cb9f467f3a" +dependencies = [ + "gimli 0.24.0", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + +[[package]] +name = "arrayvec" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7815ea54e4d821e791162e078acbebfd6d8c8939cd559c9335dceb1c8ca7282" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dea908e7347a8c64e378c17e30ef880ad73e3b4498346b055c2c00ea342f3179" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "bytecheck" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13fe11640a23eb24562225322cd3e452b93a3d4091d62fab69c70542fcd17d1f" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31225543cb46f81a7e224762764f4a6a0f097b1db0b175f69e8065efaa42de5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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" + +[[package]] +name = "cc" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clru" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" + +[[package]] +name = "const-oid" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795bc6e66a8e340f075fcf6227e417a2dc976b92b91f3cdc778bb858778b6747" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "corosensei" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9847f90f32a50b0dcbd68bc23ff242798b13080b97b0569f6ed96a45ce4cf2cd" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "scopeguard", + "windows-sys", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.1.9+0.8.1" +dependencies = [ + "digest 0.10.7", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "sha-1", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.1.9+0.8.1" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.1.9+0.8.1" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.1.9+0.8.1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cosmwasm-std" +version = "1.1.9+0.8.1" +dependencies = [ + "base64", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.3", + "thiserror", + "uuid", +] + +[[package]] +name = "cosmwasm-vm" +version = "1.1.9+0.8.1" +dependencies = [ + "bitflags", + "bytecheck", + "bytes", + "clru", + "cosmwasm-crypto", + "cosmwasm-std", + "crc32fast", + "derivative", + "enumset", + "hex", + "schemars", + "serde", + "serde_json", + "sha2 0.10.3", + "thiserror", + "wasmer", + "wasmer-middlewares", +] + +[[package]] +name = "cpufeatures" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +dependencies = [ + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "cranelift-bforest" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" +dependencies = [ + "cranelift-entity", +] + +[[package]] +name = "cranelift-codegen" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" +dependencies = [ + "arrayvec", + "bumpalo", + "cranelift-bforest", + "cranelift-codegen-meta", + "cranelift-codegen-shared", + "cranelift-egraph", + "cranelift-entity", + "cranelift-isle", + "gimli 0.26.1", + "log", + "regalloc2", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-codegen-meta" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" +dependencies = [ + "cranelift-codegen-shared", +] + +[[package]] +name = "cranelift-codegen-shared" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown", + "indexmap", + "log", + "smallvec", +] + +[[package]] +name = "cranelift-entity" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" + +[[package]] +name = "cranelift-frontend" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" +dependencies = [ + "cranelift-codegen", + "log", + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "lazy_static", + "memoffset 0.6.4", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if", + "lazy_static", +] + +[[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 = "curve25519-dalek" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639891fde0dbea823fc3d798a0fdf9d2f9440a42d64a78ab3488b0ca025117b3" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "757c0ded2af11d8e739c4daea1ac623dd1624b06c844cf3f5a39f1bdbd99bb12" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c34d8efb62d0c2d7f60ece80f75e5c63c1588ba68032740494b0b9a996466e3" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade7bff147130fe5e6d39f089c6bd49ec0250f35d70b2eebf72afdfc919f15cc" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "der" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ed52955ce76b1554f509074bb357d3fb8ac9b51288a65a3fd480d1dfba946" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.2", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + +[[package]] +name = "dynasm" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add9a102807b524ec050363f09e06f1504214b0e1c7797f64261c891022dce8b" +dependencies = [ + "bitflags", + "byteorder", + "lazy_static", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "dynasmrt" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64fba5a42bd76a17cad4bfa00de168ee1cbfa06a5e8ce992ae880218c05641a9" +dependencies = [ + "byteorder", + "dynasm", + "memmap2", +] + +[[package]] +name = "ecdsa" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519-zebra" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "403ef3e961ab98f0ba902771d29f842058578bb1ce7e3c59dad5a6a93e784c69" +dependencies = [ + "curve25519-dalek", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.5", + "thiserror", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "elliptic-curve" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-iterator" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eeac5c5edb79e4e39fe8439ef35207780a11f69c52cbe424ce3dfad4cb78de6" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "enumset" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e76129da36102af021b8e5000dab2c1c30dbef85c1e482beeff8da5dde0e0b0" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6451128aa6655d880755345d085494cf7561a6bee7c8dc821e5d77e6d267ecd4" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[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 = "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 = "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.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4075386626662786ddb0ec9081e7c7eeb1ba31951f447ca780ef9f5d568189" + +[[package]] +name = "gimli" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[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 = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.3", + "signature", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "leb128" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memmap2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4647a11b578fead29cdbb34d4adef8dd3dc35b876c9c6d5240d83f205abfe96e" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "more-asserts" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a38f2be3697a57b4060074ff41b44c16870d916ad7877c17696e063257482bc7" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[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", + "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.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regalloc2" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" +dependencies = [ + "fxhash", + "log", + "slice-group-by", + "smallvec", +] + +[[package]] +name = "region" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76e189c2369884dce920945e2ddf79b3dff49e071a167dd1817fa9c4c00d512e" +dependencies = [ + "bitflags", + "libc", + "mach", + "winapi", +] + +[[package]] +name = "rend" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rkyv" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21499ed91807f07ae081880aabb2ccc0235e9d88011867d984525e9a4c3cfa3e" +dependencies = [ + "bytecheck", + "hashbrown", + "indexmap", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1c672430eb41556291981f45ca900a0239ad007242d1cb4b4167af842db666" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "schemars" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "serde" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" +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-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "963a7dbc9895aeac7ac90e74f34a5d5261828f79df35cbed41e10189d3804d43" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[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", +] + +[[package]] +name = "serde_json" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures 0.2.2", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures 0.1.5", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899bf02746a2c92bf1053d9327dadb252b01af1f81f90cdb902411f518bc7215" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.2", + "digest 0.10.7", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b634d87b960ab1a38c4fe143b508576f075e7c978bfad18217645ebfdfa2ec" + +[[package]] +name = "smallvec" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" + +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "target-lexicon" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" + +[[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", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tracing" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +dependencies = [ + "cfg-if", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[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 = "uuid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" +dependencies = [ + "serde", + "sha1_smol", +] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "virus" +version = "0.0.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cosmwasm-vm", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "wasmer" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" +dependencies = [ + "bytes", + "cfg-if", + "derivative", + "indexmap", + "js-sys", + "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", + "target-lexicon", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-downcast", + "wasmer-compiler", + "wasmer-compiler-cranelift", + "wasmer-compiler-singlepass", + "wasmer-derive", + "wasmer-types", + "wasmer-vm", + "winapi", +] + +[[package]] +name = "wasmer-compiler" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" +dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", + "enumset", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", + "smallvec", + "thiserror", + "wasmer-types", + "wasmer-vm", + "wasmparser", + "winapi", +] + +[[package]] +name = "wasmer-compiler-cranelift" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" +dependencies = [ + "cranelift-codegen", + "cranelift-entity", + "cranelift-frontend", + "gimli 0.26.1", + "more-asserts", + "rayon", + "smallvec", + "target-lexicon", + "tracing", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-compiler-singlepass" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" +dependencies = [ + "byteorder", + "dynasm", + "dynasmrt", + "enumset", + "gimli 0.26.1", + "lazy_static", + "more-asserts", + "rayon", + "smallvec", + "wasmer-compiler", + "wasmer-types", +] + +[[package]] +name = "wasmer-derive" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "wasmer-middlewares" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" +dependencies = [ + "wasmer", + "wasmer-types", + "wasmer-vm", +] + +[[package]] +name = "wasmer-types" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" +dependencies = [ + "bytecheck", + "enum-iterator", + "enumset", + "indexmap", + "more-asserts", + "rkyv", + "target-lexicon", + "thiserror", +] + +[[package]] +name = "wasmer-vm" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" +dependencies = [ + "backtrace", + "cc", + "cfg-if", + "corosensei", + "dashmap", + "derivative", + "enum-iterator", + "fnv", + "indexmap", + "lazy_static", + "libc", + "mach", + "memoffset 0.8.0", + "more-asserts", + "region", + "scopeguard", + "thiserror", + "wasmer-types", + "winapi", +] + +[[package]] +name = "wasmparser" +version = "0.95.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" +dependencies = [ + "indexmap", + "url", +] + +[[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-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" +dependencies = [ + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm", + "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", + "windows_x86_64_msvc 0.48.0", +] + +[[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.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" + +[[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.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" + +[[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.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" + +[[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.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" + +[[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.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "zeroize" +version = "1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" diff --git a/contracts/virus/Cargo.toml b/contracts/virus/Cargo.toml new file mode 100644 index 000000000..24df513fa --- /dev/null +++ b/contracts/virus/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "virus" +version = "0.0.0" +authors = ["Simon Warta "] +edition = "2021" +publish = false +license = "Apache-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type = ["cdylib", "rlib"] + +[profile.release] +opt-level = 3 +debug = false +rpath = false +lto = true +debug-assertions = false +codegen-units = 1 +panic = 'abort' +incremental = false +overflow-checks = true + +[features] +# Add feature "cranelift" to default if you need 32 bit or ARM support +default = [] +# Use cranelift backend instead of singlepass. This is required for development on 32 bit or ARM machines. +cranelift = ["cosmwasm-vm/cranelift"] +# for quicker tests, cargo test --lib +# for more explicit tests, cargo test --features=backtraces +backtraces = ["cosmwasm-std/backtraces", "cosmwasm-vm/backtraces"] + +[dependencies] +cosmwasm-schema = { path = "../../packages/schema" } +cosmwasm-std = { path = "../../packages/std", features = ["cosmwasm_1_2"] } +schemars = "0.8.3" +serde = { version = "1.0.103", default-features = false, features = ["derive"] } +thiserror = "1.0.26" + +[dev-dependencies] +cosmwasm-vm = { path = "../../packages/vm", default-features = false, features = ["iterator"] } diff --git a/contracts/virus/README.md b/contracts/virus/README.md new file mode 100644 index 000000000..497dbf17e --- /dev/null +++ b/contracts/virus/README.md @@ -0,0 +1,3 @@ +# Virus contract + +A contract that clones itself over various levels. diff --git a/contracts/virus/schema/raw/execute.json b/contracts/virus/schema/raw/execute.json new file mode 100644 index 000000000..0c6d37f10 --- /dev/null +++ b/contracts/virus/schema/raw/execute.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "spread" + ], + "properties": { + "spread": { + "type": "object", + "required": [ + "levels", + "parent_path" + ], + "properties": { + "levels": { + "description": "The number of levels of spreading. When set to 0, the contract performs a no-op.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "parent_path": { + "description": "A slash separated path to the instance creating this one. The root is the empty string.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/virus/schema/raw/instantiate.json b/contracts/virus/schema/raw/instantiate.json new file mode 100644 index 000000000..1352613d5 --- /dev/null +++ b/contracts/virus/schema/raw/instantiate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/virus/schema/virus.json b/contracts/virus/schema/virus.json new file mode 100644 index 000000000..71f03d096 --- /dev/null +++ b/contracts/virus/schema/virus.json @@ -0,0 +1,50 @@ +{ + "contract_name": "virus", + "contract_version": "0.0.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "spread" + ], + "properties": { + "spread": { + "type": "object", + "required": [ + "levels", + "parent_path" + ], + "properties": { + "levels": { + "description": "The number of levels of spreading. When set to 0, the contract performs a no-op.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "parent_path": { + "description": "A slash separated path to the instance creating this one. The root is the empty string.", + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "query": null, + "migrate": null, + "sudo": null, + "responses": null +} diff --git a/contracts/virus/src/bin/schema.rs b/contracts/virus/src/bin/schema.rs new file mode 100644 index 000000000..341781160 --- /dev/null +++ b/contracts/virus/src/bin/schema.rs @@ -0,0 +1,10 @@ +use cosmwasm_schema::write_api; + +use virus::msg::{ExecuteMsg, InstantiateMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + execute: ExecuteMsg, + } +} diff --git a/contracts/virus/src/contract.rs b/contracts/virus/src/contract.rs new file mode 100644 index 000000000..202881b34 --- /dev/null +++ b/contracts/virus/src/contract.rs @@ -0,0 +1,111 @@ +use cosmwasm_std::{ + entry_point, instantiate2_address, to_binary, Attribute, Binary, CodeInfoResponse, + ContractInfoResponse, DepsMut, Env, MessageInfo, Response, StdResult, WasmMsg, +}; + +use crate::errors::ContractError; +use crate::msg::{ExecuteMsg, InstantiateMsg}; + +#[entry_point] +pub fn instantiate( + _deps: DepsMut, + _env: Env, + _info: MessageInfo, + _msg: InstantiateMsg, +) -> StdResult { + Ok(Response::new()) +} + +#[entry_point] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::Spread { + parent_path, + levels, + } => execute_spread(deps, env, info, parent_path, levels), + } +} + +/// Basic reproduction number +const R0: u32 = 2; + +pub fn execute_spread( + deps: DepsMut, + env: Env, + _info: MessageInfo, + parent_path: String, + levels: u32, +) -> Result { + if levels == 0 { + return Ok(Response::new()); + } + + let creator = deps.api.addr_canonicalize(env.contract.address.as_str())?; + let ContractInfoResponse { code_id, .. } = deps + .querier + .query_wasm_contract_info(env.contract.address)?; + let CodeInfoResponse { checksum, .. } = deps.querier.query_wasm_code_info(code_id)?; + + let mut msgs = Vec::::new(); + let mut attributes = Vec::::new(); + for i in 0..R0 { + let path = format!("{parent_path}/{i}"); + let label = format!("Instance {path}"); + let salt = Binary::from(path.as_bytes()); + + attributes.push(Attribute::new(format!("path{i}"), path.clone())); + + let address = deps + .api + .addr_humanize(&instantiate2_address(&checksum, &creator, &salt)?)?; + attributes.push(Attribute::new( + format!("predicted_address{i}"), + address.clone(), + )); + + msgs.push(WasmMsg::Instantiate2 { + admin: None, + code_id, + label, + msg: to_binary(&InstantiateMsg {})?, + funds: vec![], + salt, + }); + + // we know the address of the newly instantiated contract, so let's execute it right away + msgs.push(WasmMsg::Execute { + contract_addr: address.into(), + msg: to_binary(&ExecuteMsg::Spread { + parent_path: path, + levels: levels - 1, + })?, + funds: vec![], + }); + } + + Ok(Response::new() + .add_attributes(attributes) + .add_messages(msgs)) +} + +#[cfg(test)] +mod tests { + use super::*; + use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; + + const CREATOR: &str = "creator"; + + #[test] + fn instantiate_works() { + let mut deps = mock_dependencies(); + let msg = InstantiateMsg {}; + let info = mock_info(CREATOR, &[]); + let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); + assert_eq!(0, res.messages.len()); + } +} diff --git a/contracts/virus/src/errors.rs b/contracts/virus/src/errors.rs new file mode 100644 index 000000000..5a5361b57 --- /dev/null +++ b/contracts/virus/src/errors.rs @@ -0,0 +1,11 @@ +use cosmwasm_std::{Instantiate2AddressError, StdError}; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum ContractError { + #[error("{0}")] + /// this is needed so we can use `bucket.load(...)?` and have it auto-converted to the custom error + Std(#[from] StdError), + #[error("{0}")] + Instantiate2Address(#[from] Instantiate2AddressError), +} diff --git a/contracts/virus/src/lib.rs b/contracts/virus/src/lib.rs new file mode 100644 index 000000000..33208e28f --- /dev/null +++ b/contracts/virus/src/lib.rs @@ -0,0 +1,3 @@ +pub mod contract; +mod errors; +pub mod msg; diff --git a/contracts/virus/src/msg.rs b/contracts/virus/src/msg.rs new file mode 100644 index 000000000..cdf26cc71 --- /dev/null +++ b/contracts/virus/src/msg.rs @@ -0,0 +1,15 @@ +use cosmwasm_schema::cw_serde; + +#[cw_serde] +pub struct InstantiateMsg {} + +#[cw_serde] +pub enum ExecuteMsg { + Spread { + /// A slash separated path to the instance creating this one. + /// The root is the empty string. + parent_path: String, + /// The number of levels of spreading. When set to 0, the contract performs a no-op. + levels: u32, + }, +} diff --git a/contracts/virus/tests/integration.rs b/contracts/virus/tests/integration.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/contracts/virus/tests/integration.rs @@ -0,0 +1 @@ + diff --git a/contracts/voting-with-uuid/Cargo.lock b/contracts/voting-with-uuid/Cargo.lock index 296d60a18..92014a1a6 100644 --- a/contracts/voting-with-uuid/Cargo.lock +++ b/contracts/voting-with-uuid/Cargo.lock @@ -28,6 +28,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.1.0" @@ -45,21 +51,21 @@ dependencies = [ "cfg-if", "libc", "miniz_oxide", - "object 0.30.0", + "object", "rustc-demangle", ] [[package]] name = "base16ct" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64ct" @@ -73,6 +79,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -91,6 +109,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bnum" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128a44527fc0d6abf05f9eda748b9027536e12dff93f5acc8449f51583309350" + [[package]] name = "bumpalo" version = "3.11.1" @@ -99,23 +123,24 @@ checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" [[package]] name = "bytecheck" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11cac2c12b5adc6570dad2ee1b87eff4955dac476fe12d81e5fdd352e52406f" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" dependencies = [ "bytecheck_derive", "ptr_meta", + "simdutf8", ] [[package]] name = "bytecheck_derive" -version = "0.6.9" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -124,6 +149,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + [[package]] name = "cc" version = "1.0.78" @@ -144,9 +175,9 @@ checksum = "591ff76ca0691bd91c1b0b5b987e5cf93b21ec810ad96665c5a569c60846dd93" [[package]] name = "const-oid" -version = "0.9.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec318a675afcb6a1ea1d4340e2d377e56e47c266f28043ceccbf4412ddfdd3b" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" [[package]] name = "convert_case" @@ -186,7 +217,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -206,7 +237,7 @@ version = "1.1.9+0.8.1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -214,6 +245,7 @@ name = "cosmwasm-std" version = "1.1.9+0.8.1" dependencies = [ "base64", + "bnum", "cosmwasm-crypto", "cosmwasm-derive", "derivative", @@ -222,8 +254,8 @@ dependencies = [ "schemars", "serde", "serde-json-wasm", + "sha2 0.10.6", "thiserror", - "uint", "uuid", ] @@ -241,13 +273,14 @@ version = "1.1.9+0.8.1" dependencies = [ "bitflags", "bytecheck", + "bytes", "clru", "cosmwasm-crypto", "cosmwasm-std", + "crc32fast", + "derivative", "enumset", "hex", - "loupe", - "parity-wasm", "schemars", "serde", "serde_json", @@ -268,56 +301,74 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38faa2a16616c8e78a18d37b4726b98bfd2de192f2fdc8a39ddf568a408a0f75" +checksum = "2a2ab4512dfd3a6f4be184403a195f76e81a8a9f9e6c898e19d2dc3ce20e0115" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f192472a3ba23860afd07d2b0217dc628f21fcc72617aa1336d98e1671f33b" +checksum = "98b022ed2a5913a38839dfbafe6cf135342661293b08049843362df4301261dc" dependencies = [ + "arrayvec", + "bumpalo", "cranelift-bforest", "cranelift-codegen-meta", "cranelift-codegen-shared", + "cranelift-egraph", "cranelift-entity", + "cranelift-isle", "gimli 0.26.2", "log", - "regalloc", + "regalloc2", "smallvec", "target-lexicon", ] [[package]] name = "cranelift-codegen-meta" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32ddb89e9b89d3d9b36a5b7d7ea3261c98235a76ac95ba46826b8ec40b1a24" +checksum = "639307b45434ad112a98f8300c0f0ab085cbefcd767efcdef9ef19d4c0756e74" dependencies = [ "cranelift-codegen-shared", ] [[package]] name = "cranelift-codegen-shared" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01fd0d9f288cc1b42d9333b7a776b17e278fc888c28e6a0f09b5573d45a150bc" +checksum = "278e52e29c53fcf32431ef08406c295699a70306d05a0715c5b1bf50e33a9ab7" + +[[package]] +name = "cranelift-egraph" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624b54323b06e675293939311943ba82d323bb340468ce1889be5da7932c8d73" +dependencies = [ + "cranelift-entity", + "fxhash", + "hashbrown 0.12.3", + "indexmap", + "log", + "smallvec", +] [[package]] name = "cranelift-entity" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3bfe172b83167604601faf9dc60453e0d0a93415b57a9c4d1a7ae6849185cf" +checksum = "9a59bcbca89c3f1b70b93ab3cbba5e5e0cbf3e63dadb23c7525cb142e21a9d4c" [[package]] name = "cranelift-frontend" -version = "0.82.3" +version = "0.91.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a006e3e32d80ce0e4ba7f1f9ddf66066d052a8c884a110b91d05404d6ce26dce" +checksum = "0d70abacb8cfef3dc8ff7e8836e9c1d70f7967dfdac824a4cd5e30223415aca6" dependencies = [ "cranelift-codegen", "log", @@ -325,6 +376,12 @@ dependencies = [ "target-lexicon", ] +[[package]] +name = "cranelift-isle" +version = "0.91.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "393bc73c451830ff8dbb3a07f61843d6cb41a084f9996319917c0b291ed785bb" + [[package]] name = "crc32fast" version = "1.3.2" @@ -377,17 +434,11 @@ 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" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -452,7 +503,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -463,14 +514,27 @@ checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.105", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.2", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] name = "der" -version = "0.6.1" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" dependencies = [ "const-oid", "zeroize", @@ -484,7 +548,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -503,6 +567,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] @@ -525,7 +590,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -541,14 +606,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.14.8" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ "der", + "digest 0.10.6", "elliptic-curve", "rfc6979", "signature", + "spki", ] [[package]] @@ -574,13 +641,12 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" [[package]] name = "elliptic-curve" -version = "0.12.3" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914" dependencies = [ "base16ct", "crypto-bigint", - "der", "digest 0.10.6", "ff", "generic-array", @@ -609,7 +675,7 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -630,7 +696,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -639,20 +705,11 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" -[[package]] -name = "fastrand" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" -dependencies = [ - "instant", -] - [[package]] name = "ff" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core 0.6.4", "subtle", @@ -664,12 +721,36 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +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 = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[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.6" @@ -678,6 +759,7 @@ checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -710,9 +792,9 @@ checksum = "dec7af912d60cdbd3677c1af9352ebae6fb8394d165568a2234df0fa00f87793" [[package]] name = "group" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core 0.6.4", @@ -721,21 +803,18 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ "ahash", ] [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash", -] +checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" [[package]] name = "hermit-abi" @@ -768,23 +847,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "unicode-bidi", + "unicode-normalization", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ - "cfg-if", + "autocfg", + "hashbrown 0.12.3", ] [[package]] @@ -804,14 +883,16 @@ dependencies = [ [[package]] name = "k256" -version = "0.11.6" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", "ecdsa", "elliptic-curve", + "once_cell", "sha2 0.10.6", + "signature", ] [[package]] @@ -833,13 +914,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" [[package]] -name = "libloading" -version = "0.7.4" +name = "lock_api" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ - "cfg-if", - "winapi", + "autocfg", + "scopeguard", ] [[package]] @@ -851,27 +932,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "loupe" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6a72dfa44fe15b5e76b94307eeb2ff995a8c5b283b55008940c02e0c5b634d" -dependencies = [ - "indexmap", - "loupe-derive", - "rustversion", -] - -[[package]] -name = "loupe-derive" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "mach" version = "0.3.2" @@ -898,18 +958,18 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -939,18 +999,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.28.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" -dependencies = [ - "crc32fast", - "hashbrown 0.11.2", - "indexmap", - "memchr", -] - [[package]] name = "object" version = "0.30.0" @@ -962,9 +1010,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" @@ -973,10 +1021,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] -name = "parity-wasm" -version = "0.42.2" +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "percent-encoding" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be5e13c266502aadf83426d87d81a0f5d1ef45b8027f5a471c360abfe4bfae92" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pin-project-lite" @@ -986,9 +1047,9 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pkcs8" -version = "0.9.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der", "spki", @@ -1003,7 +1064,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.105", "version_check", ] @@ -1020,9 +1081,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" dependencies = [ "unicode-ident", ] @@ -1044,18 +1105,24 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand_core" version = "0.5.1" @@ -1095,21 +1162,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.16" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags", ] [[package]] -name = "regalloc" -version = "0.0.34" +name = "regalloc2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62446b1d3ebf980bdc68837700af1d77b37bc430e524bf95319c6eada2a4cc02" +checksum = "300d4fbfb40c1c66a78ba3ddd41c1110247cf52f97b87d0f2fc9209bd49b030c" dependencies = [ + "fxhash", "log", - "rustc-hash", + "slice-group-by", "smallvec", ] @@ -1125,58 +1193,52 @@ dependencies = [ "winapi", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "rend" -version = "0.3.6" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] [[package]] name = "rfc6979" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "crypto-bigint", "hmac", - "zeroize", + "subtle", ] [[package]] name = "rkyv" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cec2b3485b07d96ddfd3134767b8a447b45ea4eb91448d0a35180ec0ffd5ed15" +checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" dependencies = [ + "bitvec", "bytecheck", "hashbrown 0.12.3", + "indexmap", "ptr_meta", "rend", "rkyv_derive", "seahash", + "tinyvec", + "uuid", ] [[package]] name = "rkyv_derive" -version = "0.7.39" +version = "0.7.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eaedadc88b53e36dd32d940ed21ae4d850d5916f2581526921f553a72ac34c4" +checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1185,18 +1247,6 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustversion" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" - [[package]] name = "ryu" version = "1.0.11" @@ -1224,7 +1274,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 1.0.105", ] [[package]] @@ -1241,9 +1291,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "sec1" -version = "0.3.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +checksum = "48518a2b5775ba8ca5b46596aae011caa431e6ce7e4a67ead66d92f08884220e" dependencies = [ "base16ct", "der", @@ -1264,20 +1314,22 @@ dependencies = [ [[package]] name = "serde-json-wasm" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479b4dbc401ca13ee8ce902851b834893251404c4f3c65370a49e047a6be09a5" +checksum = "16a62a1fad1e1828b24acac8f2b468971dade7b8c3c2e672bcadefefb1f8c137" dependencies = [ "serde", ] [[package]] -name = "serde_bytes" -version = "0.11.7" +name = "serde-wasm-bindgen" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfc50e8183eeeb6178dcb167ae34a8051d63535023ae38b5d8d12beae193d37b" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" dependencies = [ + "js-sys", "serde", + "wasm-bindgen", ] [[package]] @@ -1288,7 +1340,7 @@ checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1299,7 +1351,7 @@ checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1358,14 +1410,26 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.4" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" dependencies = [ "digest 0.10.6", "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "slice-group-by" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7" + [[package]] name = "smallvec" version = "1.10.0" @@ -1374,9 +1438,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "spki" -version = "0.6.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", "der", @@ -1388,12 +1452,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - [[package]] name = "subtle" version = "2.4.1" @@ -1412,45 +1470,63 @@ dependencies = [ ] [[package]] -name = "target-lexicon" -version = "0.12.5" +name = "syn" +version = "2.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" +checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "tempfile" -version = "3.3.0" +name = "tap" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" -dependencies = [ - "cfg-if", - "fastrand", - "libc", - "redox_syscall", - "remove_dir_all", - "winapi", -] +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9410d0f6853b1d94f0e519fb95df60f29d2c1eff2d921ffdf01a4c8a3b54f12d" [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.39", ] +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tracing" version = "0.1.37" @@ -1458,7 +1534,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1472,7 +1547,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", ] [[package]] @@ -1491,16 +1566,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" [[package]] -name = "uint" -version = "0.9.5" +name = "unicode-bidi" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" @@ -1508,11 +1577,31 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "url" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + [[package]] name = "uuid" -version = "1.2.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" +checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "serde", "sha1_smol", @@ -1551,10 +1640,33 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.105", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-downcast" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dac026d43bcca6e7ce1c0956ba68f59edf6403e8e930a5d891be72c31a44340" +dependencies = [ + "js-sys", + "once_cell", + "wasm-bindgen", + "wasm-bindgen-downcast-macros", +] + +[[package]] +name = "wasm-bindgen-downcast-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5020cfa87c7cecefef118055d44e3c1fc122c7ec25701d528ee458a0b45f38f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.83" @@ -1573,7 +1685,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.105", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1586,73 +1698,65 @@ checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" [[package]] name = "wasmer" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea8d8361c9d006ea3d7797de7bd6b1492ffd0f91a22430cfda6c1658ad57bedf" +checksum = "fc7142dbb91ede83cc0aef2301fa75fcc7e0c9e5a7d5358e3c4f3a7249fe9ce8" dependencies = [ + "bytes", "cfg-if", + "derivative", "indexmap", "js-sys", - "loupe", "more-asserts", + "rustc-demangle", + "serde", + "serde-wasm-bindgen", "target-lexicon", "thiserror", "wasm-bindgen", - "wasmer-artifact", + "wasm-bindgen-downcast", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", "wasmer-derive", - "wasmer-engine", - "wasmer-engine-dylib", - "wasmer-engine-universal", "wasmer-types", "wasmer-vm", "winapi", ] -[[package]] -name = "wasmer-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aaf9428c29c1d8ad2ac0e45889ba8a568a835e33fd058964e5e500f2f7ce325" -dependencies = [ - "enumset", - "loupe", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-compiler" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67a6cd866aed456656db2cfea96c18baabbd33f676578482b85c51e1ee19d2c" +checksum = "e5b99c70711ec7631b602a9fc95577c40df21e8f3916159c9d80c3fb4f77abdc" dependencies = [ + "backtrace", + "cfg-if", + "enum-iterator", "enumset", - "loupe", - "rkyv", - "serde", - "serde_bytes", + "lazy_static", + "leb128", + "memmap2", + "more-asserts", + "region", "smallvec", - "target-lexicon", "thiserror", "wasmer-types", + "wasmer-vm", "wasmparser", + "winapi", ] [[package]] name = "wasmer-compiler-cranelift" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48be2f9f6495f08649e4f8b946a2cbbe119faf5a654aa1457f9504a99d23dae0" +checksum = "52aef2ef35513a04fed54de9a7dc9c469d4742a5c2e378a5f7e2a79b1327e3bd" dependencies = [ "cranelift-codegen", "cranelift-entity", "cranelift-frontend", "gimli 0.26.2", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1664,16 +1768,16 @@ dependencies = [ [[package]] name = "wasmer-compiler-singlepass" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ca2a35204d8befa85062bc7aac259a8db8070b801b8a783770ba58231d729e" +checksum = "ebfd019aa98b19fea0fb1d8db9b539145c9416d183ce4cda4e8e024b2c890aac" dependencies = [ "byteorder", "dynasm", "dynasmrt", + "enumset", "gimli 0.26.2", "lazy_static", - "loupe", "more-asserts", "rayon", "smallvec", @@ -1683,184 +1787,78 @@ dependencies = [ [[package]] name = "wasmer-derive" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e50405cc2a2f74ff574584710a5f2c1d5c93744acce2ca0866084739284b51" +checksum = "25bb1425c9e4dc3e2d3aacd6e82e22e27a3127379e0d09bcbdf25ff376229162" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "wasmer-engine" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f98f010978c244db431b392aeab0661df7ea0822343334f8f2a920763548e45" -dependencies = [ - "backtrace", - "enumset", - "lazy_static", - "loupe", - "memmap2", - "more-asserts", - "rustc-demangle", - "serde", - "serde_bytes", - "target-lexicon", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", - "wasmer-vm", -] - -[[package]] -name = "wasmer-engine-dylib" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0358af9c154724587731175553805648d9acb8f6657880d165e378672b7e53" -dependencies = [ - "cfg-if", - "enum-iterator", - "enumset", - "leb128", - "libloading", - "loupe", - "object 0.28.4", - "rkyv", - "serde", - "tempfile", - "tracing", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-engine", - "wasmer-object", - "wasmer-types", - "wasmer-vm", - "which", -] - -[[package]] -name = "wasmer-engine-universal" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440dc3d93c9ca47865a4f4edd037ea81bf983b5796b59b3d712d844b32dbef15" -dependencies = [ - "cfg-if", - "enumset", - "leb128", - "loupe", - "region", - "rkyv", - "wasmer-compiler", - "wasmer-engine", - "wasmer-engine-universal-artifact", - "wasmer-types", - "wasmer-vm", - "winapi", -] - -[[package]] -name = "wasmer-engine-universal-artifact" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f1db3f54152657eb6e86c44b66525ff7801dad8328fe677da48dd06af9ad41" -dependencies = [ - "enum-iterator", - "enumset", - "loupe", - "rkyv", - "thiserror", - "wasmer-artifact", - "wasmer-compiler", - "wasmer-types", + "syn 1.0.105", ] [[package]] name = "wasmer-middlewares" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7812438ed2f37203a37007cdb5332b8475cb2b16e15d51299b2647894e9ed3a" +checksum = "acfc08fb8e2e1511f1d69302d7406ace6c0ec0c90e103f8c0a5aa81ecb9fe81f" dependencies = [ - "loupe", "wasmer", "wasmer-types", "wasmer-vm", ] -[[package]] -name = "wasmer-object" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d831335ff3a44ecf451303f6f891175c642488036b92ceceb24ac8623a8fa8b" -dependencies = [ - "object 0.28.4", - "thiserror", - "wasmer-compiler", - "wasmer-types", -] - [[package]] name = "wasmer-types" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39df01ea05dc0a9bab67e054c7cb01521e53b35a7bb90bd02eca564ed0b2667f" +checksum = "d7e32ed799fa8c0d96ca9615d9ea8006857a0f0c18e7c2ed8082bd5c63a9ea70" dependencies = [ - "backtrace", + "bytecheck", "enum-iterator", + "enumset", "indexmap", - "loupe", "more-asserts", "rkyv", - "serde", + "target-lexicon", "thiserror", ] [[package]] name = "wasmer-vm" -version = "2.3.0" +version = "4.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d965fa61f4dc4cdb35a54daaf7ecec3563fbb94154a6c35433f879466247dd" +checksum = "0847513cb176b5d62a6f65d6ae474594935e726a10e9e3387177d9cbf8b8cda0" dependencies = [ "backtrace", "cc", "cfg-if", "corosensei", + "dashmap", + "derivative", "enum-iterator", + "fnv", "indexmap", "lazy_static", "libc", - "loupe", "mach", - "memoffset 0.6.5", + "memoffset 0.8.0", "more-asserts", "region", - "rkyv", "scopeguard", - "serde", "thiserror", - "wasmer-artifact", "wasmer-types", "winapi", ] [[package]] name = "wasmparser" -version = "0.83.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718ed7c55c2add6548cca3ddd6383d738cd73b892df400e96b9aa876f0141d7a" - -[[package]] -name = "which" -version = "4.3.0" +version = "0.95.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b" +checksum = "f2ea896273ea99b15132414be1da01ab0d8836415083298ecaffbe308eaac87a" dependencies = [ - "either", - "libc", - "once_cell", + "indexmap", + "url", ] [[package]] @@ -1891,43 +1889,109 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43dbb096663629518eb1dfa72d80243ca5a6aca764cae62a2df70af760a9be75" dependencies = [ - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_msvc", + "windows_aarch64_msvc 0.33.0", + "windows_i686_gnu 0.33.0", + "windows_i686_msvc 0.33.0", + "windows_x86_64_gnu 0.33.0", + "windows_x86_64_msvc 0.33.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd761fd3eb9ab8cc1ed81e56e567f02dd82c4c837e48ac3b2181b9ffc5060807" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cab0cf703a96bab2dc0c02c0fa748491294bf9b7feb27e1f4f96340f208ada0e" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cfdbe89cc9ad7ce618ba34abc34bbb6c36d99e96cae2245b7943cd75ee773d0" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4dd9b0c0e9ece7bb22e84d70d01b71c6d6248b81a3c60d11869451b4cb24784" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff1e4aa646495048ec7f3ffddc411e1d829c026a2ec62b39da15c1055e406eaa" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "zeroize" version = "1.5.7" diff --git a/contracts/voting-with-uuid/src/coin_helpers.rs b/contracts/voting-with-uuid/src/coin_helpers.rs index 97fbeb493..19037e319 100644 --- a/contracts/voting-with-uuid/src/coin_helpers.rs +++ b/contracts/voting-with-uuid/src/coin_helpers.rs @@ -33,30 +33,30 @@ mod test { fn assert_sent_sufficient_coin_works() { match validate_sent_sufficient_coin(&[], Some(coin(0, "token"))) { Ok(()) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), }; match validate_sent_sufficient_coin(&[], Some(coin(5, "token"))) { Ok(()) => panic!("Should have raised insufficient funds error"), Err(ContractError::InsufficientFundsSent {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), }; match validate_sent_sufficient_coin(&coins(10, "smokin"), Some(coin(5, "token"))) { Ok(()) => panic!("Should have raised insufficient funds error"), Err(ContractError::InsufficientFundsSent {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), }; match validate_sent_sufficient_coin(&coins(10, "token"), Some(coin(5, "token"))) { Ok(()) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), }; let sent_coins = vec![coin(2, "smokin"), coin(5, "token"), coin(1, "earth")]; match validate_sent_sufficient_coin(&sent_coins, Some(coin(5, "token"))) { Ok(()) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), }; } } diff --git a/contracts/voting-with-uuid/src/contract.rs b/contracts/voting-with-uuid/src/contract.rs index d5829b467..4a9205097 100644 --- a/contracts/voting-with-uuid/src/contract.rs +++ b/contracts/voting-with-uuid/src/contract.rs @@ -4,7 +4,8 @@ use crate::msg::{ CreatePollResponse, ExecuteMsg, InstantiateMsg, PollResponse, QueryMsg, TokenStakeResponse, }; use crate::state::{ - bank, bank_read, config, config_read, poll, poll_read, Poll, PollStatus, State, Voter, + load_bank, load_config, load_poll, may_load_bank, may_load_poll, save_bank, save_config, + save_poll, Poll, PollStatus, State, TokenManager, Voter, }; use cosmwasm_std::{ attr, coin, entry_point, new_uuid, to_binary, Addr, BankMsg, Binary, Coin, CosmosMsg, Deps, @@ -30,8 +31,7 @@ pub fn instantiate( staked_tokens: Uint128::zero(), }; - config(deps.storage).save(&state)?; - + save_config(deps.storage, &state)?; Ok(Response::default()) } @@ -77,11 +77,12 @@ pub fn stake_voting_tokens( _env: Env, info: MessageInfo, ) -> Result { - let key = info.sender.as_str().as_bytes(); + let sender_key = info.sender; - let mut token_manager = bank_read(deps.storage).may_load(key)?.unwrap_or_default(); + let mut token_manager: TokenManager = + may_load_bank(deps.storage, &sender_key)?.unwrap_or_default(); - let mut state = config(deps.storage).load()?; + let mut state = load_config(deps.storage)?; validate_sent_sufficient_coin(&info.funds, Some(coin(MIN_STAKE_AMOUNT, &state.denom)))?; let funds = info @@ -94,9 +95,9 @@ pub fn stake_voting_tokens( let staked_tokens = state.staked_tokens.u128() + funds.amount.u128(); state.staked_tokens = Uint128::from(staked_tokens); - config(deps.storage).save(&state)?; + save_config(deps.storage, &state)?; - bank(deps.storage).save(key, &token_manager)?; + save_bank(deps.storage, &sender_key, &token_manager)?; Ok(Response::default()) } @@ -108,10 +109,10 @@ pub fn withdraw_voting_tokens( info: MessageInfo, amount: Option, ) -> Result { - let sender_address_raw = info.sender.as_str().as_bytes(); + let sender_key = info.sender; - if let Some(mut token_manager) = bank_read(deps.storage).may_load(sender_address_raw)? { - let largest_staked = locked_amount(sender_address_raw, deps.storage); + if let Some(mut token_manager) = may_load_bank(deps.storage, &sender_key)? { + let largest_staked = locked_amount(&sender_key, deps.storage); let withdraw_amount = amount.unwrap_or(token_manager.token_balance); if largest_staked + withdraw_amount > token_manager.token_balance { let max_amount = token_manager.token_balance.checked_sub(largest_staked)?; @@ -120,15 +121,15 @@ pub fn withdraw_voting_tokens( let balance = token_manager.token_balance.checked_sub(withdraw_amount)?; token_manager.token_balance = balance; - bank(deps.storage).save(sender_address_raw, &token_manager)?; + save_bank(deps.storage, &sender_key, &token_manager)?; - let mut state = config(deps.storage).load()?; + let mut state = load_config(deps.storage)?; let staked_tokens = state.staked_tokens.checked_sub(withdraw_amount)?; state.staked_tokens = staked_tokens; - config(deps.storage).save(&state)?; + save_config(deps.storage, &state)?; Ok(send_tokens( - &info.sender, + &sender_key, vec![coin(withdraw_amount.u128(), &state.denom)], "approve", )) @@ -206,7 +207,7 @@ pub fn create_poll( start_height, description, }; - poll(deps.storage).save(poll_id.as_slice(), &new_poll)?; + save_poll(deps.storage, &poll_id, &new_poll)?; let r = Response::new() .add_attribute("action", "create_poll") @@ -231,7 +232,7 @@ pub fn end_poll( info: MessageInfo, poll_id: Uuid, ) -> Result { - let mut a_poll = poll(deps.storage).load(poll_id.as_slice())?; + let mut a_poll: Poll = load_poll(deps.storage, &poll_id)?; if a_poll.creator != info.sender { return Err(ContractError::PollNotCreator { @@ -272,7 +273,7 @@ pub fn end_poll( let mut passed = false; if tallied_weight > 0 { - let state = config_read(deps.storage).load()?; + let state = load_config(deps.storage)?; let staked_weight = deps .querier @@ -304,7 +305,7 @@ pub fn end_poll( if !passed { a_poll.status = PollStatus::Rejected } - poll(deps.storage).save(poll_id.as_slice(), &a_poll)?; + save_poll(deps.storage, &poll_id, &a_poll)?; for voter in &a_poll.voters { unlock_tokens(deps.storage, voter, poll_id)?; @@ -314,7 +315,7 @@ pub fn end_poll( attr("action", "end_poll"), attr("poll_id", poll_id.to_string()), attr("rejected_reason", rejected_reason), - attr("passed", &passed.to_string()), + attr("passed", passed.to_string()), ]; Ok(Response::new().add_attributes(attributes)) @@ -326,18 +327,17 @@ fn unlock_tokens( voter: &Addr, poll_id: Uuid, ) -> Result { - let voter_key = &voter.as_str().as_bytes(); - let mut token_manager = bank_read(storage).load(voter_key).unwrap(); + let mut token_manager: TokenManager = load_bank(storage, voter)?; // unlock entails removing the mapped poll_id, retaining the rest token_manager.locked_tokens.retain(|(k, _)| k != &poll_id); - bank(storage).save(voter_key, &token_manager)?; + save_bank(storage, voter, &token_manager)?; Ok(Response::default()) } // finds the largest locked amount in participated polls. -fn locked_amount(voter: &[u8], storage: &dyn Storage) -> Uint128 { - let token_manager = bank_read(storage).load(voter).unwrap(); +fn locked_amount(voter: &Addr, storage: &dyn Storage) -> Uint128 { + let token_manager: TokenManager = load_bank(storage, voter).unwrap(); token_manager .locked_tokens .iter() @@ -358,9 +358,7 @@ pub fn cast_vote( vote: String, weight: Uint128, ) -> Result { - let poll_key = poll_id.as_bytes(); - - let mut a_poll = match poll(deps.storage).load(poll_key) { + let mut a_poll: Poll = match load_poll(deps.storage, &poll_id) { Ok(poll) => poll, Err(_) => return Err(ContractError::PollNotExist {}), }; @@ -373,28 +371,29 @@ pub fn cast_vote( return Err(ContractError::PollSenderVoted {}); } - let key = info.sender.as_str().as_bytes(); - let mut token_manager = bank_read(deps.storage).may_load(key)?.unwrap_or_default(); + let sender_key = info.sender; + let mut token_manager: TokenManager = + may_load_bank(deps.storage, &sender_key)?.unwrap_or_default(); if token_manager.token_balance < weight { return Err(ContractError::PollInsufficientStake {}); } token_manager.participated_polls.push(poll_id); token_manager.locked_tokens.push((poll_id, weight)); - bank(deps.storage).save(key, &token_manager)?; + save_bank(deps.storage, &sender_key, &token_manager)?; - a_poll.voters.push(info.sender.clone()); + a_poll.voters.push(sender_key.clone()); let voter_info = Voter { vote, weight }; a_poll.voter_info.push(voter_info); - poll(deps.storage).save(poll_key, &a_poll)?; + save_poll(deps.storage, &poll_id, &a_poll)?; let attributes = vec![ attr("action", "vote_casted"), attr("poll_id", poll_id.to_string()), - attr("weight", &weight.to_string()), - attr("voter", &info.sender), + attr("weight", weight.to_string()), + attr("voter", &sender_key), ]; Ok(Response::new().add_attributes(attributes)) @@ -435,7 +434,7 @@ pub fn make_seq_id( #[entry_point] pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { match msg { - QueryMsg::Config {} => to_binary(&config_read(deps.storage).load()?), + QueryMsg::Config {} => to_binary(&load_config(deps.storage)?), QueryMsg::TokenStake { address } => { token_balance(deps, deps.api.addr_validate(address.as_str())?) } @@ -444,13 +443,10 @@ pub fn query(deps: Deps, _env: Env, msg: QueryMsg) -> StdResult { } fn query_poll(deps: Deps, poll_id: Uuid) -> StdResult { - let key = poll_id.as_bytes(); - - let poll = match poll_read(deps.storage).may_load(key)? { - Some(poll) => Some(poll), + let poll: Poll = match may_load_poll(deps.storage, &poll_id)? { + Some(poll) => poll, None => return Err(StdError::generic_err("Poll does not exist")), - } - .unwrap(); + }; let resp = PollResponse { creator: poll.creator.to_string(), @@ -464,9 +460,7 @@ fn query_poll(deps: Deps, poll_id: Uuid) -> StdResult { } fn token_balance(deps: Deps, address: Addr) -> StdResult { - let token_manager = bank_read(deps.storage) - .may_load(address.as_str().as_bytes())? - .unwrap_or_default(); + let token_manager = may_load_bank(deps.storage, &address)?.unwrap_or_default(); let resp = TokenStakeResponse { token_balance: token_manager.token_balance, diff --git a/contracts/voting-with-uuid/src/state.rs b/contracts/voting-with-uuid/src/state.rs index 5a73a0d7f..2519e3ea5 100644 --- a/contracts/voting-with-uuid/src/state.rs +++ b/contracts/voting-with-uuid/src/state.rs @@ -1,7 +1,6 @@ -use cosmwasm_std::{Addr, Storage, Uint128, Uuid}; -use cosmwasm_storage::{ - bucket, bucket_read, singleton, singleton_read, Bucket, ReadonlyBucket, ReadonlySingleton, - Singleton, +use cosmwasm_std::{ + from_slice, storage_keys::namespace_with_key, to_vec, Addr, StdError, StdResult, Storage, + Uint128, Uuid, }; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -52,26 +51,56 @@ pub struct Poll { pub description: String, } -pub fn config(storage: &mut dyn Storage) -> Singleton { - singleton(storage, CONFIG_KEY) +pub fn save_config(storage: &mut dyn Storage, item: &State) -> StdResult<()> { + storage.set(CONFIG_KEY, &to_vec(item)?); + Ok(()) } -pub fn config_read(storage: &dyn Storage) -> ReadonlySingleton { - singleton_read(storage, CONFIG_KEY) +pub fn load_config(storage: &dyn Storage) -> StdResult { + storage + .get(CONFIG_KEY) + .ok_or_else(|| StdError::not_found("config")) + .and_then(|v| from_slice(&v)) } -pub fn poll(storage: &mut dyn Storage) -> Bucket { - bucket(storage, POLL_KEY) +pub fn save_poll(storage: &mut dyn Storage, key: &Uuid, poll: &Poll) -> StdResult<()> { + storage.set( + &namespace_with_key(&[POLL_KEY], key.as_bytes()), + &to_vec(poll)?, + ); + Ok(()) } -pub fn poll_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, POLL_KEY) +pub fn may_load_poll(storage: &dyn Storage, key: &Uuid) -> StdResult> { + storage + .get(&namespace_with_key(&[POLL_KEY], key.as_bytes())) + .map(|v| from_slice(&v)) + .transpose() } -pub fn bank(storage: &mut dyn Storage) -> Bucket { - bucket(storage, BANK_KEY) +pub fn load_poll(storage: &dyn Storage, key: &Uuid) -> StdResult { + may_load_poll(storage, key)?.ok_or_else(|| StdError::not_found(format!("poll {key:?}"))) } -pub fn bank_read(storage: &dyn Storage) -> ReadonlyBucket { - bucket_read(storage, BANK_KEY) +pub fn save_bank( + storage: &mut dyn Storage, + key: &Addr, + token_manager: &TokenManager, +) -> StdResult<()> { + storage.set( + &namespace_with_key(&[BANK_KEY], key.as_bytes()), + &to_vec(token_manager)?, + ); + Ok(()) +} + +pub fn may_load_bank(storage: &dyn Storage, key: &Addr) -> StdResult> { + storage + .get(&namespace_with_key(&[BANK_KEY], key.as_bytes())) + .map(|v| from_slice(&v)) + .transpose() +} + +pub fn load_bank(storage: &dyn Storage, key: &Addr) -> StdResult { + may_load_bank(storage, key)?.ok_or_else(|| StdError::not_found(format!("bank {key:?}"))) } diff --git a/contracts/voting-with-uuid/src/tests.rs b/contracts/voting-with-uuid/src/tests.rs index 568f4792e..bd768bd27 100644 --- a/contracts/voting-with-uuid/src/tests.rs +++ b/contracts/voting-with-uuid/src/tests.rs @@ -1,7 +1,7 @@ use crate::contract::{execute, instantiate, query, VOTING_TOKEN}; use crate::error::ContractError; use crate::msg::{ExecuteMsg, InstantiateMsg, PollResponse, QueryMsg}; -use crate::state::{config_read, PollStatus, State}; +use crate::state::{load_config, PollStatus, State}; use cosmwasm_std::testing::{ mock_dependencies, mock_dependencies_with_balance, mock_env, mock_info, }; @@ -49,7 +49,7 @@ fn proper_initialization() { let res = instantiate(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_eq!(0, res.messages.len()); - let state = config_read(&deps.storage).load().unwrap(); + let state = load_config(&deps.storage).unwrap(); assert_eq!( state, State { @@ -69,7 +69,7 @@ fn poll_not_found() { match res { Err(StdError::GenericErr { msg, .. }) => assert_eq!(msg, "Poll does not exist"), - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), _ => panic!("Must return error"), } } @@ -89,7 +89,7 @@ fn fails_create_poll_invalid_quorum_percentage() { Err(ContractError::PollQuorumPercentageMismatch { quorum_percentage }) => { assert_eq!(quorum_percentage, qp) } - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -214,7 +214,7 @@ fn fails_end_poll_before_end_height() { Err(ContractError::PollVotingPeriodNotExpired { expire_height }) => { assert_eq!(expire_height, msg_end_height) } - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -532,7 +532,7 @@ fn fails_end_poll_before_start_height() { Err(ContractError::PoolVotingPeriodNotStarted { start_height }) => { assert_eq!(start_height, msg_start_height) } - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -569,7 +569,7 @@ fn fails_cast_vote_not_enough_staked() { match res { Ok(_) => panic!("Must return error"), Err(ContractError::PollInsufficientStake {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -625,7 +625,7 @@ fn happy_days_withdraw_voting_tokens() { let execute_res = execute(deps.as_mut(), mock_env(), info, msg).unwrap(); assert_stake_tokens_result(11, execute_res, deps.as_mut()); - let state = config_read(&deps.storage).load().unwrap(); + let state = load_config(&deps.storage).unwrap(); assert_eq!( state, State { @@ -651,7 +651,7 @@ fn happy_days_withdraw_voting_tokens() { }) ); - let state = config_read(&deps.storage).load().unwrap(); + let state = load_config(&deps.storage).unwrap(); assert_eq!( state, State { @@ -677,7 +677,7 @@ fn fails_withdraw_voting_tokens_no_stake() { match res { Ok(_) => panic!("Must return error"), Err(ContractError::PollNoStake {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -704,7 +704,7 @@ fn fails_withdraw_too_many_tokens() { Err(ContractError::ExcessiveWithdraw { max_amount }) => { assert_eq!(max_amount, Uint128::from(10u32)) } - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -755,7 +755,7 @@ fn fails_cast_vote_twice() { match res { Ok(_) => panic!("Must return error"), Err(ContractError::PollSenderVoted {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -777,7 +777,7 @@ fn fails_cast_vote_without_poll() { match res { Ok(_) => panic!("Must return error"), Err(ContractError::PollNotExist {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -813,7 +813,7 @@ fn fails_insufficient_funds() { match res { Ok(_) => panic!("Must return error"), Err(ContractError::InsufficientFundsSent {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -836,7 +836,7 @@ fn fails_staking_wrong_token() { match res { Ok(_) => panic!("Must return error"), Err(ContractError::InsufficientFundsSent {}) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), } } @@ -863,7 +863,7 @@ fn assert_create_poll_result( ); //confirm poll count - let state = config_read(deps.storage).load().unwrap(); + let state = load_config(deps.storage).unwrap(); assert_eq!( state, State { @@ -877,7 +877,7 @@ fn assert_create_poll_result( fn assert_stake_tokens_result(staked_tokens: u128, execute_res: Response, deps: DepsMut) { assert_eq!(execute_res, Response::default()); - let state = config_read(deps.storage).load().unwrap(); + let state = load_config(deps.storage).unwrap(); assert_eq!( state, State { diff --git a/contracts/voting-with-uuid/tests/integration.rs b/contracts/voting-with-uuid/tests/integration.rs index f481b3495..8f75d9492 100644 --- a/contracts/voting-with-uuid/tests/integration.rs +++ b/contracts/voting-with-uuid/tests/integration.rs @@ -50,5 +50,5 @@ fn compare_gas_spent() { let gas_used_seq_id = before_gas2 - deps.get_gas_left(); assert!(gas_used_seq_id < gas_used_uuid); - println!("gas_seq_id {} gas_uuid {}", gas_used_seq_id, gas_used_uuid); + println!("gas_seq_id {gas_used_seq_id} gas_uuid {gas_used_uuid}"); } diff --git a/devtools/check_workspace.sh b/devtools/check_workspace.sh index 9609054c4..1747d316d 100755 --- a/devtools/check_workspace.sh +++ b/devtools/check_workspace.sh @@ -7,12 +7,13 @@ cargo fmt (cd packages/derive && cargo check && cargo clippy --all-targets -- -D warnings) ( cd packages/std + # default, min, all cargo check - cargo check --features iterator,staking,stargate + cargo check --no-default-features + cargo check --features abort,iterator,staking,stargate,cosmwasm_1_2 cargo wasm-debug cargo wasm-debug --features iterator,staking,stargate cargo clippy --all-targets --features iterator,staking,stargate -- -D warnings - cargo schema --features cosmwasm_1_1 ) (cd packages/storage && cargo build && cargo clippy --all-targets --features iterator -- -D warnings) (cd packages/schema && cargo build && cargo clippy --all-targets -- -D warnings) diff --git a/devtools/test_workspace.sh b/devtools/test_workspace.sh index 0fdcfb201..5ade3f183 100755 --- a/devtools/test_workspace.sh +++ b/devtools/test_workspace.sh @@ -4,7 +4,7 @@ command -v shellcheck >/dev/null && shellcheck "$0" cargo fmt (cd packages/crypto && cargo test) -(cd packages/std && cargo test --features iterator) +(cd packages/std && cargo test --features iterator,cosmwasm_1_2) (cd packages/storage && cargo test --features iterator) (cd packages/schema && cargo test) (cd packages/schema-derive && cargo test) diff --git a/devtools/update_crate.sh b/devtools/update_crate.sh new file mode 100755 index 000000000..500d36f6e --- /dev/null +++ b/devtools/update_crate.sh @@ -0,0 +1,15 @@ +#!/bin/bash +set -o errexit -o nounset -o pipefail +command -v shellcheck >/dev/null && shellcheck "$0" + +CRATE_NAME="$1" + +# Update root Cargo.lock +cargo update -p "$CRATE_NAME" + +for contract_dir in contracts/*/; do + ( + cd "$contract_dir" + cargo update -p "$CRATE_NAME" + ) +done diff --git a/docs/CAPABILITIES-BUILT-IN.md b/docs/CAPABILITIES-BUILT-IN.md new file mode 100644 index 000000000..bf31681e9 --- /dev/null +++ b/docs/CAPABILITIES-BUILT-IN.md @@ -0,0 +1,25 @@ +# Built-in capabilities + +Since capabilities can be created between contract and environment, we don't +know them all in the VM. This is a list of all built-in capabilities, but chains +might define others. + +- `iterator` is for storage backends that allow range queries. Not all types of + databases do that. There are trees that don't allow it and Secret Network does + not support iterators for other technical reasons. +- `stargate` is for messages and queries that came with the Cosmos SDK upgrade + "Stargate". It primarily includes protobuf messages and IBC support. +- `staking` is for chains with the Cosmos SDK staking module. There are Cosmos + chains that don't use this (e.g. Tgrade). +- `cosmwasm_1_1` enables the `BankQuery::Supply` query. Only chains running + CosmWasm `1.1.0` or higher support this. +- `cosmwasm_1_2` enables the `GovMsg::VoteWeighted` and `WasmMsg::Instantiate2` + messages. Only chains running CosmWasm `1.2.0` or higher support this. +- `cosmwasm_1_3` enables the `BankQuery::AllDenomMetadata`, + `BankQuery::DenomMetadata` and `DistributionQuery::DelegatorWithdrawAddress` + queries, as well as `DistributionMsg::FundCommunityPool`. Only chains running + CosmWasm `1.3.0` or higher support this. +- `cosmwasm_1_4` enables the `DistributionQuery::DelegationRewards`, + `DistributionQuery::DelegationTotalRewards` and + `DistributionQuery::DelegatorValidators` queries. Only chains running CosmWasm + `1.4.0` or higher support this. diff --git a/docs/CAPABILITIES.md b/docs/CAPABILITIES.md index 2679f5dd7..e647274c8 100644 --- a/docs/CAPABILITIES.md +++ b/docs/CAPABILITIES.md @@ -81,18 +81,9 @@ function name in Rust and other CosmWasm smart contract languages such as Go. By convention, the name should be short and all lower ASCII alphanumerical plus underscores. -## Common capabilities - -Here is a list of capabilities created in the past. Since capabilities can be -created between contract and environment, we don't know them all in the VM. - -- `iterator` is for storage backends that allow range queries. Not all types of - databases do that. There are trees that don't allow it and Secret Network does - not support iterators for other technical reasons. -- `stargate` is for messages and queries that came with the Cosmos SDK upgrade - "Stargate". It primarily includes protobuf messages and IBC support. -- `staking` is for chains with the Cosmos SDK staking module. There are Cosmos - chains that don't use this (e.g. Tgrade). +## Built-in capabilities + +Here is a list of all [built-in capabilities](CAPABILITIES-BUILT-IN.md). ## What's a good capability? diff --git a/docs/MESSAGE_TYPES.md b/docs/MESSAGE_TYPES.md index faaf1e65d..8c3424370 100644 --- a/docs/MESSAGE_TYPES.md +++ b/docs/MESSAGE_TYPES.md @@ -9,37 +9,46 @@ this reason, the CosmWasm standard library `cosmwasm-std` ships types that ensure good user experience in JSON. The following table shows both standard Rust types as well as `cosmwasm_std` types and how they are encoded in JSON. -| Rust type | JSON type[^1] | Example | Note | -| ------------------- | -------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| bool | `true` or `false` | `true` | | -| u32/i32 | number | `123` | | -| u64/i64 | number | `123456` | Supported in Rust and Go. Other implementations (`jq`, `JavaScript`) do not support the full uint64/int64 range. | -| u128/i128 | string | `"340282366920938463463374607431768211455", "-2766523308300312711084346401884294402"` | | -| usize/isize | number | `123456` | 🚫 Don't use this type because it has a different size in unit tests (64 bit) and Wasm (32 bit). Also it tends to issue float instructions such that the contracts cannot be uploaded. | -| String | string | `"foo"` | -| &str | string | `"foo"` | 🚫 Unsuppored since message types must be owned (DeserializeOwned) | -| Option\ | `null` or JSON type of `T` | `null`, `{"foo":12}` | | -| Vec\ | array of JSON type of `T` | `["one", "two", "three"]` (Vec\), `[true, false]` (Vec\) | -| Vec\ | array of numbers from 0 to 255 | `[187, 61, 11, 250]` | ⚠️ Discouraged as this encoding is not as compact as it can be. See `Binary`. | -| struct MyType { … } | object | `{"foo":12}` | | -| [Uint64] | string containing number | `"1234321"` | Used to support full uint64 range in all implementations | -| [Uint128] | string containing number | `"1234321"` | | -| [Uint256] | string containing number | `"1234321"` | | -| [Uint512] | string containing number | `"1234321"` | | -| [Decimal] | string containing decimal number | `"55.6584"` | | -| [Decimal256] | string containing decimal number | `"55.6584"` | | -| [Binary] | string containing base64 data | `"MTIzCg=="` | | -| [HexBinary] | string containing hex data | `"b5d7d24e428c"` | | +| Rust type | JSON type[^1] | Example | Note | +| ------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| bool | `true` or `false` | `true` | | +| u32/i32 | number | `123` | | +| u64/i64 | number | `123456` | Supported in Rust and Go. Other implementations (`jq`, `JavaScript`) do not support the full uint64/int64 range. | +| u128/i128 | string | `"340282366920938463463374607431768211455", "-2766523308300312711084346401884294402"` | 🚫 Strongly discouraged because the JSON type in serde-json-wasm is wrong and will change. See [Dev Note #4: u128/i128 serialization][dev-note-4]. | +| usize/isize | number | `123456` | 🚫 Don't use this type because it has a different size in unit tests (64 bit) and Wasm (32 bit). Also it tends to issue float instructions such that the contracts cannot be uploaded. | +| String | string | `"foo"` | +| &str | string | `"foo"` | 🚫 Unsuppored since message types must be owned (DeserializeOwned) | +| Option\ | `null` or JSON type of `T` | `null`, `{"foo":12}` | | +| Vec\ | array of JSON type of `T` | `["one", "two", "three"]` (Vec\), `[true, false]` (Vec\) | +| Vec\ | array of numbers from 0 to 255 | `[187, 61, 11, 250]` | ⚠️ Discouraged as this encoding is not as compact as it can be. See `Binary`. | +| struct MyType { … } | object | `{"foo":12}` | | +| [Uint64]/[Int64] | string containing number | `"1234321"`, `"-1234321"` | Used to support full uint64/int64 range in all implementations | +| [Uint128]/[Int128] | string containing number | `"1234321"`, `"-1234321"` | | +| [Uint256]/[Int256] | string containing number | `"1234321"`, `"-1234321"` | | +| [Uint512]/[Int512] | string containing number | `"1234321"`, `"-1234321"` | | +| [Decimal] | string containing decimal number | `"55.6584"` | | +| [Decimal256] | string containing decimal number | `"55.6584"` | | +| [Binary] | string containing base64 data | `"MTIzCg=="` | | +| [HexBinary] | string containing hex data | `"b5d7d24e428c"` | | +| [Timestamp] | string containing nanoseconds since epoch | `"1677687687000000000"` | | -[uint64]: https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Uint64.html -[uint128]: https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Uint128.html -[uint256]: https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Uint256.html -[uint512]: https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Uint512.html -[decimal]: https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Decimal.html +[uint64]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Uint64.html +[uint128]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Uint128.html +[uint256]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Uint256.html +[uint512]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Uint512.html +[int64]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Int64.html +[int128]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Int128.html +[int256]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Int256.html +[int512]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Int512.html +[decimal]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Decimal.html [decimal256]: - https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Decimal256.html -[binary]: https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.Binary.html + https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Decimal256.html +[binary]: https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Binary.html [hexbinary]: - https://docs.rs/cosmwasm-std/1.1.1/cosmwasm_std/struct.HexBinary.html + https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.HexBinary.html +[timestamp]: + https://docs.rs/cosmwasm-std/1.3.3/cosmwasm_std/struct.Timestamp.html +[dev-note-4]: + https://medium.com/cosmwasm/dev-note-4-u128-i128-serialization-in-cosmwasm-90cb76784d44 [^1]: https://www.json.org/ diff --git a/docs/STORAGE_KEYS.md b/docs/STORAGE_KEYS.md new file mode 100644 index 000000000..52f7b5f44 --- /dev/null +++ b/docs/STORAGE_KEYS.md @@ -0,0 +1,83 @@ +# Storage keys + +CosmWasm provides a generic key value store to contract developers via the +`Storage` trait. This is powerful but the nature of low level byte operations +makes it hard to use for high level storage types. In this document we discuss +the foundations of storage key composition all the way up to cw-storage-plus. + +In a simple world, all you need is a `&[u8]` key which you can get e.g. using +`&17u64.to_be_bytes()`. This is an 8 bytes key with an encoded integer. But if +you have multiple data types in your contract, you want to prefix those keys in +order to avoid collisions. A simple concatenation is not sufficient because you +want to avoid collisions when part of the prefixes and part of the key overlap. +E.g. `b"keya" | b"x"` and `b"key" | b"ax"` (`|` denotes concatenation) must not +have the same binary representation. + +In the early days, multiple approaches of key namespacing were discussed and +were documented here: https://github.com/webmaster128/key-namespacing. The "0x00 +separated ASCIIHEX" approach was never used but "Length-prefixed keys" is used. + +To recap, Length-prefixed keys have the following layout: + +``` +len(namespace_1) | namespace_1 + | len(namespace_2) | namespace_2 + | len(namespace_3) | namespace_3 + | ... + | len(namespace_m) | namespace_m + | key +``` + +In this repo (package `cosmwasm-storage`), the following functions were +implemented: + +```rust +pub fn to_length_prefixed(namespace: &[u8]) -> Vec + +pub fn to_length_prefixed_nested(namespaces: &[&[u8]]) -> Vec + +fn concat(namespace: &[u8], key: &[u8]) -> Vec +``` + +With the emerging cw-storage-plus we see two additions to that approach: + +1. Manually creating the namespace and concatenating it with `concat` makes no + sense anymore. Instead `namespace` and `key` are always provided and a + composed database key is created. +2. Using a multi component namespace becomes the norm. + +This led to the following addition in cw-storage-plus: + +```rust +/// This is equivalent concat(to_length_prefixed_nested(namespaces), key) +/// But more efficient when the intermediate namespaces often must be recalculated +pub(crate) fn namespaces_with_key(namespaces: &[&[u8]], key: &[u8]) -> Vec { +``` + +In contrast to `concat(to_length_prefixed_nested(namespaces), key)` this direct +implementation saves once vector allocation since the final length can be +pre-computed and reserved. Also it's shorter to use. + +Also since `to_length_prefixed` returns the same result as +`to_length_prefixed_nested` when called with one namespace element, there is no +good reason to preserve the single component version. + +## 2023 updates + +With the deprecation if cosmwasm-storage and the adoption of the system in +cw-storage-plus, it is time to do a few changes to the Length-prefixed keys +standard, without breaking existing users. + +1. Remove the single component `to_length_prefixed` implementation and fully + commit to the multi-component version. This shifts focus from the recursive + implementation to the compatible iterative implementation. +2. Rename "namespaces" to just "namespace" and let one namespace have multiple + components. +3. Adopt the combined namespace + key encoder `namespaces_with_key` from + cw-storage-plus. +4. Add a decomposition implementation + +Given the importance of Length-prefixed keys for the entire CosmWasm ecosystem, +those implementations should be maintained in cosmwasm-std. The generic approach +allows building all sorts of storage solutions on top of it and it allows +indexers to parse storage keys for all of them. diff --git a/docs/USING_COSMWASM_STD.md b/docs/USING_COSMWASM_STD.md new file mode 100644 index 000000000..19a04bdb6 --- /dev/null +++ b/docs/USING_COSMWASM_STD.md @@ -0,0 +1,91 @@ +# Using cosmwasm-std + +cosmwasm-std is the standard library for building contracts in CosmWasm. It is +compiled as part of the contract to Wasm. When creating a dependency to +cosmwasm-std, the required Wasm imports and exports are created implicitly via C +interfaces, e.g.: + +```rust +// Exports +#[no_mangle] +extern "C" fn interface_version_8() -> () { /* ... */ } +#[no_mangle] +extern "C" fn allocate(size: usize) -> u32 { /* ... */ } +#[no_mangle] +extern "C" fn deallocate(pointer: u32) { /* ... */ } + +// Imports +extern "C" { + #[cfg(feature = "abort")] + fn abort(source_ptr: u32); + + fn db_read(key: u32) -> u32; + fn db_write(key: u32, value: u32); + fn db_remove(key: u32); + + /* ... */ +} +``` + +As those exports are not namespaced, only one version of cosmwasm-std must exist +in the dependency tree. Otherwise conflicting C exports are created. + +## cosmwasm-std features + +The libarary comes with the following features: + +| Feature | Enabled by default | Description | +| ------------ | ------------------ | ------------------------------------------------------------------------- | +| iterator | x | Storage iterators | +| abort | x | A panic handler that aborts the contract execution with a helpful message | +| stargate | | Cosmos SDK 0.40+ features and IBC | +| ibc3 | | New fields added in IBC v3 | +| staking | | Access to the staking module | +| backtraces | | Add backtraces to errors (for unit testing) | +| cosmwasm_1_1 | | Features that require CosmWasm 1.1+ on the chain | +| cosmwasm_1_2 | | Features that require CosmWasm 1.2+ on the chain | +| cosmwasm_1_3 | | Features that require CosmWasm 1.3+ on the chain | +| cosmwasm_1_4 | | Features that require CosmWasm 1.4+ on the chain | + +## The cosmwasm-std dependency for contract developers + +As a contract developer you can simply specify the dependency as follows in +`Cargo.toml`: + +```toml +cosmwasm-std = { version = "1.2.0" } +``` + +Please note that it is recommended to set all 3 version components and use the +minimum version you are willing to accept in the contract. For contracts this +would usually be the latest stable version. + +Most likely you also want to enable the `stargate`, which is pretty basic these +days and maybe you know your chain supports CosmWasm 1.2 or higher. Then you add +those features: + +```toml +cosmwasm-std = { version = "1.2.0", features = ["stargate", "cosmwasm_1_2"] } +``` + +## The cosmwasm-std dependency for library developers + +When you are creating a library that uses cosmwasm-std, you should be incredibly +careful with which features you require. The moment you add e.g. `cosmwasm_1_2` +there it becomes impossible to use the contract in chains with lower CosmWasm +versions. If you add `abort`, it becomes impossible for the contract developer +to opt out of the abort feature due to your library. Since this affects the +default features `abort` and `iterator`, you should always disable default +features. + +Also libraries should define a loose version range that allows the contract +developer to control which cosmwasm-std version they want to use in the final +project. E.g. if your library does not work with 1.0.0 due to a bug fixed in +1.0.1, your min version is 1.0.1 and not the latest stable. + +A typical dependency then looks like this: + +```toml +# We really need `stargate` here as this is an IBC related library. `abort` and `iterator` are not needed. +cosmwasm-std = { version = "1.0.1", default-features = false, features = ["stargate"] } +``` diff --git a/packages/check/Cargo.toml b/packages/check/Cargo.toml index 8d350c516..6c4ad1608 100644 --- a/packages/check/Cargo.toml +++ b/packages/check/Cargo.toml @@ -9,7 +9,11 @@ license = "Apache-2.0" [dependencies] anyhow = "1.0.57" -clap = "2" +clap = "4" colored = "2" cosmwasm-vm = { path = "../vm", version = "1.1.9+0.8.1" } cosmwasm-std = { path = "../std", version = "1.1.9+0.8.1" } + +[dev-dependencies] +assert_cmd = "=2.0.10" # 2.0.11+ requires Rust 1.65.0 which we currently don't want to make the minimum if possible +predicates = "3" diff --git a/packages/check/src/main.rs b/packages/check/src/main.rs index 1d4e6eb67..48998f889 100644 --- a/packages/check/src/main.rs +++ b/packages/check/src/main.rs @@ -4,47 +4,53 @@ use std::io::Read; use std::path::Path; use std::process::exit; -use clap::{App, Arg}; +use clap::{Arg, ArgAction, Command}; use colored::Colorize; use cosmwasm_vm::capabilities_from_csv; -use cosmwasm_vm::internals::{check_wasm, compile}; +use cosmwasm_vm::internals::{check_wasm, compile, make_compiling_engine}; -const DEFAULT_AVAILABLE_CAPABILITIES: &str = "iterator,staking,stargate,cosmwasm_1_1"; +const DEFAULT_AVAILABLE_CAPABILITIES: &str = + "iterator,staking,stargate,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_3,cosmwasm_1_4"; pub fn main() { - let matches = App::new("Contract checking") + let matches = Command::new("Contract checking") .version(env!("CARGO_PKG_VERSION")) .long_about("Checks the given wasm file (memories, exports, imports, available capabilities, and non-determinism).") .author("Mauro Lacy ") .arg( - Arg::with_name("CAPABILITIES") + Arg::new("CAPABILITIES") // `long` setting required to turn the position argument into an option 🤷 .long("available-capabilities") - .aliases(&["FEATURES", "supported-features"]) // Old names + .aliases(["FEATURES", "supported-features"]) // Old names .value_name("CAPABILITIES") .help("Sets the available capabilities that the desired target chain has") - .takes_value(true) + .num_args(1) + .action(ArgAction::Set), ) .arg( - Arg::with_name("WASM") + Arg::new("WASM") .help("Wasm file to read and compile") .required(true) .index(1) - .multiple(true), + .num_args(0..) + .action(ArgAction::Append), ) .get_matches(); // Available capabilities let available_capabilities_csv = matches - .value_of("CAPABILITIES") + .get_one::("CAPABILITIES") + .map(|s| s.as_str()) .unwrap_or(DEFAULT_AVAILABLE_CAPABILITIES); let available_capabilities = capabilities_from_csv(available_capabilities_csv); - println!("Available capabilities: {:?}", available_capabilities); + println!("Available capabilities: {available_capabilities:?}"); println!(); // File - let paths = matches.values_of("WASM").expect("Error parsing file names"); + let paths = matches + .get_many::("WASM") + .expect("Error parsing file names"); let (passes, failures): (Vec<_>, _) = paths .map(|p| { @@ -53,7 +59,7 @@ pub fn main() { Ok(_) => println!("{}: {}", p, "pass".green()), Err(e) => { println!("{}: {}", p, "failure".red()); - println!("{}", e); + println!("{e}"); } }; result @@ -93,7 +99,8 @@ fn check_contract( check_wasm(&wasm, available_capabilities)?; // Compile module - compile(&wasm, None, &[])?; + let engine = make_compiling_engine(None); + let _module = compile(&engine, &wasm)?; Ok(()) } diff --git a/packages/check/tests/cosmwasm_check_tests.rs b/packages/check/tests/cosmwasm_check_tests.rs new file mode 100644 index 000000000..0c4301d68 --- /dev/null +++ b/packages/check/tests/cosmwasm_check_tests.rs @@ -0,0 +1,74 @@ +use assert_cmd::prelude::*; +use predicates::prelude::*; +use std::process::Command; + +#[test] +fn valid_contract_check() -> Result<(), Box> { + let mut cmd = Command::cargo_bin("cosmwasm-check")?; + + cmd.arg("../vm/testdata/hackatom.wasm"); + cmd.assert() + .success() + .stdout(predicate::str::contains("pass")); + + Ok(()) +} + +#[test] +fn invalid_contract_check() -> Result<(), Box> { + let mut cmd = Command::cargo_bin("cosmwasm-check")?; + + cmd.arg("../vm/testdata/corrupted.wasm"); + cmd.assert() + .failure() + .stdout(predicate::str::contains("Deserialization error")); + + Ok(()) +} + +#[test] +fn invalid_contract_check_float_operator() -> Result<(), Box> { + let mut cmd = Command::cargo_bin("cosmwasm-check")?; + + cmd.arg("../vm/testdata/floaty.wasm"); + cmd.assert() + .failure() + .stdout(predicate::str::contains("Float operator detected")) + .stdout(predicate::str::contains( + "The use of floats is not supported", + )); + + Ok(()) +} + +#[test] +fn several_contracts_check() -> Result<(), Box> { + let mut cmd = Command::cargo_bin("cosmwasm-check")?; + + cmd.arg("../vm/testdata/hackatom.wasm") + .arg("../vm/testdata/corrupted.wasm"); + cmd.assert() + .failure() + .stdout(predicate::str::contains("failure")) + .stdout(predicate::str::contains("Deserialization error")) + .stdout(predicate::str::contains("Passes: 1, failures: 1")); + + Ok(()) +} + +#[test] +fn custom_capabilities_check() -> Result<(), Box> { + let mut cmd = Command::cargo_bin("cosmwasm-check")?; + + cmd.arg("--available-capabilities") + .arg("iterator,osmosis,friendship") + .arg("../vm/testdata/hackatom.wasm"); + cmd.assert() + .success() + .stdout(predicate::str::contains("Available capabilities:")) + .stdout(predicate::str::contains("iterator")) + .stdout(predicate::str::contains("osmosis")) + .stdout(predicate::str::contains("friendship")); + + Ok(()) +} diff --git a/packages/crypto/Cargo.toml b/packages/crypto/Cargo.toml index 275f03e36..270ea96c2 100644 --- a/packages/crypto/Cargo.toml +++ b/packages/crypto/Cargo.toml @@ -19,19 +19,18 @@ backtraces = [] bench = false [dependencies] -k256 = { version = "0.11.1", features = ["ecdsa"] } +k256 = { version = "0.13.1", features = ["ecdsa"] } ed25519-zebra = "3" digest = "0.10" rand_core = { version = "0.6", features = ["getrandom"] } -thiserror = "1.0.13" +thiserror = "1.0.38" sha-1 = "0.9.8" [dev-dependencies] -criterion = "0.3" +criterion = "0.4" serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"] } serde_json = "1.0.40" sha2 = "0.10" -base64 = "0.13.0" hex = "0.4" hex-literal = "0.3.1" english-numbers = "0.3" diff --git a/packages/crypto/README.md b/packages/crypto/README.md index a60ffe6e0..e9e16fd5d 100644 --- a/packages/crypto/README.md +++ b/packages/crypto/README.md @@ -11,9 +11,9 @@ and [cosmwasm-std](`https://github.com/Finschia/cosmwasm/tree/main/packages/std` - `secp256k1_verify()`: Digital signature verification using the ECDSA sepc256k1 scheme, for Cosmos signature / public key formats. - `ed25519_verify()`: Digital signature verification using the EdDSA ed25519 - scheme, for Tendemint signature / public key formats. + scheme, for Tendermint signature / public key formats. - `ed25519_batch_verify()`: Batch digital signature verification using the EdDSA - ed25519 scheme, for Tendemint signature / public key formats. + ed25519 scheme, for Tendermint signature / public key formats. ## Benchmarking diff --git a/packages/crypto/benches/main.rs b/packages/crypto/benches/main.rs index b395724b6..81b63b306 100644 --- a/packages/crypto/benches/main.rs +++ b/packages/crypto/benches/main.rs @@ -8,7 +8,6 @@ use serde::Deserialize; // Crypto stuff use digest::Digest; use k256::ecdsa::SigningKey; // type alias -use k256::elliptic_curve::sec1::ToEncodedPoint; use sha2::Sha256; use cosmwasm_crypto::{ @@ -19,7 +18,8 @@ use std::cmp::min; const COSMOS_SECP256K1_MSG_HEX: &str = "0a93010a90010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412700a2d636f736d6f7331706b707472653766646b6c366766727a6c65736a6a766878686c63337234676d6d6b38727336122d636f736d6f7331717970717870713971637273737a673270767871367273307a716733797963356c7a763778751a100a0575636f736d12073132333435363712650a4e0a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029012040a02080112130a0d0a0575636f736d12043230303010c09a0c1a0c73696d642d74657374696e672001"; const COSMOS_SECP256K1_SIGNATURE_HEX: &str = "c9dd20e07464d3a688ff4b710b1fbc027e495e797cfa0b4804da2ed117959227772de059808f765aa29b8f92edf30f4c2c5a438e30d3fe6897daa7141e3ce6f9"; -const COSMOS_SECP256K1_PUBKEY_BASE64: &str = "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"; +const COSMOS_SECP256K1_PUBKEY_HEX: &str = + "034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c70290"; // TEST 3 test vector from https://tools.ietf.org/html/rfc8032#section-7.1 const COSMOS_ED25519_MSG_HEX: &str = "af82"; @@ -81,9 +81,9 @@ fn bench_crypto(c: &mut Criterion) { group.bench_function("secp256k1_verify", |b| { let message = hex::decode(COSMOS_SECP256K1_MSG_HEX).unwrap(); - let message_hash = Sha256::digest(&message); + let message_hash = Sha256::digest(message); let signature = hex::decode(COSMOS_SECP256K1_SIGNATURE_HEX).unwrap(); - let public_key = base64::decode(COSMOS_SECP256K1_PUBKEY_BASE64).unwrap(); + let public_key = hex::decode(COSMOS_SECP256K1_PUBKEY_HEX).unwrap(); b.iter(|| { assert!(secp256k1_verify(&message_hash, &signature, &public_key).unwrap()); }); @@ -97,7 +97,7 @@ fn bench_crypto(c: &mut Criterion) { let r_s = hex!("99e71a99cb2270b8cac5254f9e99b6210c6c10224a1579cf389ef88b20a1abe9129ff05af364204442bdb53ab6f18a99ab48acc9326fa689f228040429e3ca66"); let recovery_param: u8 = 0; - let expected = SigningKey::from_bytes(&private_key) + let expected = SigningKey::from_bytes(&private_key.into()) .unwrap() .verifying_key() .to_encoded_point(false) diff --git a/packages/crypto/src/ed25519.rs b/packages/crypto/src/ed25519.rs index c53449cd8..7b87affcd 100644 --- a/packages/crypto/src/ed25519.rs +++ b/packages/crypto/src/ed25519.rs @@ -253,8 +253,7 @@ mod tests { // ed25519_verify() works assert!( ed25519_verify(&message, &signature, &public_key).unwrap(), - "verify() failed (test case {})", - i + "verify() failed (test case {i})" ); } } diff --git a/packages/crypto/src/lib.rs b/packages/crypto/src/lib.rs index 2bf21cbfa..f452545ed 100644 --- a/packages/crypto/src/lib.rs +++ b/packages/crypto/src/lib.rs @@ -2,7 +2,8 @@ //! Please don't use any of these types directly, as //! they might change frequently, or be removed in the future. //! This crate does not adhere to semantic versioning. -#![cfg_attr(feature = "backtraces", feature(backtrace))] +#![cfg_attr(feature = "backtraces", feature(error_generic_member_access))] +#![cfg_attr(feature = "backtraces", feature(provide_any))] mod ed25519; mod errors; diff --git a/packages/crypto/src/secp256k1.rs b/packages/crypto/src/secp256k1.rs index dda5ce257..d77f71181 100644 --- a/packages/crypto/src/secp256k1.rs +++ b/packages/crypto/src/secp256k1.rs @@ -1,9 +1,7 @@ use digest::{Digest, Update}; // trait use k256::{ - ecdsa::recoverable, - ecdsa::signature::{DigestVerifier, Signature as _}, // traits - ecdsa::{Signature, VerifyingKey}, // type aliases - elliptic_curve::sec1::ToEncodedPoint, + ecdsa::signature::DigestVerifier, // traits + ecdsa::{RecoveryId, Signature, VerifyingKey}, // type aliases }; use crate::errors::{CryptoError, CryptoResult}; @@ -35,6 +33,11 @@ pub const ECDSA_PUBKEY_MAX_LEN: usize = ECDSA_UNCOMPRESSED_PUBKEY_LEN; /// - signature: Serialized "compact" signature (64 bytes). /// - public key: [Serialized according to SEC 2](https://www.oreilly.com/library/view/programming-bitcoin/9781492031482/ch04.html) /// (33 or 65 bytes). +/// +/// This implementation accepts both high-S and low-S signatures. Some applications +/// including Ethereum transactions consider high-S signatures invalid in order to +/// avoid malleability. If that's the case for your protocol, the signature needs +/// to be tested for low-S in addition to this verification. pub fn secp256k1_verify( message_hash: &[u8], signature: &[u8], @@ -47,9 +50,12 @@ pub fn secp256k1_verify( // Already hashed, just build Digest container let message_digest = Identity256::new().chain(message_hash); - let mut signature = - Signature::from_bytes(&signature).map_err(|e| CryptoError::generic_err(e.to_string()))?; - // Non low-S signatures require normalization + let mut signature = Signature::from_bytes(&signature.into()) + .map_err(|e| CryptoError::generic_err(e.to_string()))?; + + // High-S signatures require normalization since our verification implementation + // rejects them by default. If we had a verifier that does not restrict to + // low-S only, this step was not needed. if let Some(normalized) = signature.normalize_s() { signature = normalized; } @@ -74,6 +80,22 @@ pub fn secp256k1_verify( /// /// Returns the recovered pubkey in compressed form, which can be used /// in secp256k1_verify directly. +/// +/// This implementation accepts both high-S and low-S signatures. This is the +/// same behavior as Ethereum's `ecrecover`. The reason is that high-S signatures +/// may be perfectly valid if the application protocol does not disallow them. +/// Or as [EIP-2] put it "The ECDSA recover precompiled contract remains unchanged +/// and will keep accepting high s-values; this is useful e.g. if a contract +/// recovers old Bitcoin signatures.". +/// +/// See also OpenZeppelin's [ECDSA.recover implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.8.1/contracts/utils/cryptography/ECDSA.sol#L138-L149) +/// which adds further restrictions to avoid potential signature malleability. +/// Please note that restricting signatures to low-S does not make signatures unique +/// in the sense that for each (pubkey, message) there is only one signature. The +/// signer can generate an arbitrary amount of valid signatures. +/// +/// +/// [EIP-2]: https://eips.ethereum.org/EIPS/eip-2 pub fn secp256k1_recover_pubkey( message_hash: &[u8], signature: &[u8], @@ -82,19 +104,20 @@ pub fn secp256k1_recover_pubkey( let message_hash = read_hash(message_hash)?; let signature = read_signature(signature)?; - let id = - recoverable::Id::new(recovery_param).map_err(|_| CryptoError::invalid_recovery_param())?; + // params other than 0 and 1 are explicitly not supported + let id = match recovery_param { + 0 => RecoveryId::new(false, false), + 1 => RecoveryId::new(true, false), + _ => return Err(CryptoError::invalid_recovery_param()), + }; // Compose extended signature - let signature = - Signature::from_bytes(&signature).map_err(|e| CryptoError::generic_err(e.to_string()))?; - let extended_signature = recoverable::Signature::new(&signature, id) + let signature = Signature::from_bytes(&signature.into()) .map_err(|e| CryptoError::generic_err(e.to_string()))?; // Recover let message_digest = Identity256::new().chain(message_hash); - let pubkey = extended_signature - .recover_verifying_key_from_digest(message_digest) + let pubkey = VerifyingKey::recover_from_digest(message_digest, &signature, id) .map_err(|e| CryptoError::generic_err(e.to_string()))?; let encoded: Vec = pubkey.to_encoded_point(false).as_bytes().into(); Ok(encoded) @@ -159,16 +182,19 @@ mod tests { ecdsa::signature::DigestSigner, // trait ecdsa::SigningKey, // type alias elliptic_curve::rand_core::OsRng, - elliptic_curve::sec1::ToEncodedPoint, }; + use serde::Deserialize; use sha2::Sha256; + use std::fs::File; + use std::io::BufReader; // For generic signature verification const MSG: &str = "Hello World!"; // Cosmos secp256k1 signature verification // tendermint/PubKeySecp256k1 pubkey - const COSMOS_SECP256K1_PUBKEY_BASE64: &str = "A08EGB7ro1ORuFhjOnZcSgwYlpe0DSFjVNUIkNNQxwKQ"; + const COSMOS_SECP256K1_PUBKEY_HEX: &str = + "034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c70290"; const COSMOS_SECP256K1_MSG_HEX1: &str = "0a93010a90010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412700a2d636f736d6f7331706b707472653766646b6c366766727a6c65736a6a766878686c63337234676d6d6b38727336122d636f736d6f7331717970717870713971637273737a673270767871367273307a716733797963356c7a763778751a100a0575636f736d12073132333435363712650a4e0a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029012040a02080112130a0d0a0575636f736d12043230303010c09a0c1a0c73696d642d74657374696e672001"; const COSMOS_SECP256K1_MSG_HEX2: &str = "0a93010a90010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e6412700a2d636f736d6f7331706b707472653766646b6c366766727a6c65736a6a766878686c63337234676d6d6b38727336122d636f736d6f7331717970717870713971637273737a673270767871367273307a716733797963356c7a763778751a100a0575636f736d12073132333435363712670a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21034f04181eeba35391b858633a765c4a0c189697b40d216354d50890d350c7029012040a020801180112130a0d0a0575636f736d12043230303010c09a0c1a0c73696d642d74657374696e672001"; @@ -181,6 +207,15 @@ mod tests { // Test data originally from https://github.com/cosmos/cosmjs/blob/v0.24.0-alpha.22/packages/crypto/src/secp256k1.spec.ts#L195-L394 const COSMOS_SECP256K1_TESTS_JSON: &str = "./testdata/secp256k1_tests.json"; + #[derive(Deserialize, Debug)] + struct Encoded { + message: String, + message_hash: String, + signature: String, + #[serde(rename = "pubkey")] + public_key: String, + } + #[test] fn test_secp256k1_verify() { // Explicit / external hashing @@ -200,7 +235,7 @@ mod tests { // Verification (uncompressed public key) assert!(secp256k1_verify( &message_hash, - signature.as_bytes(), + signature.to_bytes().as_slice(), public_key.to_encoded_point(false).as_bytes() ) .unwrap()); @@ -208,7 +243,7 @@ mod tests { // Verification (compressed public key) assert!(secp256k1_verify( &message_hash, - signature.as_bytes(), + signature.to_bytes().as_slice(), public_key.to_encoded_point(true).as_bytes() ) .unwrap()); @@ -217,7 +252,7 @@ mod tests { let bad_message_hash = Sha256::new().chain(MSG).chain("\0").finalize(); assert!(!secp256k1_verify( &bad_message_hash, - signature.as_bytes(), + signature.to_bytes().as_slice(), public_key.to_encoded_point(false).as_bytes() ) .unwrap()); @@ -227,7 +262,7 @@ mod tests { let other_public_key = VerifyingKey::from(&other_secret_key); assert!(!secp256k1_verify( &message_hash, - signature.as_bytes(), + signature.to_bytes().as_slice(), other_public_key.to_encoded_point(false).as_bytes() ) .unwrap()); @@ -235,7 +270,7 @@ mod tests { #[test] fn test_cosmos_secp256k1_verify() { - let public_key = base64::decode(COSMOS_SECP256K1_PUBKEY_BASE64).unwrap(); + let public_key = hex::decode(COSMOS_SECP256K1_PUBKEY_HEX).unwrap(); for ((i, msg), sig) in (1..) .zip(&[ @@ -253,33 +288,16 @@ mod tests { let signature = hex::decode(sig).unwrap(); // Explicit hash - let message_hash = Sha256::digest(&message); + let message_hash = Sha256::digest(message); // secp256k1_verify works - assert!( - secp256k1_verify(&message_hash, &signature, &public_key).unwrap(), - "secp256k1_verify() failed (test case {})", - i - ); + let valid = secp256k1_verify(&message_hash, &signature, &public_key).unwrap(); + assert!(valid, "secp256k1_verify() failed (test case {i})",); } } #[test] fn test_cosmos_extra_secp256k1_verify() { - use std::fs::File; - use std::io::BufReader; - - use serde::Deserialize; - - #[derive(Deserialize, Debug)] - struct Encoded { - message: String, - message_hash: String, - signature: String, - #[serde(rename = "pubkey")] - public_key: String, - } - // Open the file in read-only mode with buffer. let file = File::open(COSMOS_SECP256K1_TESTS_JSON).unwrap(); let reader = BufReader::new(file); @@ -288,20 +306,18 @@ mod tests { for (i, encoded) in (1..).zip(codes) { let message = hex::decode(&encoded.message).unwrap(); + let signature = hex::decode(&encoded.signature).unwrap(); + let public_key = hex::decode(&encoded.public_key).unwrap(); let hash = hex::decode(&encoded.message_hash).unwrap(); - let message_hash = Sha256::digest(&message); + let message_hash = Sha256::digest(message); assert_eq!(hash.as_slice(), message_hash.as_slice()); - let signature = hex::decode(&encoded.signature).unwrap(); - - let public_key = hex::decode(&encoded.public_key).unwrap(); - // secp256k1_verify() works + let valid = secp256k1_verify(&message_hash, &signature, &public_key).unwrap(); assert!( - secp256k1_verify(&message_hash, &signature, &public_key).unwrap(), - "verify() failed (test case {})", - i + valid, + "secp256k1_verify failed (test case {i} in {COSMOS_SECP256K1_TESTS_JSON})" ); } } @@ -312,7 +328,7 @@ mod tests { { let private_key = hex!("3c9229289a6125f7fdf1885a77bb12c37a8d3b4962d936f7e3084dece32a3ca1"); - let expected = SigningKey::from_bytes(&private_key) + let expected = SigningKey::from_bytes(&private_key.into()) .unwrap() .verifying_key() .to_encoded_point(false) @@ -327,10 +343,11 @@ mod tests { } // Test data from https://github.com/randombit/botan/blob/2.9.0/src/tests/data/pubkey/ecdsa_key_recovery.vec + // This is a high-s value (`0x81F1A4457589F30D76AB9F89E748A68C8A94C30FE0BAC8FB5C0B54EA70BF6D2F > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0` is true) { let expected_x = "F3F8BB913AA68589A2C8C607A877AB05252ADBD963E1BE846DDEB8456942AEDC"; let expected_y = "A2ED51F08CA3EF3DAC0A7504613D54CD539FC1B3CBC92453CD704B6A2D012B2C"; - let expected = hex::decode(format!("04{}{}", expected_x, expected_y)).unwrap(); + let expected = hex::decode(format!("04{expected_x}{expected_y}")).unwrap(); let r_s = hex!("E30F2E6A0F705F4FB5F8501BA79C7C0D3FAC847F1AD70B873E9797B17B89B39081F1A4457589F30D76AB9F89E748A68C8A94C30FE0BAC8FB5C0B54EA70BF6D2F"); let recovery_param: u8 = 0; let message_hash = @@ -349,6 +366,32 @@ mod tests { let pubkey = secp256k1_recover_pubkey(&message_hash, &r_s, recovery_param).unwrap(); assert_eq!(pubkey, expected); } + + let file = File::open(COSMOS_SECP256K1_TESTS_JSON).unwrap(); + let reader = BufReader::new(file); + let codes: Vec = serde_json::from_reader(reader).unwrap(); + for (i, encoded) in (1..).zip(codes) { + let message = hex::decode(&encoded.message).unwrap(); + let signature = hex::decode(&encoded.signature).unwrap(); + let public_key = hex::decode(&encoded.public_key).unwrap(); + + let hash = hex::decode(&encoded.message_hash).unwrap(); + let message_hash = Sha256::digest(message); + assert_eq!(hash.as_slice(), message_hash.as_slice()); + + // Since the recovery param is missing in the test vectors, we try both 0 and 1 + let try0 = secp256k1_recover_pubkey(&message_hash, &signature, 0); + let try1 = secp256k1_recover_pubkey(&message_hash, &signature, 1); + match (try0, try1) { + (Ok(recovered0), Ok(recovered1)) => { + // Got two different pubkeys. Without the recovery param, we don't know which one is the right one. + assert!(recovered0 == public_key || recovered1 == public_key) + }, + (Ok(recovered), Err(_)) => assert_eq!(recovered, public_key), + (Err(_), Ok(recovered)) => assert_eq!(recovered, public_key), + (Err(_), Err(_)) => panic!("secp256k1_recover_pubkey failed (test case {i} in {COSMOS_SECP256K1_TESTS_JSON})"), + } + } } #[test] @@ -360,24 +403,24 @@ mod tests { let recovery_param: u8 = 2; match secp256k1_recover_pubkey(&message_hash, &r_s, recovery_param).unwrap_err() { CryptoError::InvalidRecoveryParam { .. } => {} - err => panic!("Unexpected error: {}", err), + err => panic!("Unexpected error: {err}"), } let recovery_param: u8 = 3; match secp256k1_recover_pubkey(&message_hash, &r_s, recovery_param).unwrap_err() { CryptoError::InvalidRecoveryParam { .. } => {} - err => panic!("Unexpected error: {}", err), + err => panic!("Unexpected error: {err}"), } // Other values are garbage let recovery_param: u8 = 4; match secp256k1_recover_pubkey(&message_hash, &r_s, recovery_param).unwrap_err() { CryptoError::InvalidRecoveryParam { .. } => {} - err => panic!("Unexpected error: {}", err), + err => panic!("Unexpected error: {err}"), } let recovery_param: u8 = 255; match secp256k1_recover_pubkey(&message_hash, &r_s, recovery_param).unwrap_err() { CryptoError::InvalidRecoveryParam { .. } => {} - err => panic!("Unexpected error: {}", err), + err => panic!("Unexpected error: {err}"), } } } diff --git a/packages/derive/src/lib.rs b/packages/derive/src/lib.rs index 2b5bbfb94..cd8d8c957 100644 --- a/packages/derive/src/lib.rs +++ b/packages/derive/src/lib.rs @@ -62,9 +62,9 @@ pub fn entry_point(_attr: TokenStream, mut item: TokenStream) -> TokenStream { let args = function.sig.inputs.len() - 1; // E.g. "ptr0: u32, ptr1: u32, ptr2: u32, " - let typed_ptrs = (0..args).fold(String::new(), |acc, i| format!("{}ptr{}: u32, ", acc, i)); + let typed_ptrs = (0..args).fold(String::new(), |acc, i| format!("{acc}ptr{i}: u32, ")); // E.g. "ptr0, ptr1, ptr2, " - let ptrs = (0..args).fold(String::new(), |acc, i| format!("{}ptr{}, ", acc, i)); + let ptrs = (0..args).fold(String::new(), |acc, i| format!("{acc}ptr{i}, ")); let new_code = format!( r##" @@ -75,10 +75,7 @@ pub fn entry_point(_attr: TokenStream, mut item: TokenStream) -> TokenStream { cosmwasm_std::do_{name}(&super::{name}, {ptrs}) }} }} - "##, - name = name, - typed_ptrs = typed_ptrs, - ptrs = ptrs + "## ); let entry = TokenStream::from_str(&new_code).unwrap(); item.extend(entry); diff --git a/packages/go-gen/Cargo.toml b/packages/go-gen/Cargo.toml new file mode 100644 index 000000000..ef4f97622 --- /dev/null +++ b/packages/go-gen/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "go-gen" +authors = ["Christoph Otter "] +version = "0.1.0" +edition = "2021" +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +schemars = "0.8.3" +cosmwasm-std = { path = "../std", version = "1.1.9+0.8.1", features = ["cosmwasm_1_4", "staking", "stargate", "ibc3"] } +cosmwasm-schema = { path = "../schema", version = "1.1.9+0.8.1" } +anyhow = "1" +Inflector = "0.11.4" +indenter = "0.3.3" diff --git a/packages/go-gen/README.md b/packages/go-gen/README.md new file mode 100644 index 000000000..07d242a15 --- /dev/null +++ b/packages/go-gen/README.md @@ -0,0 +1,21 @@ +# JsonSchema Go Type Generator + +This is an internal utility to generate Go types from `cosmwasm-std`'s query +response types. These types can then be used in +[wasmvm](https://github.com/CosmWasm/wasmvm). + +## Usage + +Adjust the query / response type you want to generate in `src/main.rs` and run: +`cargo run -p go-gen` + +## Limitations + +Only basic structs and enums are supported. Tuples and enum variants with 0 or +more than 1 parameters don't work, for example. + +## License + +This package is part of the cosmwasm repository, licensed under the Apache +License 2.0 (see [NOTICE](https://github.com/CosmWasm/cosmwasm/blob/main/NOTICE) +and [LICENSE](https://github.com/CosmWasm/cosmwasm/blob/main/LICENSE)). diff --git a/packages/go-gen/src/go.rs b/packages/go-gen/src/go.rs new file mode 100644 index 000000000..faead10df --- /dev/null +++ b/packages/go-gen/src/go.rs @@ -0,0 +1,237 @@ +use std::fmt::{self, Display, Write}; + +use indenter::indented; +use inflector::Inflector; + +use crate::utils::replace_acronyms; + +pub struct GoStruct { + pub name: String, + pub docs: Option, + pub fields: Vec, +} + +impl Display for GoStruct { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // generate documentation + format_docs(f, self.docs.as_deref())?; + // generate type + writeln!(f, "type {} struct {{", self.name)?; + // generate fields + { + let mut f = indented(f); + for field in &self.fields { + writeln!(f, "{}", field)?; + } + } + f.write_char('}')?; + Ok(()) + } +} + +pub struct GoField { + /// The name of the field in Rust (snake_case) + pub rust_name: String, + /// The documentation of the field + pub docs: Option, + /// The type of the field + pub ty: GoType, +} + +impl Display for GoField { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // documentation + format_docs(f, self.docs.as_deref())?; + // {field} {type} `json:"{field}"` + write!( + f, + "{} {} `json:\"{}", + replace_acronyms(self.rust_name.to_pascal_case()), + self.ty, + self.rust_name + )?; + if self.ty.is_nullable { + f.write_str(",omitempty")?; + } + f.write_str("\"`") + } +} + +pub struct GoType { + /// The name of the type in Go + pub name: String, + /// Whether the type should be nullable + /// This will add `omitempty` to the json tag and use a pointer type if + /// the type is not a basic type + pub is_nullable: bool, +} + +impl GoType { + pub fn is_basic_type(&self) -> bool { + const BASIC_GO_TYPES: &[&str] = &[ + "string", + "bool", + "int", + "int8", + "int16", + "int32", + "int64", + "uint", + "uint8", + "uint16", + "uint32", + "uint64", + "float32", + "float64", + "byte", + "rune", + "uintptr", + "complex64", + "complex128", + ]; + BASIC_GO_TYPES.contains(&&*self.name) + } +} + +impl Display for GoType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.is_nullable && !self.is_basic_type() { + // if the type is nullable and not a basic type, use a pointer + f.write_char('*')?; + } + f.write_str(&self.name) + } +} + +fn format_docs(f: &mut fmt::Formatter, docs: Option<&str>) -> fmt::Result { + if let Some(docs) = docs { + for line in docs.lines() { + f.write_str("// ")?; + f.write_str(line)?; + f.write_char('\n')?; + } + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn go_type_display_works() { + let ty = GoType { + name: "string".to_string(), + is_nullable: true, + }; + let ty2 = GoType { + name: "string".to_string(), + is_nullable: false, + }; + assert_eq!(format!("{}", ty), "string"); + assert_eq!(format!("{}", ty2), "string"); + + let ty = GoType { + name: "FooBar".to_string(), + is_nullable: true, + }; + assert_eq!(format!("{}", ty), "*FooBar"); + let ty = GoType { + name: "FooBar".to_string(), + is_nullable: false, + }; + assert_eq!(format!("{}", ty), "FooBar"); + } + + #[test] + fn go_field_display_works() { + let field = GoField { + rust_name: "foo_bar".to_string(), + docs: None, + ty: GoType { + name: "string".to_string(), + is_nullable: true, + }, + }; + assert_eq!( + format!("{}", field), + "FooBar string `json:\"foo_bar,omitempty\"`" + ); + + let field = GoField { + rust_name: "foo_bar".to_string(), + docs: None, + ty: GoType { + name: "string".to_string(), + is_nullable: false, + }, + }; + assert_eq!(format!("{}", field), "FooBar string `json:\"foo_bar\"`"); + + let field = GoField { + rust_name: "foo_bar".to_string(), + docs: None, + ty: GoType { + name: "FooBar".to_string(), + is_nullable: true, + }, + }; + assert_eq!( + format!("{}", field), + "FooBar *FooBar `json:\"foo_bar,omitempty\"`" + ); + } + + #[test] + fn go_field_docs_display_works() { + let field = GoField { + rust_name: "foo_bar".to_string(), + docs: Some("foo_bar is a test field".to_string()), + ty: GoType { + name: "string".to_string(), + is_nullable: true, + }, + }; + assert_eq!( + format!("{}", field), + "// foo_bar is a test field\nFooBar string `json:\"foo_bar,omitempty\"`" + ); + } + + #[test] + fn go_type_def_display_works() { + let ty = GoStruct { + name: "FooBar".to_string(), + docs: None, + fields: vec![GoField { + rust_name: "foo_bar".to_string(), + docs: None, + ty: GoType { + name: "string".to_string(), + is_nullable: true, + }, + }], + }; + assert_eq!( + format!("{}", ty), + "type FooBar struct {\n FooBar string `json:\"foo_bar,omitempty\"`\n}" + ); + + let ty = GoStruct { + name: "FooBar".to_string(), + docs: Some("FooBar is a test struct".to_string()), + fields: vec![GoField { + rust_name: "foo_bar".to_string(), + docs: None, + ty: GoType { + name: "string".to_string(), + is_nullable: true, + }, + }], + }; + assert_eq!( + format!("{}", ty), + "// FooBar is a test struct\ntype FooBar struct {\n FooBar string `json:\"foo_bar,omitempty\"`\n}" + ); + } +} diff --git a/packages/go-gen/src/main.rs b/packages/go-gen/src/main.rs new file mode 100644 index 000000000..8d3dcc3d4 --- /dev/null +++ b/packages/go-gen/src/main.rs @@ -0,0 +1,469 @@ +use anyhow::{bail, ensure, Context, Result}; +use go::*; +use inflector::cases::pascalcase::to_pascal_case; +use schema::{documentation, schema_object_type, SchemaExt, TypeContext}; +use schemars::schema::{ObjectValidation, RootSchema, Schema, SchemaObject}; +use std::fmt::Write; +use utils::replace_acronyms; + +mod go; +mod schema; +mod utils; + +fn main() -> Result<()> { + let root = cosmwasm_schema::schema_for!(cosmwasm_std::BankQuery); + + let code = generate_go(root)?; + println!("{}", code); + + Ok(()) +} + +/// Generates the Go code for the given schema +fn generate_go(root: RootSchema) -> Result { + let title = replace_acronyms( + root.schema + .metadata + .as_ref() + .and_then(|m| m.title.as_ref()) + .context("failed to get type name")?, + ); + + let mut types = vec![]; + build_type(&title, &root.schema, &mut types) + .with_context(|| format!("failed to generate {title}"))?; + + // go through additional definitions + for (name, additional_type) in &root.definitions { + additional_type + .object() + .map(|def| build_type(&replace_acronyms(name), def, &mut types)) + .and_then(|r| r) + .context("failed to generate additional definitions")?; + } + let mut code = String::new(); + for ty in types { + writeln!(&mut code, "{ty}")?; + } + + Ok(code) +} + +/// Generates Go structs for the given schema and adds them to `structs`. +/// This will add more than one struct if the schema contains object types (anonymous structs). +fn build_type(name: &str, schema: &SchemaObject, structs: &mut Vec) -> Result<()> { + if schema::custom_type_of(name).is_some() { + // ignore custom types + return Ok(()); + } + + // first detect if we have a struct or enum + if let Some(obj) = schema.object.as_ref() { + let strct = build_struct(name, schema, obj, structs) + .map(Some) + .with_context(|| format!("failed to generate struct '{name}'"))?; + if let Some(strct) = strct { + structs.push(strct); + } + } else if let Some(variants) = schema::enum_variants(schema) { + let strct = build_enum(name, schema, variants, structs) + .map(Some) + .with_context(|| format!("failed to generate enum '{name}'"))?; + if let Some(strct) = strct { + structs.push(strct); + } + } else { + anyhow::bail!("failed to determine type for '{name}'"); + } + + Ok(()) +} + +/// Creates a Go struct for the given schema object and returns it. +/// This will also add any additional structs to `additional_structs` (but not the returned one). +pub fn build_struct( + name: &str, + strct: &SchemaObject, + obj: &ObjectValidation, + additional_structs: &mut Vec, +) -> Result { + let docs = documentation(strct); + + // go through all fields + let fields = obj.properties.iter().map(|(field, ty)| { + // get schema object + let schema = ty + .object() + .with_context(|| format!("expected schema object for field {field}"))?; + // extract type from schema object + let ty = schema_object_type(schema, TypeContext::new(name, field), additional_structs) + .with_context(|| format!("failed to get type of field '{field}'"))?; + Ok(GoField { + rust_name: field.clone(), + docs: documentation(schema), + ty, + }) + }); + let fields = fields.collect::>>()?; + + Ok(GoStruct { + name: to_pascal_case(name), + docs, + fields, + }) +} + +/// Creates a Go struct for the given schema object and returns it. +/// This will also add any additional structs to `additional_structs` (but not the returned one). +pub fn build_enum<'a>( + name: &str, + enm: &SchemaObject, + variants: impl Iterator, + additional_structs: &mut Vec, +) -> Result { + let docs = documentation(enm); + + // go through all fields + let fields = variants.map(|v| { + // get schema object + let v = v + .object() + .with_context(|| format!("expected schema object for enum variants of {name}"))?; + + // analyze the variant + let variant_field = build_enum_variant(v, name, additional_structs) + .context("failed to extract enum variant")?; + + anyhow::Ok(variant_field) + }); + let fields = fields.collect::>>()?; + + Ok(GoStruct { + name: name.to_string(), + docs, + fields, + }) +} + +/// Tries to extract the name and type of the given enum variant and returns it as a `GoField`. +pub fn build_enum_variant( + schema: &SchemaObject, + enum_name: &str, + additional_structs: &mut Vec, +) -> Result { + // for variants without inner data, there is an entry in `enum_variants` + // we are not interested in that case, so we error out + if let Some(values) = &schema.enum_values { + bail!( + "enum variants {} without inner data not supported", + values + .iter() + .map(|v| v.to_string()) + .collect::>() + .join(", ") + ); + } + + let docs = documentation(schema); + + // for variants with inner data, there is an object validation entry with a single property + // we extract the type of that property + let properties = &schema + .object + .as_ref() + .context("expected object validation for enum variant")? + .properties; + ensure!( + properties.len() == 1, + "expected exactly one property in enum variant" + ); + // we can unwrap here, because we checked the length above + let (name, schema) = properties.first_key_value().unwrap(); + let GoType { name: ty, .. } = schema_object_type( + schema.object()?, + TypeContext::new(enum_name, name), + additional_structs, + )?; + + Ok(GoField { + rust_name: name.to_string(), + docs, + ty: GoType { + name: ty, + is_nullable: true, // always nullable + }, + }) +} + +#[cfg(test)] +mod tests { + use cosmwasm_schema::cw_serde; + use cosmwasm_std::{Binary, Empty, HexBinary, Uint128}; + + use super::*; + + fn assert_code_eq(actual: String, expected: &str) { + let actual_no_ws = actual.split_whitespace().collect::>(); + let expected_no_ws = expected.split_whitespace().collect::>(); + + assert!( + actual_no_ws == expected_no_ws, + "assertion failed: `(actual == expected)`\nactual:\n`{}`,\nexpected:\n`\"{}\"`", + actual, + expected + ); + } + + fn assert_code_eq_ignore_docs(actual: String, expected: &str) { + let actual_filtered = actual + .lines() + .map(|line| line.split("//").next().unwrap()) // ignore comments + .flat_map(|line| line.split_whitespace()) + .collect::>(); + let expected_filtered = expected + .lines() + .map(|line| line.split("//").next().unwrap()) // ignore comments + .flat_map(|line| line.split_whitespace()) + .collect::>(); + + assert!( + actual_filtered == expected_filtered, + "assertion failed: `(actual == expected)`\nactual:\n`{}`,\nexpected:\n`\"{}\"`", + actual, + expected + ); + } + + #[test] + fn special_types() { + #[cw_serde] + struct SpecialTypes { + binary: Binary, + nested_binary: Vec>, + hex_binary: HexBinary, + uint128: Uint128, + } + + let schema = schemars::schema_for!(SpecialTypes); + let code = generate_go(schema).unwrap(); + + assert_code_eq( + code, + r#" + type SpecialTypes struct { + Binary []byte `json:"binary"` + HexBinary Checksum `json:"hex_binary"` + NestedBinary []*[]byte `json:"nested_binary"` + Uint128 string `json:"uint128"` + }"#, + ); + } + + #[test] + fn integers() { + #[cw_serde] + struct Integers { + a: u64, + b: i64, + c: u32, + d: i32, + e: u8, + f: i8, + g: u16, + h: i16, + } + + let schema = schemars::schema_for!(Integers); + let code = generate_go(schema).unwrap(); + + assert_code_eq( + code, + r#" + type Integers struct { + A uint64 `json:"a"` + B int64 `json:"b"` + C uint32 `json:"c"` + D int32 `json:"d"` + E uint8 `json:"e"` + F int8 `json:"f"` + G uint16 `json:"g"` + H int16 `json:"h"` + }"#, + ); + + #[cw_serde] + struct U128 { + a: u128, + } + #[cw_serde] + struct I128 { + a: i128, + } + let schema = schemars::schema_for!(U128); + assert!(generate_go(schema) + .unwrap_err() + .root_cause() + .to_string() + .contains("unsupported integer format: uint128")); + let schema = schemars::schema_for!(I128); + assert!(generate_go(schema) + .unwrap_err() + .root_cause() + .to_string() + .contains("unsupported integer format: int128")); + } + + #[test] + fn empty() { + #[cw_serde] + struct Empty {} + + let schema = schemars::schema_for!(Empty); + let code = generate_go(schema).unwrap(); + assert_code_eq(code, "type Empty struct { }"); + } + + /// Compares the generated code for a given type with the code in the corresponding file in + /// `tests/`. + /// The file name is derived from the type name by replacing `::` with `__` and adding `.go`. + macro_rules! compare_codes { + ($name:ty) => {{ + let filename = stringify!($name).replace("::", "__"); + let generated = generate_go(cosmwasm_schema::schema_for!($name)).unwrap(); + let expected = std::fs::read_to_string(format!("tests/{}.go", filename)).unwrap(); + + assert_code_eq_ignore_docs(generated, &expected); + }}; + } + + #[test] + fn responses_work() { + // bank + compare_codes!(cosmwasm_std::SupplyResponse); + compare_codes!(cosmwasm_std::BalanceResponse); + // compare_codes!(cosmwasm_std::AllBalanceResponse); // has different name in wasmvm + compare_codes!(cosmwasm_std::DenomMetadataResponse); + // compare_codes!(cosmwasm_std::AllDenomMetadataResponse); // uses `[]byte` instead of `*[]byte` + // staking + compare_codes!(cosmwasm_std::BondedDenomResponse); + compare_codes!(cosmwasm_std::AllDelegationsResponse); + compare_codes!(cosmwasm_std::DelegationResponse); + compare_codes!(cosmwasm_std::AllValidatorsResponse); + // compare_codes!(cosmwasm_std::ValidatorResponse); // does not use "omitempty" for `Validator` field + // distribution + compare_codes!(cosmwasm_std::DelegatorWithdrawAddressResponse); + compare_codes!(cosmwasm_std::DelegationRewardsResponse); + compare_codes!(cosmwasm_std::DelegationTotalRewardsResponse); + compare_codes!(cosmwasm_std::DelegatorValidatorsResponse); + // wasm + compare_codes!(cosmwasm_std::ContractInfoResponse); + // compare_codes!(cosmwasm_std::CodeInfoResponse); // TODO: Checksum type and "omitempty" + } + + #[test] + fn nested_enum_works() { + #[cw_serde] + struct Inner { + a: String, + } + + #[cw_serde] + enum MyEnum { + A(Inner), + B(String), + C { a: String }, + } + + let schema = schemars::schema_for!(MyEnum); + let code = generate_go(schema).unwrap(); + assert_code_eq( + code, + r#" + type CEnum struct { + A string `json:"a"` + } + type MyEnum struct { + A *Inner `json:"a,omitempty"` + B string `json:"b,omitempty"` + C *CEnum `json:"c,omitempty"` + } + type Inner struct { + A string `json:"a"` + } + "#, + ); + + #[cw_serde] + enum ShouldFail1 { + A(), + } + #[cw_serde] + enum ShouldFail2 { + A, + } + let schema = schemars::schema_for!(ShouldFail1); + assert!(generate_go(schema) + .unwrap_err() + .root_cause() + .to_string() + .contains("array type with non-singular item type is not supported")); + let schema = schemars::schema_for!(ShouldFail2); + assert!(generate_go(schema) + .unwrap_err() + .root_cause() + .to_string() + .contains("failed to determine type for 'ShouldFail2'")); + } + + #[test] + fn queries_work() { + // compare_codes!(cosmwasm_std::QueryRequest); // omit for now because it's huge + // just assert that it compiles + generate_go(cosmwasm_schema::schema_for!( + cosmwasm_std::QueryRequest + )) + .unwrap(); + // TODO: PageRequest.Key uses "omitempty" and no * + // compare_codes!(cosmwasm_std::BankQuery); + compare_codes!(cosmwasm_std::StakingQuery); + compare_codes!(cosmwasm_std::DistributionQuery); + compare_codes!(cosmwasm_std::IbcQuery); + compare_codes!(cosmwasm_std::WasmQuery); + } + + #[test] + fn array_item_type_works() { + #[cw_serde] + struct A { + a: Vec>>>>, + } + #[cw_serde] + struct B {} + + // example json: + // A { a: vec![vec![vec![None, Some(Some(B {})), Some(None)]]] } + // => {"a":[[[null,{},null]]]} + let code = generate_go(cosmwasm_schema::schema_for!(A)).unwrap(); + assert_code_eq( + code, + r#" + type A struct { + A [][][]*B `json:"a"` + } + type B struct { }"#, + ); + + #[cw_serde] + struct C { + c: Vec>>>>, + } + let code = generate_go(cosmwasm_schema::schema_for!(C)).unwrap(); + assert_code_eq( + code, + r#" + type C struct { + C [][][]*string `json:"c"` + }"#, + ); + } +} diff --git a/packages/go-gen/src/schema.rs b/packages/go-gen/src/schema.rs new file mode 100644 index 000000000..9d9a3fa86 --- /dev/null +++ b/packages/go-gen/src/schema.rs @@ -0,0 +1,276 @@ +use anyhow::{bail, ensure, Context, Result}; + +use inflector::Inflector; +use schemars::schema::{InstanceType, Schema, SchemaObject, SingleOrVec}; + +use crate::{ + go::{GoField, GoStruct, GoType}, + utils::{replace_acronyms, suffixes}, +}; + +pub trait SchemaExt { + /// Returns a reference to the contained schema object, + /// or an error if the schema is not an object. + fn object(&self) -> anyhow::Result<&SchemaObject>; +} + +impl SchemaExt for Schema { + fn object(&self) -> anyhow::Result<&SchemaObject> { + match self { + Schema::Object(o) => Ok(o), + _ => bail!("expected schema object"), + } + } +} + +/// Returns the schemas of the variants of this enum, if it is an enum. +/// Returns `None` if the schema is not an enum. +pub fn enum_variants(schema: &SchemaObject) -> Option> { + Some(schema.subschemas.as_ref()?.one_of.as_ref()?.iter()) +} + +/// Returns the Go type for the given schema object and whether it is nullable. +/// May also add additional structs to the given `Vec` that need to be generated for this type. +pub fn schema_object_type( + schema: &SchemaObject, + type_context: TypeContext, + additional_structs: &mut Vec, +) -> Result { + let mut is_nullable = is_null(schema); + + // if it has a title, use that + let ty = if let Some(title) = schema.metadata.as_ref().and_then(|m| m.title.as_ref()) { + replace_custom_type(title) + } else if let Some(reference) = &schema.reference { + // if it has a reference, strip the path and use that + replace_custom_type( + reference + .split('/') + .last() + .expect("split should always return at least one item"), + ) + } else if let Some(t) = &schema.instance_type { + type_from_instance_type(schema, type_context, t, additional_structs)? + } else if let Some(subschemas) = schema.subschemas.as_ref().and_then(|s| s.any_of.as_ref()) { + // check if one of them is null + let nullable = nullable_type(subschemas)?; + if let Some(non_null) = nullable { + ensure!(subschemas.len() == 2, "multiple subschemas in anyOf"); + is_nullable = true; + // extract non-null type + let GoType { name, .. } = + schema_object_type(non_null, type_context, additional_structs)?; + replace_custom_type(&name) + } else { + subschema_type(subschemas, type_context, additional_structs) + .context("failed to get type of anyOf subschemas")? + } + } else if let Some(subschemas) = schema + .subschemas + .as_ref() + .and_then(|s| s.all_of.as_ref().or(s.one_of.as_ref())) + { + subschema_type(subschemas, type_context, additional_structs) + .context("failed to get type of allOf subschemas")? + } else { + bail!("no type for schema found: {:?}", schema); + }; + + Ok(GoType { + name: ty, + is_nullable, + }) +} + +/// Tries to extract the type of the non-null variant of an anyOf schema. +/// +/// Returns `Ok(None)` if the type is not nullable. +pub fn nullable_type(subschemas: &[Schema]) -> Result, anyhow::Error> { + let (found_null, nullable_type): (bool, Option<&SchemaObject>) = subschemas + .iter() + .fold(Ok((false, None)), |result: Result<_>, subschema| { + result.and_then(|(nullable, not_null)| { + let subschema = subschema.object()?; + if is_null(subschema) { + Ok((true, not_null)) + } else { + Ok((nullable, Some(subschema))) + } + }) + }) + .context("failed to get anyOf subschemas")?; + + Ok(if found_null { nullable_type } else { None }) +} + +/// The context for type extraction +#[derive(Clone, Copy, Debug)] +pub struct TypeContext<'a> { + /// The struct name + struct_name: &'a str, + /// The name of the field in the parent struct + field: &'a str, +} + +impl<'a> TypeContext<'a> { + pub fn new(parent: &'a str, field: &'a str) -> Self { + Self { + struct_name: parent, + field, + } + } +} + +/// Tries to extract a type name from the given instance type. +/// +/// Fails for unsupported instance types or integer formats. +pub fn type_from_instance_type( + schema: &SchemaObject, + type_context: TypeContext, + t: &SingleOrVec, + additional_structs: &mut Vec, +) -> Result { + // if it has an instance type, use that + Ok(if t.contains(&InstanceType::String) { + "string".to_string() + } else if t.contains(&InstanceType::Number) { + "float64".to_string() + } else if t.contains(&InstanceType::Integer) { + const AVAILABLE_INTS: &[&str] = &[ + "uint8", "int8", "uint16", "int16", "uint32", "int32", "uint64", "int64", + ]; + let format = schema.format.as_deref().unwrap_or("int64"); + if AVAILABLE_INTS.contains(&format) { + format.to_string() + } else { + bail!("unsupported integer format: {}", format); + } + } else if t.contains(&InstanceType::Boolean) { + "bool".to_string() + } else if t.contains(&InstanceType::Object) { + // generate a new struct for this object + // struct_name should be in PascalCase, so we detect the last word and use that as + // the suffix for the new struct name + let suffix = suffixes(type_context.struct_name) + .rev() + .find(|s| s.starts_with(char::is_uppercase)) + .unwrap_or(type_context.struct_name); + let new_struct_name = format!( + "{}{suffix}", + replace_acronyms(type_context.field.to_pascal_case()) + ); + + let fields = schema + .object + .as_ref() + .context("expected object validation")? + .properties + .iter() + .map(|(name, schema)| { + let schema = schema.object()?; + let ty = schema_object_type( + schema, + TypeContext::new(&new_struct_name, name), + additional_structs, + )?; + Ok(GoField { + rust_name: name.to_string(), + docs: documentation(schema), + ty, + }) + }) + .collect::>>()?; + + let strct = GoStruct { + name: new_struct_name.clone(), + docs: None, + fields, + }; + additional_structs.push(strct); + + new_struct_name + } else if t.contains(&InstanceType::Array) { + // get type of items + let item_type = array_item_type(schema, type_context, additional_structs) + .context("failed to get array item type")?; + + // for nullable array item types, we have to use a pointer type, even for basic types, + // so we can pass null as elements + // otherwise they would just be omitted from the array + replace_custom_type(&if item_type.is_nullable { + format!("[]*{}", item_type.name) + } else { + format!("[]{}", item_type.name) + }) + } else { + unreachable!("instance type should be one of the above") + }) +} + +/// Extract the type of the items of an array. +/// +/// This fails if the given schema object is not an array, +/// has multiple item types or other errors occur during type extraction of +/// the underlying schema. +pub fn array_item_type( + schema: &SchemaObject, + type_context: TypeContext, + additional_structs: &mut Vec, +) -> Result { + match schema.array.as_ref().and_then(|a| a.items.as_ref()) { + Some(SingleOrVec::Single(array_validation)) => { + schema_object_type(array_validation.object()?, type_context, additional_structs) + } + _ => bail!("array type with non-singular item type is not supported"), + } +} + +/// Tries to extract a type name from the given subschemas. +/// +/// This fails if there are multiple subschemas or other errors occur +/// during subschema type extraction. +pub fn subschema_type( + subschemas: &[Schema], + type_context: TypeContext, + additional_structs: &mut Vec, +) -> Result { + ensure!( + subschemas.len() == 1, + "multiple subschemas are not supported" + ); + let subschema = &subschemas[0]; + let GoType { name, .. } = + schema_object_type(subschema.object()?, type_context, additional_structs)?; + Ok(replace_custom_type(&name)) +} + +pub fn is_null(schema: &SchemaObject) -> bool { + schema + .instance_type + .as_ref() + .map_or(false, |s| s.contains(&InstanceType::Null)) +} + +pub fn documentation(schema: &SchemaObject) -> Option { + schema.metadata.as_ref()?.description.as_ref().cloned() +} + +/// Maps special types to their Go equivalents. +/// If the given type is not a special type, returns `None`. +pub fn custom_type_of(ty: &str) -> Option<&str> { + match ty { + "Uint128" => Some("string"), + "Binary" => Some("[]byte"), + "HexBinary" => Some("Checksum"), + "Addr" => Some("string"), + "Decimal" => Some("string"), + "Decimal256" => Some("string"), + _ => None, + } +} + +pub fn replace_custom_type(ty: &str) -> String { + custom_type_of(ty) + .map(|ty| ty.to_string()) + .unwrap_or_else(|| ty.to_string()) +} diff --git a/packages/go-gen/src/utils.rs b/packages/go-gen/src/utils.rs new file mode 100644 index 000000000..fab616c7e --- /dev/null +++ b/packages/go-gen/src/utils.rs @@ -0,0 +1,80 @@ +/// An iterator that returns all suffixes of a string, excluding the empty string. +/// +/// It starts with the full string and ends with the last character. +/// It is a double-ended iterator and can be reversed. +pub fn suffixes(s: &str) -> impl Iterator + DoubleEndedIterator { + s.char_indices().map(|(pos, _)| &s[pos..]) +} + +/// Replaces common pascal-case acronyms with their uppercase counterparts. +pub fn replace_acronyms(ty: impl Into) -> String { + let mut ty = ty.into(); + replace_word_in_place(&mut ty, "Url", "URL"); + replace_word_in_place(&mut ty, "Uri", "URI"); + replace_word_in_place(&mut ty, "Id", "ID"); + replace_word_in_place(&mut ty, "Ibc", "IBC"); + ty +} + +fn replace_word_in_place(haystack: &mut String, from: &str, to: &str) { + assert_eq!(from.len(), to.len(), "from and to must be the same length"); + let mut start = 0; + while let Some(pos) = haystack[start..].find(from) { + let begin = start + pos; + let end = start + pos + from.len(); + let next_char = haystack.chars().nth(end); + match next_char { + Some(next_char) if next_char.is_ascii_lowercase() => {} + _ => { + // if the next character is uppercase or any non-ascii char or + // there is no next char, it's a full word + haystack.replace_range(begin..end, to); + } + } + start = end; + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic = "from and to must be the same length"] + fn replace_in_place_different_lengths() { + let mut s = "foo".to_string(); + replace_word_in_place(&mut s, "foo", "barbar"); + } + + #[test] + fn replace_in_place_multiple_works() { + let mut s = "FooFooFooFooFoo".to_string(); + replace_word_in_place(&mut s, "Foo", "bar"); + assert_eq!(s, "barbarbarbarbar"); + } + + #[test] + fn replace_in_place_single_works() { + let mut s = "foo".to_string(); + replace_word_in_place(&mut s, "foo", "bar"); + assert_eq!(s, "bar"); + } + + #[test] + fn replace_word_in_place_part() { + let mut s = "Foofoo".to_string(); + replace_word_in_place(&mut s, "Foo", "Bar"); + // should not replace, because it's not a full word + assert_eq!(s, "Foofoo"); + } + + #[test] + fn replace_acronyms_works() { + assert_eq!(replace_acronyms("MyIdentity"), "MyIdentity"); + assert_eq!(replace_acronyms("MyIdentityId"), "MyIdentityID"); + assert_eq!(replace_acronyms("MyUri"), "MyURI"); + assert_eq!(replace_acronyms("Url"), "URL"); + assert_eq!(replace_acronyms("A"), "A"); + assert_eq!(replace_acronyms("Url🦦"), "URL🦦"); + } +} diff --git a/packages/go-gen/tests/cosmwasm_std__AllBalanceResponse.go b/packages/go-gen/tests/cosmwasm_std__AllBalanceResponse.go new file mode 100644 index 000000000..8d1ea8136 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__AllBalanceResponse.go @@ -0,0 +1,10 @@ +// AllBalancesResponse is the expected response to AllBalancesQuery +type AllBalancesResponse struct { + Amount []Coin `json:"amount"` // in wasmvm, there is an alias for `[]Coin` +} + +// Coin is a string representation of the sdk.Coin type (more portable than sdk.Int) +type Coin struct { + Amount string `json:"amount"` // string encoing of decimal value, eg. "12.3456" + Denom string `json:"denom"` // type, eg. "ATOM" +} diff --git a/packages/go-gen/tests/cosmwasm_std__AllDelegationsResponse.go b/packages/go-gen/tests/cosmwasm_std__AllDelegationsResponse.go new file mode 100644 index 000000000..ccebdbcd3 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__AllDelegationsResponse.go @@ -0,0 +1,16 @@ +// AllDelegationsResponse is the expected response to AllDelegationsQuery +type AllDelegationsResponse struct { + Delegations []Delegation `json:"delegations"` // in wasmvm, there is an alias for `[]Delegation` +} + +// Coin is a string representation of the sdk.Coin type (more portable than sdk.Int) +type Coin struct { + Amount string `json:"amount"` // string encoing of decimal value, eg. "12.3456" + Denom string `json:"denom"` // type, eg. "ATOM" +} + +type Delegation struct { + Amount Coin `json:"amount"` + Delegator string `json:"delegator"` + Validator string `json:"validator"` +} diff --git a/packages/go-gen/tests/cosmwasm_std__AllDenomMetadataResponse.go b/packages/go-gen/tests/cosmwasm_std__AllDenomMetadataResponse.go new file mode 100644 index 000000000..d61cf12f3 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__AllDenomMetadataResponse.go @@ -0,0 +1,51 @@ +type AllDenomMetadataResponse struct { + Metadata []DenomMetadata `json:"metadata"` + // NextKey is the key to be passed to PageRequest.key to + // query the next page most efficiently. It will be empty if + // there are no more results. + NextKey []byte `json:"next_key,omitempty"` +} + +// Replicating the cosmos-sdk bank module Metadata type +type DenomMetadata struct { + // Base represents the base denom (should be the DenomUnit with exponent = 0). + Base string `json:"base"` + // DenomUnits represents the list of DenomUnits for a given coin + DenomUnits []DenomUnit `json:"denom_units"` + Description string `json:"description"` + // Display indicates the suggested denom that should be + // displayed in clients. + Display string `json:"display"` + // Name defines the name of the token (eg: Cosmos Atom) + // + // Since: cosmos-sdk 0.43 + Name string `json:"name"` + // Symbol is the token symbol usually shown on exchanges (eg: ATOM). This can + // be the same as the display. + // + // Since: cosmos-sdk 0.43 + Symbol string `json:"symbol"` + // URI to a document (on or off-chain) that contains additional information. Optional. + // + // Since: cosmos-sdk 0.46 + URI string `json:"uri"` + // URIHash is a sha256 hash of a document pointed by URI. It's used to verify that + // the document didn't change. Optional. + // + // Since: cosmos-sdk 0.46 + URIHash string `json:"uri_hash"` +} + +// Replicating the cosmos-sdk bank module DenomUnit type +type DenomUnit struct { + // Aliases is a list of string aliases for the given denom + Aliases []string `json:"aliases"` + // Denom represents the string name of the given denom unit (e.g uatom). + Denom string `json:"denom"` + // Exponent represents power of 10 exponent that one must + // raise the base_denom to in order to equal the given DenomUnit's denom + // 1 denom = 10^exponent base_denom + // (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with + // exponent = 6, thus: 1 atom = 10^6 uatom). + Exponent uint32 `json:"exponent"` +} diff --git a/packages/go-gen/tests/cosmwasm_std__AllValidatorsResponse.go b/packages/go-gen/tests/cosmwasm_std__AllValidatorsResponse.go new file mode 100644 index 000000000..9280eda05 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__AllValidatorsResponse.go @@ -0,0 +1,14 @@ +// AllValidatorsResponse is the expected response to AllValidatorsQuery +type AllValidatorsResponse struct { + Validators []Validator `json:"validators"` // in wasmvm, there is an alias for `[]Validator` +} + +type Validator struct { + Address string `json:"address"` + // decimal string, eg "0.02" + Commission string `json:"commission"` + // decimal string, eg "0.02" + MaxChangeRate string `json:"max_change_rate"` + // decimal string, eg "0.02" + MaxCommission string `json:"max_commission"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__BalanceResponse.go b/packages/go-gen/tests/cosmwasm_std__BalanceResponse.go new file mode 100644 index 000000000..a8735fd00 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__BalanceResponse.go @@ -0,0 +1,10 @@ +// BalanceResponse is the expected response to BalanceQuery +type BalanceResponse struct { + Amount Coin `json:"amount"` +} + +// Coin is a string representation of the sdk.Coin type (more portable than sdk.Int) +type Coin struct { + Amount string `json:"amount"` // string encoing of decimal value, eg. "12.3456" + Denom string `json:"denom"` // type, eg. "ATOM" +} diff --git a/packages/go-gen/tests/cosmwasm_std__BankQuery.go b/packages/go-gen/tests/cosmwasm_std__BankQuery.go new file mode 100644 index 000000000..ef7729af8 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__BankQuery.go @@ -0,0 +1,43 @@ +type SupplyQuery struct { + Denom string `json:"denom"` +} + +type BalanceQuery struct { + Address string `json:"address"` + Denom string `json:"denom"` +} + +type AllBalancesQuery struct { + Address string `json:"address"` +} + +type DenomMetadataQuery struct { + Denom string `json:"denom"` +} + +type AllDenomMetadataQuery struct { + // Pagination is an optional argument. + // Default pagination will be used if this is omitted + Pagination *PageRequest `json:"pagination,omitempty"` +} + +type BankQuery struct { + Supply *SupplyQuery `json:"supply,omitempty"` + Balance *BalanceQuery `json:"balance,omitempty"` + AllBalances *AllBalancesQuery `json:"all_balances,omitempty"` + DenomMetadata *DenomMetadataQuery `json:"denom_metadata,omitempty"` + AllDenomMetadata *AllDenomMetadataQuery `json:"all_denom_metadata,omitempty"` +} + +// Simplified version of the cosmos-sdk PageRequest type +type PageRequest struct { + // Key is a value returned in PageResponse.next_key to begin + // querying the next page most efficiently. Only one of offset or key + // should be set. + Key []byte `json:"key"` + // Limit is the total number of results to be returned in the result page. + // If left empty it will default to a value to be set by each app. + Limit uint32 `json:"limit"` + // Reverse is set to true if results are to be returned in the descending order. + Reverse bool `json:"reverse"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__BondedDenomResponse.go b/packages/go-gen/tests/cosmwasm_std__BondedDenomResponse.go new file mode 100644 index 000000000..cb16d2273 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__BondedDenomResponse.go @@ -0,0 +1,3 @@ +type BondedDenomResponse struct { + Denom string `json:"denom"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go b/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go new file mode 100644 index 000000000..1173e9e7f --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__CodeInfoResponse.go @@ -0,0 +1,5 @@ +type CodeInfoResponse struct { + Checksum Checksum `json:"checksum,omitempty"` + CodeID uint64 `json:"code_id"` + Creator string `json:"creator"` +} diff --git a/packages/go-gen/tests/cosmwasm_std__ContractInfoResponse.go b/packages/go-gen/tests/cosmwasm_std__ContractInfoResponse.go new file mode 100644 index 000000000..55ae866f5 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__ContractInfoResponse.go @@ -0,0 +1,9 @@ +type ContractInfoResponse struct { + // Set to the admin who can migrate contract, if any + Admin string `json:"admin,omitempty"` + CodeID uint64 `json:"code_id"` + Creator string `json:"creator"` + // Set if the contract is IBC enabled + IBCPort string `json:"ibc_port,omitempty"` + Pinned bool `json:"pinned"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__DelegationResponse.go b/packages/go-gen/tests/cosmwasm_std__DelegationResponse.go new file mode 100644 index 000000000..9dcac82df --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DelegationResponse.go @@ -0,0 +1,18 @@ +// DelegationResponse is the expected response to DelegationsQuery +type DelegationResponse struct { + Delegation *FullDelegation `json:"delegation,omitempty"` +} + +// Coin is a string representation of the sdk.Coin type (more portable than sdk.Int) +type Coin struct { + Amount string `json:"amount"` // string encoing of decimal value, eg. "12.3456" + Denom string `json:"denom"` // type, eg. "ATOM" +} + +type FullDelegation struct { + AccumulatedRewards []Coin `json:"accumulated_rewards"` // in wasmvm, there is an alias for `[]Coin` + Amount Coin `json:"amount"` + CanRedelegate Coin `json:"can_redelegate"` + Delegator string `json:"delegator"` + Validator string `json:"validator"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__DelegationRewardsResponse.go b/packages/go-gen/tests/cosmwasm_std__DelegationRewardsResponse.go new file mode 100644 index 000000000..8779f696d --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DelegationRewardsResponse.go @@ -0,0 +1,10 @@ +// See +type DelegationRewardsResponse struct { + Rewards []DecCoin `json:"rewards"` +} + +// A coin type with decimal amount. Modeled after the Cosmos SDK's [DecCoin](https://github.com/cosmos/cosmos-sdk/blob/c74e2887b0b73e81d48c2f33e6b1020090089ee0/proto/cosmos/base/v1beta1/coin.proto#L32-L41) type +type DecCoin struct { + Amount string `json:"amount"` + Denom string `json:"denom"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__DelegationTotalRewardsResponse.go b/packages/go-gen/tests/cosmwasm_std__DelegationTotalRewardsResponse.go new file mode 100644 index 000000000..772861c71 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DelegationTotalRewardsResponse.go @@ -0,0 +1,16 @@ +// See +type DelegationTotalRewardsResponse struct { + Rewards []DelegatorReward `json:"rewards"` + Total []DecCoin `json:"total"` +} + +// A coin type with decimal amount. Modeled after the Cosmos SDK's [DecCoin](https://github.com/cosmos/cosmos-sdk/blob/c74e2887b0b73e81d48c2f33e6b1020090089ee0/proto/cosmos/base/v1beta1/coin.proto#L32-L41) type +type DecCoin struct { + Amount string `json:"amount"` + Denom string `json:"denom"` +} + +type DelegatorReward struct { + Reward []DecCoin `json:"reward"` + ValidatorAddress string `json:"validator_address"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__DelegatorValidatorsResponse.go b/packages/go-gen/tests/cosmwasm_std__DelegatorValidatorsResponse.go new file mode 100644 index 000000000..3b831e04a --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DelegatorValidatorsResponse.go @@ -0,0 +1,4 @@ +// See +type DelegatorValidatorsResponse struct { + Validators []string `json:"validators"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__DelegatorWithdrawAddressResponse.go b/packages/go-gen/tests/cosmwasm_std__DelegatorWithdrawAddressResponse.go new file mode 100644 index 000000000..0e46ed30e --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DelegatorWithdrawAddressResponse.go @@ -0,0 +1,3 @@ +type DelegatorWithdrawAddressResponse struct { + WithdrawAddress string `json:"withdraw_address"` +} diff --git a/packages/go-gen/tests/cosmwasm_std__DenomMetadataResponse.go b/packages/go-gen/tests/cosmwasm_std__DenomMetadataResponse.go new file mode 100644 index 000000000..a75ddaf21 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DenomMetadataResponse.go @@ -0,0 +1,47 @@ +type DenomMetadataResponse struct { + Metadata DenomMetadata `json:"metadata"` +} + +// Replicating the cosmos-sdk bank module Metadata type +type DenomMetadata struct { + // Base represents the base denom (should be the DenomUnit with exponent = 0). + Base string `json:"base"` + // DenomUnits represents the list of DenomUnits for a given coin + DenomUnits []DenomUnit `json:"denom_units"` + Description string `json:"description"` + // Display indicates the suggested denom that should be + // displayed in clients. + Display string `json:"display"` + // Name defines the name of the token (eg: Cosmos Atom) + // + // Since: cosmos-sdk 0.43 + Name string `json:"name"` + // Symbol is the token symbol usually shown on exchanges (eg: ATOM). This can + // be the same as the display. + // + // Since: cosmos-sdk 0.43 + Symbol string `json:"symbol"` + // URI to a document (on or off-chain) that contains additional information. Optional. + // + // Since: cosmos-sdk 0.46 + URI string `json:"uri"` + // URIHash is a sha256 hash of a document pointed by URI. It's used to verify that + // the document didn't change. Optional. + // + // Since: cosmos-sdk 0.46 + URIHash string `json:"uri_hash"` +} + +// Replicating the cosmos-sdk bank module DenomUnit type +type DenomUnit struct { + // Aliases is a list of string aliases for the given denom + Aliases []string `json:"aliases"` + // Denom represents the string name of the given denom unit (e.g uatom). + Denom string `json:"denom"` + // Exponent represents power of 10 exponent that one must + // raise the base_denom to in order to equal the given DenomUnit's denom + // 1 denom = 10^exponent base_denom + // (e.g. with a base_denom of uatom, one can create a DenomUnit of 'atom' with + // exponent = 6, thus: 1 atom = 10^6 uatom). + Exponent uint32 `json:"exponent"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__DistributionQuery.go b/packages/go-gen/tests/cosmwasm_std__DistributionQuery.go new file mode 100644 index 000000000..5d33c3805 --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__DistributionQuery.go @@ -0,0 +1,24 @@ +type DelegatorWithdrawAddressQuery struct { + DelegatorAddress string `json:"delegator_address"` +} +type DelegationRewardsQuery struct { + DelegatorAddress string `json:"delegator_address"` + ValidatorAddress string `json:"validator_address"` +} +type DelegationTotalRewardsQuery struct { + DelegatorAddress string `json:"delegator_address"` +} +type DelegatorValidatorsQuery struct { + DelegatorAddress string `json:"delegator_address"` +} + +type DistributionQuery struct { + // See + DelegatorWithdrawAddress *DelegatorWithdrawAddressQuery `json:"delegator_withdraw_address,omitempty"` + // See + DelegationRewards *DelegationRewardsQuery `json:"delegation_rewards,omitempty"` + // See + DelegationTotalRewards *DelegationTotalRewardsQuery `json:"delegation_total_rewards,omitempty"` + // See + DelegatorValidators *DelegatorValidatorsQuery `json:"delegator_validators,omitempty"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__IbcQuery.go b/packages/go-gen/tests/cosmwasm_std__IbcQuery.go new file mode 100644 index 000000000..0bf4e30fa --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__IbcQuery.go @@ -0,0 +1,25 @@ +type PortIDQuery struct { +} + +// ListChannelsQuery is an IBCQuery that lists all channels that are bound to a given port. +// If `PortID` is unset, this list all channels bound to the contract's port. +// Returns a `ListChannelsResponse`. +// This is the counterpart of [IbcQuery::ListChannels](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0-beta1/packages/std/src/ibc.rs#L70-L73). +type ListChannelsQuery struct { + // optional argument + PortID string `json:"port_id,omitempty"` +} + +type ChannelQuery struct { + ChannelID string `json:"channel_id"` + // optional argument + PortID string `json:"port_id,omitempty"` +} + +// IBCQuery defines a query request from the contract into the chain. +// This is the counterpart of [IbcQuery](https://github.com/CosmWasm/cosmwasm/blob/v0.14.0-beta1/packages/std/src/ibc.rs#L61-L83). +type IBCQuery struct { + PortID *PortIDQuery `json:"port_id,omitempty"` + ListChannels *ListChannelsQuery `json:"list_channels,omitempty"` + Channel *ChannelQuery `json:"channel,omitempty"` +} diff --git a/packages/go-gen/tests/cosmwasm_std__StakingQuery.go b/packages/go-gen/tests/cosmwasm_std__StakingQuery.go new file mode 100644 index 000000000..a9667033f --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__StakingQuery.go @@ -0,0 +1,27 @@ +type BondedDenomQuery struct { // does not exist in wasmvm, but is an anonymous struct instead +} + +type AllDelegationsQuery struct { + Delegator string `json:"delegator"` +} + +type DelegationQuery struct { + Delegator string `json:"delegator"` + Validator string `json:"validator"` +} + +type AllValidatorsQuery struct { +} + +type ValidatorQuery struct { + /// Address is the validator's address (e.g. cosmosvaloper1...) + Address string `json:"address"` +} + +type StakingQuery struct { + BondedDenom *BondedDenomQuery `json:"bonded_denom,omitempty"` + AllDelegations *AllDelegationsQuery `json:"all_delegations,omitempty"` + Delegation *DelegationQuery `json:"delegation,omitempty"` + AllValidators *AllValidatorsQuery `json:"all_validators,omitempty"` + Validator *ValidatorQuery `json:"validator,omitempty"` +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__SupplyResponse.go b/packages/go-gen/tests/cosmwasm_std__SupplyResponse.go new file mode 100644 index 000000000..c87e3dc2b --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__SupplyResponse.go @@ -0,0 +1,10 @@ +// SupplyResponse is the expected response to SupplyQuery +type SupplyResponse struct { + Amount Coin `json:"amount"` +} + +// Coin is a string representation of the sdk.Coin type (more portable than sdk.Int) +type Coin struct { + Amount string `json:"amount"` // string encoing of decimal value, eg. "12.3456" + Denom string `json:"denom"` // type, eg. "ATOM" +} \ No newline at end of file diff --git a/packages/go-gen/tests/cosmwasm_std__ValidatorResponse.go b/packages/go-gen/tests/cosmwasm_std__ValidatorResponse.go new file mode 100644 index 000000000..21c24134e --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__ValidatorResponse.go @@ -0,0 +1,14 @@ +// ValidatorResponse is the expected response to ValidatorQuery +type ValidatorResponse struct { + Validator *Validator `json:"validator"` // serializes to `null` when unset which matches Rust's Option::None serialization +} + +type Validator struct { + Address string `json:"address"` + // decimal string, eg "0.02" + Commission string `json:"commission"` + // decimal string, eg "0.02" + MaxChangeRate string `json:"max_change_rate"` + // decimal string, eg "0.02" + MaxCommission string `json:"max_commission"` +} diff --git a/packages/go-gen/tests/cosmwasm_std__WasmQuery.go b/packages/go-gen/tests/cosmwasm_std__WasmQuery.go new file mode 100644 index 000000000..84f3f453c --- /dev/null +++ b/packages/go-gen/tests/cosmwasm_std__WasmQuery.go @@ -0,0 +1,30 @@ + +// SmartQuery response is raw bytes ([]byte) +type SmartQuery struct { + // Bech32 encoded sdk.AccAddress of the contract + ContractAddr string `json:"contract_addr"` + Msg []byte `json:"msg"` +} + +// RawQuery response is raw bytes ([]byte) +type RawQuery struct { + // Bech32 encoded sdk.AccAddress of the contract + ContractAddr string `json:"contract_addr"` + Key []byte `json:"key"` +} + +type ContractInfoQuery struct { + // Bech32 encoded sdk.AccAddress of the contract + ContractAddr string `json:"contract_addr"` +} + +type CodeInfoQuery struct { + CodeID uint64 `json:"code_id"` +} + +type WasmQuery struct { + Smart *SmartQuery `json:"smart,omitempty"` + Raw *RawQuery `json:"raw,omitempty"` + ContractInfo *ContractInfoQuery `json:"contract_info,omitempty"` + CodeInfo *CodeInfoQuery `json:"code_info,omitempty"` +} \ No newline at end of file diff --git a/packages/schema-derive/src/generate_api.rs b/packages/schema-derive/src/generate_api.rs index b275ca561..1306aa613 100644 --- a/packages/schema-derive/src/generate_api.rs +++ b/packages/schema-derive/src/generate_api.rs @@ -15,23 +15,34 @@ pub fn write_api_impl(input: Options) -> Block { { #[cfg(target_arch = "wasm32")] compile_error!("can't compile schema generator for the `wasm32` arch\nhint: are you trying to compile a smart contract without specifying `--lib`?"); - use ::std::env::current_dir; + use ::std::env; use ::std::fs::{create_dir_all, write}; use ::cosmwasm_schema::{remove_schemas, Api, QueryResponses}; - let mut out_dir = current_dir().unwrap(); + let mut out_dir = env::current_dir().unwrap(); out_dir.push("schema"); create_dir_all(&out_dir).unwrap(); remove_schemas(&out_dir).unwrap(); - let path = out_dir.join(concat!(#name, ".json")); - let api = #api_object.render(); + + let path = out_dir.join(concat!(#name, ".json")); + let json = api.to_string().unwrap(); write(&path, json + "\n").unwrap(); println!("Exported the full API as {}", path.to_str().unwrap()); + + let raw_dir = out_dir.join("raw"); + create_dir_all(&raw_dir).unwrap(); + + for (filename, json) in api.to_schema_files().unwrap() { + let path = raw_dir.join(filename); + + write(&path, json + "\n").unwrap(); + println!("Exported {}", path.to_str().unwrap()); + } } } } @@ -189,7 +200,7 @@ impl Parse for Options { }; if let Some((invalid_option, _)) = map.into_iter().next() { - panic!("unknown generate_api option: {}", invalid_option); + panic!("unknown generate_api option: {invalid_option}"); } Ok(Self { diff --git a/packages/schema-derive/src/query_responses.rs b/packages/schema-derive/src/query_responses.rs index 195bb93d7..f3d9b755d 100644 --- a/packages/schema-derive/src/query_responses.rs +++ b/packages/schema-derive/src/query_responses.rs @@ -1,6 +1,8 @@ mod context; -use syn::{parse_quote, Expr, ExprTuple, Generics, ItemEnum, ItemImpl, Type, Variant}; +use syn::{ + parse_quote, Expr, ExprTuple, Generics, ItemEnum, ItemImpl, Type, TypeParamBound, Variant, +}; use self::context::Context; @@ -13,7 +15,11 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> ItemImpl { // Handle generics if the type has any let (_, type_generics, where_clause) = input.generics.split_for_impl(); - let impl_generics = impl_generics(&ctx, &input.generics); + let impl_generics = impl_generics( + &ctx, + &input.generics, + &[parse_quote! {::cosmwasm_schema::QueryResponses}], + ); let subquery_len = subquery_calls.len(); parse_quote! { @@ -24,7 +30,7 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> ItemImpl { let subqueries = [ #( #subquery_calls, )* ]; - ::cosmwasm_schema::combine_subqueries::<#subquery_len, #ident>(subqueries) + ::cosmwasm_schema::combine_subqueries::<#subquery_len, #ident #type_generics>(subqueries) } } } @@ -37,7 +43,7 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> ItemImpl { // Handle generics if the type has any let (_, type_generics, where_clause) = input.generics.split_for_impl(); - let impl_generics = impl_generics(&ctx, &input.generics); + let impl_generics = impl_generics(&ctx, &input.generics, &[]); parse_quote! { #[automatically_derived] @@ -55,7 +61,7 @@ pub fn query_responses_derive_impl(input: ItemEnum) -> ItemImpl { /// Takes a list of generics from the type definition and produces a list of generics /// for the expanded `impl` block, adding trait bounds like `JsonSchema` as appropriate. -fn impl_generics(ctx: &Context, generics: &Generics) -> Generics { +fn impl_generics(ctx: &Context, generics: &Generics, bounds: &[TypeParamBound]) -> Generics { let mut impl_generics = generics.to_owned(); for param in impl_generics.type_params_mut() { // remove the default type if present, as those are invalid in @@ -65,7 +71,8 @@ fn impl_generics(ctx: &Context, generics: &Generics) -> Generics { if !ctx.no_bounds_for.contains(¶m.ident) { param .bounds - .push(parse_quote! {::cosmwasm_schema::schemars::JsonSchema}) + .push(parse_quote! {::cosmwasm_schema::schemars::JsonSchema}); + param.bounds.extend(bounds.to_owned()); } } diff --git a/packages/schema-derive/src/query_responses/context.rs b/packages/schema-derive/src/query_responses/context.rs index ed7f425f1..6c45bd1f2 100644 --- a/packages/schema-derive/src/query_responses/context.rs +++ b/packages/schema-derive/src/query_responses/context.rs @@ -22,7 +22,7 @@ pub fn get_context(input: &ItemEnum) -> Context { if let Meta::List(l) = attr.parse_meta().unwrap() { l.nested } else { - panic!("{} attribute must contain a meta list", ATTR_PATH); + panic!("{ATTR_PATH} attribute must contain a meta list"); } }) .map(|nested_meta| { @@ -55,7 +55,7 @@ pub fn get_context(input: &ItemEnum) -> Context { } } "nested" => ctx.is_nested = true, - path => panic!("unrecognized QueryResponses param: {}", path), + path => panic!("unrecognized QueryResponses param: {path}"), } } diff --git a/packages/schema/Cargo.toml b/packages/schema/Cargo.toml index 7456b9e37..fc2b197cd 100644 --- a/packages/schema/Cargo.toml +++ b/packages/schema/Cargo.toml @@ -12,9 +12,10 @@ cosmwasm-schema-derive = { version = "=1.1.9+0.8.1", path = "../schema-derive" } schemars = "0.8.3" serde = "1.0" serde_json = "1.0.40" -thiserror = "1.0.13" +thiserror = "1.0.26" [dev-dependencies] anyhow = "1.0.57" +cosmwasm-std = { version = "=1.1.9+0.8.1", path = "../std" } semver = "1" tempfile = "3" diff --git a/packages/schema/src/export.rs b/packages/schema/src/export.rs index 2e5c7dcd1..fa26dae9a 100644 --- a/packages/schema/src/export.rs +++ b/packages/schema/src/export.rs @@ -7,7 +7,7 @@ use schemars::schema::RootSchema; use crate::casing::to_snake_case; -// Exports a schema, auto-generating filename based on the metadata title of the generated schema. +/// Exports a schema, auto-generating filename based on the metadata title of the generated schema. pub fn export_schema(schema: &RootSchema, out_dir: &Path) { let title = schema .schema @@ -18,8 +18,8 @@ pub fn export_schema(schema: &RootSchema, out_dir: &Path) { write_schema(schema, out_dir, &title); } -// use this if you want to override the auto-detected name of the object. -// very useful when creating an alias for a type-alias. +/// Use this if you want to override the auto-detected name of the object. +/// very useful when creating an alias for a type-alias. pub fn export_schema_with_title(schema: &RootSchema, out_dir: &Path, title: &str) { let mut schema = schema.clone(); // set the title explicitly on the schema's metadata diff --git a/packages/schema/src/idl.rs b/packages/schema/src/idl.rs index 8297d6f19..80166b7cd 100644 --- a/packages/schema/src/idl.rs +++ b/packages/schema/src/idl.rs @@ -85,6 +85,48 @@ impl JsonApi { serde_json::to_string_pretty(&self).map_err(Into::into) } + pub fn to_schema_files(&self) -> Result, EncodeError> { + let mut result = vec![( + "instantiate.json".to_string(), + serde_json::to_string_pretty(&self.instantiate)?, + )]; + + if let Some(execute) = &self.execute { + result.push(( + "execute.json".to_string(), + serde_json::to_string_pretty(&execute)?, + )); + } + if let Some(query) = &self.query { + result.push(( + "query.json".to_string(), + serde_json::to_string_pretty(&query)?, + )); + } + if let Some(migrate) = &self.migrate { + result.push(( + "migrate.json".to_string(), + serde_json::to_string_pretty(&migrate)?, + )); + } + if let Some(sudo) = &self.sudo { + result.push(( + "sudo.json".to_string(), + serde_json::to_string_pretty(&sudo)?, + )); + } + if let Some(responses) = &self.responses { + for (name, response) in responses { + result.push(( + format!("response_to_{name}.json"), + serde_json::to_string_pretty(&response)?, + )); + } + } + + Ok(result) + } + pub fn to_writer(&self, writer: impl std::io::Write) -> Result<(), EncodeError> { serde_json::to_writer_pretty(writer, self).map_err(Into::into) } diff --git a/packages/schema/src/query_response.rs b/packages/schema/src/query_response.rs index 20cf84e26..85ecc7f3b 100644 --- a/packages/schema/src/query_response.rs +++ b/packages/schema/src/query_response.rs @@ -1,9 +1,6 @@ use std::collections::{BTreeMap, BTreeSet}; -use schemars::{ - schema::{InstanceType, RootSchema, SingleOrVec, SubschemaValidation}, - JsonSchema, -}; +use schemars::{schema::RootSchema, JsonSchema}; use thiserror::Error; pub use cosmwasm_schema_derive::QueryResponses; @@ -69,10 +66,6 @@ pub trait QueryResponses: JsonSchema { fn response_schemas() -> Result, IntegrityError> { let response_schemas = Self::response_schemas_impl(); - let queries: BTreeSet<_> = response_schemas.keys().cloned().collect(); - - check_api_integrity::(queries)?; - Ok(response_schemas) } @@ -95,121 +88,6 @@ pub fn combine_subqueries( map } -/// Returns possible enum variants from `one_of` analysis -fn enum_variants( - subschemas: SubschemaValidation, -) -> Result>, IntegrityError> { - let iter = subschemas - .one_of - .ok_or(IntegrityError::InvalidQueryMsgSchema)? - .into_iter() - .map(|s| { - let s = s.into_object(); - - if let Some(SingleOrVec::Single(ty)) = s.instance_type { - match *ty { - // We'll have an object if the Rust enum variant was C-like or tuple-like - InstanceType::Object => s - .object - .ok_or(IntegrityError::InvalidQueryMsgSchema)? - .required - .into_iter() - .next() - .ok_or(IntegrityError::InvalidQueryMsgSchema), - // We might have a string here if the Rust enum variant was unit-like - InstanceType::String => { - let values = s.enum_values.ok_or(IntegrityError::InvalidQueryMsgSchema)?; - - if values.len() != 1 { - return Err(IntegrityError::InvalidQueryMsgSchema); - } - - values[0] - .as_str() - .map(String::from) - .ok_or(IntegrityError::InvalidQueryMsgSchema) - } - _ => Err(IntegrityError::InvalidQueryMsgSchema), - } - } else { - Err(IntegrityError::InvalidQueryMsgSchema) - } - }); - - Ok(iter) -} - -fn verify_queries( - query_msg: BTreeSet, - responses: BTreeSet, -) -> Result<(), IntegrityError> { - if query_msg != responses { - return Err(IntegrityError::InconsistentQueries { - query_msg, - responses, - }); - } - - Ok(()) -} - -/// `generated_queries` is expected to be a sorted slice here! -fn check_api_integrity( - generated_queries: BTreeSet, -) -> Result<(), IntegrityError> { - let schema = crate::schema_for!(T); - - let subschemas = if let Some(subschemas) = schema.schema.subschemas { - subschemas - } else { - // No subschemas - no resposnes are expected - return verify_queries(BTreeSet::new(), generated_queries); - }; - - let schema_queries = if let Some(any_of) = subschemas.any_of { - // If `any_of` exists, we assume schema is generated from untagged enum - any_of - .into_iter() - .map(|schema| dbg!(schema.into_object())) - .filter_map(|obj| { - if let Some(reference) = obj.reference { - // Subschemas can be hidden behind references - we want to map them to proper - // subschemas in such case - - // Only references to definitions are supported - let reference = match reference.strip_prefix("#/definitions/") { - Some(reference) => reference, - None => { - return Some(Err(IntegrityError::ExternalReference { - reference: reference.to_owned(), - })) - } - }; - - let schema = match schema.definitions.get(reference) { - Some(schema) => schema.clone(), - None => return Some(Err(IntegrityError::InvalidQueryMsgSchema)), - }; - - Ok(schema.into_object().subschemas).transpose() - } else { - Ok(obj.subschemas).transpose() - } - }) - .map(|subschema| enum_variants(*subschema?)) - .collect::, _>>()? - .into_iter() - .flatten() - .collect::>()? - } else { - // If `any_of` is not present, there was no untagged enum on top, we expect normal enum at - // this point - enum_variants(*subschemas)?.collect::>()? - }; - - verify_queries(schema_queries, generated_queries) -} - #[derive(Debug, Error, PartialEq, Eq)] pub enum IntegrityError { #[error("the structure of the QueryMsg schema was unexpected")] @@ -299,18 +177,6 @@ mod tests { } } - #[test] - fn bad_msg_fails() { - let err = BadMsg::response_schemas().unwrap_err(); - assert_eq!( - err, - IntegrityError::InconsistentQueries { - query_msg: BTreeSet::from(["balance-for".to_string()]), - responses: BTreeSet::from(["balance_for".to_string()]) - } - ); - } - #[derive(Debug, JsonSchema)] #[serde(rename_all = "snake_case")] #[allow(dead_code)] diff --git a/packages/schema/src/remove.rs b/packages/schema/src/remove.rs index 2b7c2359e..a5e50f070 100644 --- a/packages/schema/src/remove.rs +++ b/packages/schema/src/remove.rs @@ -28,7 +28,7 @@ pub fn remove_schemas(schemas_dir: &path::Path) -> Result<(), io::Error> { ; for file_path in file_paths { - println!("Removing {:?} …", file_path); + println!("Removing {file_path:?} …"); fs::remove_file(file_path)?; } Ok(()) diff --git a/packages/schema/tests/idl.rs b/packages/schema/tests/idl.rs index d6f00d4f5..2e8ffca3b 100644 --- a/packages/schema/tests/idl.rs +++ b/packages/schema/tests/idl.rs @@ -1,36 +1,32 @@ use std::collections::HashMap; -use cosmwasm_schema::{generate_api, QueryResponses, IDL_VERSION}; -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; +use cosmwasm_schema::{cw_serde, generate_api, QueryResponses, IDL_VERSION}; use serde_json::Value; -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cw_serde] pub struct InstantiateMsg { pub admin: String, pub cap: u128, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum ExecuteMsg { Mint { amount: u128 }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsg { #[returns(u128)] Balance { account: String }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] -#[serde(rename_all = "snake_case")] +#[cw_serde] pub enum SudoMsg { SetAdmin { new_admin: String }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[cw_serde] pub struct MigrateMsg { pub admin: String, pub cap: u128, @@ -133,15 +129,15 @@ fn test_query_responses() { api.get("responses").unwrap().get("balance").unwrap(); } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsgWithGenerics { #[returns(u128)] QueryData { data: T }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsgWithGenericsAndTraitBounds where T: PartialEq, @@ -150,8 +146,8 @@ where QueryData { data: T }, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum QueryMsgWithGenericsAndDefaultType { #[returns(u128)] QueryData { data: T }, @@ -217,7 +213,8 @@ fn test_query_responses_generics_and_trait_bounds() { api.get("responses").unwrap().get("query_data").unwrap(); } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] +#[cw_serde] +#[derive(QueryResponses)] #[serde(untagged)] #[query_responses(nested)] pub enum NestedQueryMsg { @@ -225,8 +222,8 @@ pub enum NestedQueryMsg { Sub(SubQueryMsg1), } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] pub enum SubQueryMsg1 { #[returns(u128)] Variant1 { test: String }, @@ -234,80 +231,45 @@ pub enum SubQueryMsg1 { #[test] fn test_nested_query_responses() { - let api_str = generate_api! { + generate_api! { instantiate: InstantiateMsg, query: NestedQueryMsg, } .render() .to_string() .unwrap(); +} - let api: Value = serde_json::from_str(&api_str).unwrap(); - let queries = api - .get("query") - .unwrap() - .get("anyOf") - .unwrap() - .as_array() - .unwrap(); - let definitions = api.get("query").unwrap().get("definitions").unwrap(); - - // Find the subqueries - assert_eq!(queries.len(), 2); - assert_eq!( - queries[0].get("$ref").unwrap().as_str().unwrap(), - "#/definitions/QueryMsg" - ); - assert_eq!( - queries[1].get("$ref").unwrap().as_str().unwrap(), - "#/definitions/SubQueryMsg1" - ); - let query_msg_queries = definitions - .get("QueryMsg") - .unwrap() - .get("oneOf") - .unwrap() - .as_array() - .unwrap(); - let sub_query_msg_queries = definitions - .get("SubQueryMsg1") - .unwrap() - .get("oneOf") - .unwrap() - .as_array() - .unwrap(); - - // Find "balance" and "variant1" queries in the query schema - assert_eq!( - query_msg_queries[0] - .get("required") - .unwrap() - .get(0) - .unwrap(), - "balance" - ); - assert_eq!( - sub_query_msg_queries[0] - .get("required") - .unwrap() - .get(0) - .unwrap(), - "variant1" - ); +#[cw_serde] +#[derive(QueryResponses)] +#[serde(untagged)] +#[query_responses(nested)] +pub enum NestedQueryMsgGenerics { + /// doc comment + Query(T), + Sub(U), +} - // Find "balance" and "variant1" queries in responses - api.get("responses").unwrap().get("balance").unwrap(); - api.get("responses").unwrap().get("variant1").unwrap(); +#[test] +fn test_nested_query_responses_with_generics() { + generate_api! { + instantiate: InstantiateMsg, + query: NestedQueryMsgGenerics, + } + .render() + .to_string() + .unwrap(); } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] -#[serde(rename_all = "snake_case")] +#[cw_serde] +#[derive(QueryResponses)] enum QueryMsg2 { #[returns(u128)] Balance {}, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema, QueryResponses)] +#[cw_serde] +#[derive(QueryResponses)] #[query_responses(nested)] enum NestedNameCollision { Q1(QueryMsg), diff --git a/packages/std/.cargo/config b/packages/std/.cargo/config index 7d1a066c8..b93207d67 100644 --- a/packages/std/.cargo/config +++ b/packages/std/.cargo/config @@ -1,5 +1,4 @@ [alias] -wasm = "build --release --target wasm32-unknown-unknown" -wasm-debug = "build --target wasm32-unknown-unknown" +wasm = "build --release --lib --target wasm32-unknown-unknown" +wasm-debug = "build --lib --target wasm32-unknown-unknown" unit-test = "test --lib" -schema = "run --example schema" diff --git a/packages/std/Cargo.toml b/packages/std/Cargo.toml index 422a448cb..2f143b44c 100644 --- a/packages/std/Cargo.toml +++ b/packages/std/Cargo.toml @@ -9,7 +9,7 @@ license = "Apache-2.0" readme = "README.md" [package.metadata.docs.rs] -features = ["stargate", "staking", "ibc3"] +features = ["abort", "stargate", "staking", "ibc3", "cosmwasm_1_3"] [features] default = ["iterator", "abort"] @@ -36,21 +36,31 @@ ibc3 = ["stargate"] # This feature makes `BankQuery::Supply` available for the contract to call, but requires # the host blockchain to run CosmWasm `1.1.0` or higher. cosmwasm_1_1 = [] +# This feature makes `GovMsg::VoteWeighted` available for the contract to call, but requires +# the host blockchain to run CosmWasm `1.2.0` or higher. +cosmwasm_1_2 = ["cosmwasm_1_1"] +# This feature makes `BankQuery::DenomMetadata` available for the contract to call, but requires +# the host blockchain to run CosmWasm `1.3.0` or higher. +cosmwasm_1_3 = ["cosmwasm_1_2"] +# Together with the `iterator` feature this enables additional imports for more +# efficient iteration over DB keys or values. +# It also makes `DistributionQuery::{DelegationRewards, DelegationTotalRewards, DelegatorValidators}` +# available for the contract to call. +# It requires the host blockchain to run CosmWasm `1.4.0` or higher. +cosmwasm_1_4 = ["cosmwasm_1_3"] [dependencies] -base64 = "0.13.0" +base64 = "0.21.0" cosmwasm-derive = { path = "../derive", version = "1.1.9+0.8.1" } derivative = "2" forward_ref = "1" hex = "0.4" schemars = "0.8.3" +sha2 = "0.10.3" serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"] } -serde-json-wasm = { version = "0.4.1" } -thiserror = "1.0.13" -# uint 0.9.2 uses edition2021 and this cannot be used from wasmvm now. -# See also https://github.com/CosmWasm/wasmvm/issues/277 -# and https://github.com/CosmWasm/cosmwasm/issues/1204 -uint = "0.9.3" +serde-json-wasm = { version = "0.5.0" } +thiserror = "1.0.26" +bnum = "0.8.0" uuid = { version = "1.0.0", features = ["v5", "serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] @@ -60,4 +70,6 @@ cosmwasm-crypto = { path = "../crypto", version = "1.1.9+0.8.1" } cosmwasm-schema = { path = "../schema" } # The chrono dependency is only used in an example, which Rust compiles for us. If this causes trouble, remove it. chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] } +crc32fast = "1.3.2" hex-literal = "0.3.1" +serde_json = "1.0.81" diff --git a/packages/std/examples/schema.rs b/packages/std/examples/schema.rs deleted file mode 100644 index 0fe2eac96..000000000 --- a/packages/std/examples/schema.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::env::current_dir; -use std::fs::create_dir_all; - -use cosmwasm_schema::{export_schema, export_schema_with_title, remove_schemas, schema_for}; -use cosmwasm_std::{BlockInfo, CosmosMsg, Empty, QueryRequest, Timestamp}; - -fn main() { - let mut out_dir = current_dir().unwrap(); - out_dir.push("schema"); - create_dir_all(&out_dir).unwrap(); - remove_schemas(&out_dir).unwrap(); - - export_schema(&schema_for!(BlockInfo), &out_dir); - export_schema(&schema_for!(Timestamp), &out_dir); - export_schema_with_title(&schema_for!(CosmosMsg), &out_dir, "CosmosMsg"); - export_schema_with_title(&schema_for!(QueryRequest), &out_dir, "QueryRequest"); -} diff --git a/packages/std/schema/block_info.json b/packages/std/schema/block_info.json deleted file mode 100644 index f60c1ecc8..000000000 --- a/packages/std/schema/block_info.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "BlockInfo", - "type": "object", - "required": [ - "chain_id", - "height", - "time" - ], - "properties": { - "chain_id": { - "type": "string" - }, - "height": { - "description": "The height of a block is the number of blocks preceding it in the blockchain.", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "time": { - "description": "Absolute time of the block creation in seconds since the UNIX epoch (00:00:00 on 1970-01-01 UTC).\n\nThe source of this is the [BFT Time](https://github.com/Finschia/ostracon/blob/main/spec/README.md#consensus-protocol), which has the same nanosecond precision as the `Timestamp` type.\n\n# Examples\n\nUsing chrono:\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; # extern crate chrono; use chrono::NaiveDateTime; let seconds = env.block.time.seconds(); let nsecs = env.block.time.subsec_nanos(); let dt = NaiveDateTime::from_timestamp(seconds as i64, nsecs as u32); ```\n\nCreating a simple millisecond-precision timestamp (as used in JavaScript):\n\n``` # use cosmwasm_std::{Addr, BlockInfo, ContractInfo, Env, MessageInfo, Timestamp, TransactionInfo}; # let env = Env { # block: BlockInfo { # height: 12_345, # time: Timestamp::from_nanos(1_571_797_419_879_305_533), # chain_id: \"cosmos-testnet-14002\".to_string(), # }, # transaction: Some(TransactionInfo { index: 3 }), # contract: ContractInfo { # address: Addr::unchecked(\"contract\"), # }, # }; let millis = env.block.time.nanos() / 1_000_000; ```", - "allOf": [ - { - "$ref": "#/definitions/Timestamp" - } - ] - } - }, - "definitions": { - "Timestamp": { - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ] - }, - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/std/schema/cosmos_msg.json b/packages/std/schema/cosmos_msg.json deleted file mode 100644 index 08aae943d..000000000 --- a/packages/std/schema/cosmos_msg.json +++ /dev/null @@ -1,303 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "CosmosMsg", - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankMsg" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmMsg" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankMsg": { - "description": "The message types of the bank module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto.", - "oneOf": [ - { - "description": "Sends native tokens from the contract to the given address.\n\nThis is translated to a [MsgSend](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmos/bank/v1beta1/tx.proto#L19-L28). `from_address` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "send" - ], - "properties": { - "send": { - "type": "object", - "required": [ - "amount", - "to_address" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "to_address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This will burn the given coins from the contract's account. There is no Cosmos SDK message that performs this, but it can be done by calling the bank keeper. Important if a contract controls significant token supply that must be retired.", - "type": "object", - "required": [ - "burn" - ], - "properties": { - "burn": { - "type": "object", - "required": [ - "amount" - ], - "properties": { - "amount": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Coin": { - "type": "object", - "required": [ - "amount", - "denom" - ], - "properties": { - "amount": { - "$ref": "#/definitions/Uint128" - }, - "denom": { - "type": "string" - } - } - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "Uint128": { - "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", - "type": "string" - }, - "WasmMsg": { - "description": "The message types of the wasm module.\n\nSee https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto.", - "oneOf": [ - { - "description": "Dispatches a call to another contract at a known address (with known ABI).\n\nThis is translated to a [MsgExecuteContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L71-L82). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "execute" - ], - "properties": { - "execute": { - "type": "object", - "required": [ - "contract_addr", - "funds", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "msg": { - "description": "msg is the json-encoded ExecuteMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Instantiates a new contracts from previously uploaded Wasm code.\n\nThis is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "instantiate" - ], - "properties": { - "instantiate": { - "type": "object", - "required": [ - "code_id", - "funds", - "label", - "msg" - ], - "properties": { - "admin": { - "type": [ - "string", - "null" - ] - }, - "code_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "funds": { - "type": "array", - "items": { - "$ref": "#/definitions/Coin" - } - }, - "label": { - "description": "A human-readbale label for the contract", - "type": "string" - }, - "msg": { - "description": "msg is the JSON-encoded InstantiateMsg struct (as raw Binary)", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to customize behavior.\n\nOnly the contract admin (as defined in wasmd), if any, is able to make this call.\n\nThis is translated to a [MsgMigrateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L90-L100). `sender` is automatically filled with the current contract's address.", - "type": "object", - "required": [ - "migrate" - ], - "properties": { - "migrate": { - "type": "object", - "required": [ - "contract_addr", - "msg", - "new_code_id" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded MigrateMsg struct that will be passed to the new code", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - }, - "new_code_id": { - "description": "the code_id of the new logic to place in the given contract", - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Sets a new admin (for migrate) on the given contract. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "update_admin" - ], - "properties": { - "update_admin": { - "type": "object", - "required": [ - "admin", - "contract_addr" - ], - "properties": { - "admin": { - "type": "string" - }, - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "Clears the admin on the given contract, so no more migration possible. Fails if this contract is not currently admin of the target contract.", - "type": "object", - "required": [ - "clear_admin" - ], - "properties": { - "clear_admin": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/std/schema/query_request.json b/packages/std/schema/query_request.json deleted file mode 100644 index 2099d32b1..000000000 --- a/packages/std/schema/query_request.json +++ /dev/null @@ -1,187 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "QueryRequest", - "oneOf": [ - { - "type": "object", - "required": [ - "bank" - ], - "properties": { - "bank": { - "$ref": "#/definitions/BankQuery" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "custom" - ], - "properties": { - "custom": { - "$ref": "#/definitions/Empty" - } - }, - "additionalProperties": false - }, - { - "type": "object", - "required": [ - "wasm" - ], - "properties": { - "wasm": { - "$ref": "#/definitions/WasmQuery" - } - }, - "additionalProperties": false - } - ], - "definitions": { - "BankQuery": { - "oneOf": [ - { - "description": "This calls into the native bank module for one denomination Return value is BalanceResponse", - "type": "object", - "required": [ - "balance" - ], - "properties": { - "balance": { - "type": "object", - "required": [ - "address", - "denom" - ], - "properties": { - "address": { - "type": "string" - }, - "denom": { - "type": "string" - } - } - } - }, - "additionalProperties": false - }, - { - "description": "This calls into the native bank module for all denominations. Note that this may be much more expensive than Balance and should be avoided if possible. Return value is AllBalanceResponse.", - "type": "object", - "required": [ - "all_balances" - ], - "properties": { - "all_balances": { - "type": "object", - "required": [ - "address" - ], - "properties": { - "address": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - }, - "Binary": { - "description": "Binary is a wrapper around Vec to add base64 de/serialization with serde. It also adds some helper methods to help encode inline.\n\nThis is only needed as serde-json-{core,wasm} has a horrible encoding for Vec. See also .", - "type": "string" - }, - "Empty": { - "description": "An empty struct that serves as a placeholder in different places, such as contracts that don't set a custom message.\n\nIt is designed to be expressable in correct JSON and JSON Schema but contains no meaningful data. Previously we used enums without cases, but those cannot represented as valid JSON Schema (https://github.com/CosmWasm/cosmwasm/issues/451)", - "type": "object" - }, - "WasmQuery": { - "oneOf": [ - { - "description": "this queries the public API of another contract at a known address (with known ABI) Return value is whatever the contract returns (caller should know), wrapped in a ContractResult that is JSON encoded.", - "type": "object", - "required": [ - "smart" - ], - "properties": { - "smart": { - "type": "object", - "required": [ - "contract_addr", - "msg" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "msg": { - "description": "msg is the json-encoded QueryMsg struct", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "this queries the raw kv-store of the contract. returns the raw, unparsed data stored at that key, which may be an empty vector if not present", - "type": "object", - "required": [ - "raw" - ], - "properties": { - "raw": { - "type": "object", - "required": [ - "contract_addr", - "key" - ], - "properties": { - "contract_addr": { - "type": "string" - }, - "key": { - "description": "Key is the raw key used in the contracts Storage", - "allOf": [ - { - "$ref": "#/definitions/Binary" - } - ] - } - } - } - }, - "additionalProperties": false - }, - { - "description": "returns a ContractInfoResponse with metadata on the contract from the runtime", - "type": "object", - "required": [ - "contract_info" - ], - "properties": { - "contract_info": { - "type": "object", - "required": [ - "contract_addr" - ], - "properties": { - "contract_addr": { - "type": "string" - } - } - } - }, - "additionalProperties": false - } - ] - } - } -} diff --git a/packages/std/schema/timestamp.json b/packages/std/schema/timestamp.json deleted file mode 100644 index 6dd9971a1..000000000 --- a/packages/std/schema/timestamp.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Timestamp", - "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", - "allOf": [ - { - "$ref": "#/definitions/Uint64" - } - ], - "definitions": { - "Uint64": { - "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", - "type": "string" - } - } -} diff --git a/packages/std/src/addresses.rs b/packages/std/src/addresses.rs index ef03d5ab6..39bc8bc06 100644 --- a/packages/std/src/addresses.rs +++ b/packages/std/src/addresses.rs @@ -1,10 +1,15 @@ +use alloc::borrow::Cow; +use core::fmt; +use core::ops::Deref; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::borrow::Cow; -use std::fmt; -use std::ops::Deref; +use sha2::{ + digest::{Digest, Update}, + Sha256, +}; +use thiserror::Error; -use crate::{binary::Binary, HexBinary}; +use crate::{binary::Binary, forward_ref_partial_eq, HexBinary}; /// A human readable address. /// @@ -27,6 +32,8 @@ use crate::{binary::Binary, HexBinary}; )] pub struct Addr(String); +forward_ref_partial_eq!(Addr, Addr); + impl Addr { /// Creates a new `Addr` instance from the given input without checking the validity /// of the input. Since `Addr` must always contain valid addresses, the caller is @@ -81,6 +88,9 @@ impl AsRef for Addr { } /// Implement `Addr == &str` +/// +/// Deprecated. This comparison unsafe. Convert both sides to Addr first. +/// Will be removed soon: https://github.com/CosmWasm/cosmwasm/issues/1669 impl PartialEq<&str> for Addr { fn eq(&self, rhs: &&str) -> bool { self.0 == *rhs @@ -88,6 +98,9 @@ impl PartialEq<&str> for Addr { } /// Implement `&str == Addr` +/// +/// Deprecated. This comparison unsafe. Convert both sides to Addr first. +/// Will be removed soon: https://github.com/CosmWasm/cosmwasm/issues/1669 impl PartialEq for &str { fn eq(&self, rhs: &Addr) -> bool { *self == rhs.0 @@ -95,6 +108,9 @@ impl PartialEq for &str { } /// Implement `Addr == String` +/// +/// Deprecated. This comparison unsafe. Convert both sides to Addr first. +/// Will be removed soon: https://github.com/CosmWasm/cosmwasm/issues/1669 impl PartialEq for Addr { fn eq(&self, rhs: &String) -> bool { &self.0 == rhs @@ -102,6 +118,9 @@ impl PartialEq for Addr { } /// Implement `String == Addr` +/// +/// Deprecated. This comparison unsafe. Convert both sides to Addr first. +/// Will be removed soon: https://github.com/CosmWasm/cosmwasm/issues/1669 impl PartialEq for String { fn eq(&self, rhs: &Addr) -> bool { self == &rhs.0 @@ -265,18 +284,123 @@ impl CanonicalAddr { impl fmt::Display for CanonicalAddr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { for byte in self.0.as_slice() { - write!(f, "{:02X}", byte)?; + write!(f, "{byte:02X}")?; } Ok(()) } } +#[derive(Error, Debug, PartialEq, Eq)] +pub enum Instantiate2AddressError { + /// Checksum must be 32 bytes + InvalidChecksumLength, + /// Salt must be between 1 and 64 bytes + InvalidSaltLength, +} + +impl fmt::Display for Instantiate2AddressError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Instantiate2AddressError::InvalidChecksumLength => write!(f, "invalid checksum length"), + Instantiate2AddressError::InvalidSaltLength => write!(f, "invalid salt length"), + } + } +} + +/// Creates a contract address using the predictable address format introduced with +/// wasmd 0.29. When using instantiate2, this is a way to precompute the address. +/// When using instantiate, the contract address will use a different algorithm and +/// cannot be pre-computed as it contains inputs from the chain's state at the time of +/// message execution. +/// +/// The predicable address format of instantiate2 is stable. But bear in mind this is +/// a powerful tool that requires multiple software components to work together smoothly. +/// It should be used carefully and tested thoroughly to avoid the loss of funds. +/// +/// This method operates on [`CanonicalAddr`] to be implemented without chain interaction. +/// The typical usage looks like this: +/// +/// ``` +/// # use cosmwasm_std::{ +/// # HexBinary, +/// # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, +/// # Response, QueryResponse, +/// # }; +/// # type ExecuteMsg = (); +/// use cosmwasm_std::instantiate2_address; +/// +/// #[entry_point] +/// pub fn execute( +/// deps: DepsMut, +/// env: Env, +/// info: MessageInfo, +/// msg: ExecuteMsg, +/// ) -> Result { +/// let canonical_creator = deps.api.addr_canonicalize(env.contract.address.as_str())?; +/// let checksum = HexBinary::from_hex("9af782a3a1bcbcd22dbb6a45c751551d9af782a3a1bcbcd22dbb6a45c751551d")?; +/// let salt = b"instance 1231"; +/// let canonical_addr = instantiate2_address(&checksum, &canonical_creator, salt) +/// .map_err(|_| StdError::generic_err("Could not calculate addr"))?; +/// let addr = deps.api.addr_humanize(&canonical_addr)?; +/// +/// # Ok(Default::default()) +/// } +/// ``` +pub fn instantiate2_address( + checksum: &[u8], + creator: &CanonicalAddr, + salt: &[u8], +) -> Result { + // Non-empty msg values are discouraged. + // See https://medium.com/cosmwasm/dev-note-3-limitations-of-instantiate2-and-how-to-deal-with-them-a3f946874230. + let msg = b""; + instantiate2_address_impl(checksum, creator, salt, msg) +} + +/// The instantiate2 address derivation implementation. This API is used for +/// testing puposes only. The `msg` field is discouraged and should not be used. +/// Use [`instantiate2_address`]. +#[doc(hidden)] +fn instantiate2_address_impl( + checksum: &[u8], + creator: &CanonicalAddr, + salt: &[u8], + msg: &[u8], +) -> Result { + if checksum.len() != 32 { + return Err(Instantiate2AddressError::InvalidChecksumLength); + } + + if salt.is_empty() || salt.len() > 64 { + return Err(Instantiate2AddressError::InvalidSaltLength); + }; + + let mut key = Vec::::new(); + key.extend_from_slice(b"wasm\0"); + key.extend_from_slice(&(checksum.len() as u64).to_be_bytes()); + key.extend_from_slice(checksum); + key.extend_from_slice(&(creator.len() as u64).to_be_bytes()); + key.extend_from_slice(creator); + key.extend_from_slice(&(salt.len() as u64).to_be_bytes()); + key.extend_from_slice(salt); + key.extend_from_slice(&(msg.len() as u64).to_be_bytes()); + key.extend_from_slice(msg); + let address_data = hash("module", &key); + Ok(address_data.into()) +} + +/// The "Basic Address" Hash from +/// https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/docs/architecture/adr-028-public-key-addresses.md +fn hash(ty: &str, key: &[u8]) -> Vec { + let inner = Sha256::digest(ty.as_bytes()); + Sha256::new().chain(inner).chain(key).finalize().to_vec() +} + #[cfg(test)] mod tests { use super::*; - use std::collections::hash_map::DefaultHasher; - use std::collections::HashSet; - use std::hash::{Hash, Hasher}; + use crate::{assert_hash_works, HexBinary}; + use hex_literal::hex; #[test] fn addr_unchecked_works() { @@ -305,7 +429,7 @@ mod tests { #[test] fn addr_implements_display() { let addr = Addr::unchecked("cos934gh9034hg04g0h134"); - let embedded = format!("Address: {}", addr); + let embedded = format!("Address: {addr}"); assert_eq!(embedded, "Address: cos934gh9034hg04g0h134"); assert_eq!(addr.to_string(), "cos934gh9034hg04g0h134"); } @@ -316,24 +440,34 @@ mod tests { assert_eq!(addr.as_ref(), "literal-string"); } + // Please note that this will be removed soon + // https://github.com/CosmWasm/cosmwasm/issues/1669 #[test] - fn addr_implements_partial_eq_with_str() { + fn addr_implements_partial_eq_with_str_and_string() { let addr = Addr::unchecked("cos934gh9034hg04g0h134"); // `Addr == &str` assert_eq!(addr, "cos934gh9034hg04g0h134"); // `&str == Addr` assert_eq!("cos934gh9034hg04g0h134", addr); + // `Addr == String` + assert_eq!(addr, String::from("cos934gh9034hg04g0h134")); + // `String == Addr` + assert_eq!(String::from("cos934gh9034hg04g0h134"), addr); } #[test] - fn addr_implements_partial_eq_with_string() { + fn addr_implements_partial_eq_addr_ref() { let addr = Addr::unchecked("cos934gh9034hg04g0h134"); + let addr_ref = &addr; + let addr_ref2 = &addr; - // `Addr == String` - assert_eq!(addr, String::from("cos934gh9034hg04g0h134")); - // `String == Addr` - assert_eq!(String::from("cos934gh9034hg04g0h134"), addr); + // `Addr == &Addr` + assert_eq!(addr, addr_ref); + // `&Addr == Addr` + assert_eq!(addr_ref, addr); + // `&Addr == &Addr` + assert_eq!(addr_ref, addr_ref2); } #[test] @@ -492,7 +626,7 @@ mod tests { 0xff, ]; let address = CanonicalAddr::from(bytes); - let embedded = format!("Address: {}", address); + let embedded = format!("Address: {address}"); assert_eq!(embedded, "Address: 1203AB00FF"); assert_eq!(address.to_string(), "1203AB00FF"); } @@ -512,43 +646,13 @@ mod tests { assert_eq!(canonical_addr_slice, &[0u8, 187, 61, 11, 250, 0]); } + /// Tests that `CanonicalAddr` implements `EQ` and `Hash` correctly and thus + /// can be used with hash maps and sets. #[test] - fn canonical_addr_implements_hash() { - let alice1 = CanonicalAddr::from([0, 187, 61, 11, 250, 0]); - let mut hasher = DefaultHasher::new(); - alice1.hash(&mut hasher); - let alice1_hash = hasher.finish(); - - let alice2 = CanonicalAddr::from([0, 187, 61, 11, 250, 0]); - let mut hasher = DefaultHasher::new(); - alice2.hash(&mut hasher); - let alice2_hash = hasher.finish(); - - let bob = CanonicalAddr::from([16, 21, 33, 0, 255, 9]); - let mut hasher = DefaultHasher::new(); - bob.hash(&mut hasher); - let bob_hash = hasher.finish(); - - assert_eq!(alice1_hash, alice2_hash); - assert_ne!(alice1_hash, bob_hash); - } - - /// This requires Hash and Eq to be implemented - #[test] - fn canonical_addr_can_be_used_in_hash_set() { - let alice1 = CanonicalAddr::from([0, 187, 61, 11, 250, 0]); - let alice2 = CanonicalAddr::from([0, 187, 61, 11, 250, 0]); + fn canonical_addr_implements_hash_eq() { + let alice = CanonicalAddr::from([0, 187, 61, 11, 250, 0]); let bob = CanonicalAddr::from([16, 21, 33, 0, 255, 9]); - - let mut set = HashSet::new(); - set.insert(alice1.clone()); - set.insert(alice2.clone()); - set.insert(bob.clone()); - assert_eq!(set.len(), 2); - - let set1 = HashSet::::from_iter(vec![bob.clone(), alice1.clone()]); - let set2 = HashSet::from_iter(vec![alice1, alice2, bob]); - assert_eq!(set1, set2); + assert_hash_works!(alice, bob); } // helper to show we can handle Addr and &Addr equally @@ -567,4 +671,161 @@ mod tests { // pass by value assert_eq!(value, &flexible(addr)); } + + #[test] + fn instantiate2_address_impl_works() { + let checksum1 = + HexBinary::from_hex("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5") + .unwrap(); + let creator1 = CanonicalAddr::from(hex!("9999999999aaaaaaaaaabbbbbbbbbbcccccccccc")); + let salt1 = hex!("61"); + let salt2 = hex!("aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae"); + let msg1: &[u8] = b""; + let msg2: &[u8] = b"{}"; + let msg3: &[u8] = b"{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}"; + + // No msg + let expected = CanonicalAddr::from(hex!( + "5e865d3e45ad3e961f77fd77d46543417ced44d924dc3e079b5415ff6775f847" + )); + assert_eq!( + instantiate2_address_impl(&checksum1, &creator1, &salt1, msg1).unwrap(), + expected + ); + + // With msg + let expected = CanonicalAddr::from(hex!( + "0995499608947a5281e2c7ebd71bdb26a1ad981946dad57f6c4d3ee35de77835" + )); + assert_eq!( + instantiate2_address_impl(&checksum1, &creator1, &salt1, msg2).unwrap(), + expected + ); + + // Long msg + let expected = CanonicalAddr::from(hex!( + "83326e554723b15bac664ceabc8a5887e27003abe9fbd992af8c7bcea4745167" + )); + assert_eq!( + instantiate2_address_impl(&checksum1, &creator1, &salt1, msg3).unwrap(), + expected + ); + + // Long salt + let expected = CanonicalAddr::from(hex!( + "9384c6248c0bb171e306fd7da0993ec1e20eba006452a3a9e078883eb3594564" + )); + assert_eq!( + instantiate2_address_impl(&checksum1, &creator1, &salt2, b"").unwrap(), + expected + ); + + // Salt too short or too long + let empty = Vec::::new(); + assert!(matches!( + instantiate2_address_impl(&checksum1, &creator1, &empty, b"").unwrap_err(), + Instantiate2AddressError::InvalidSaltLength + )); + let too_long = vec![0x11; 65]; + assert!(matches!( + instantiate2_address_impl(&checksum1, &creator1, &too_long, b"").unwrap_err(), + Instantiate2AddressError::InvalidSaltLength + )); + + // invalid checksum length + let broken_cs = hex!("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2"); + assert!(matches!( + instantiate2_address_impl(&broken_cs, &creator1, &salt1, b"").unwrap_err(), + Instantiate2AddressError::InvalidChecksumLength + )); + let broken_cs = hex!(""); + assert!(matches!( + instantiate2_address_impl(&broken_cs, &creator1, &salt1, b"").unwrap_err(), + Instantiate2AddressError::InvalidChecksumLength + )); + let broken_cs = hex!("13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2aaaa"); + assert!(matches!( + instantiate2_address_impl(&broken_cs, &creator1, &salt1, b"").unwrap_err(), + Instantiate2AddressError::InvalidChecksumLength + )); + } + + #[test] + fn instantiate2_address_impl_works_for_cosmjs_testvectors() { + // Test data from https://github.com/cosmos/cosmjs/pull/1253 + const COSMOS_ED25519_TESTS_JSON: &str = "./testdata/instantiate2_addresses.json"; + + #[derive(Deserialize, Debug)] + #[serde(rename_all = "camelCase")] + #[allow(dead_code)] + struct In { + checksum: HexBinary, + creator: String, + creator_data: HexBinary, + salt: HexBinary, + msg: Option, + } + + #[derive(Deserialize, Debug)] + #[serde(rename_all = "camelCase")] + #[allow(dead_code)] + struct Intermediate { + key: HexBinary, + address_data: HexBinary, + } + + #[derive(Deserialize, Debug)] + #[serde(rename_all = "camelCase")] + #[allow(dead_code)] + struct Out { + address: String, + } + + #[derive(Deserialize, Debug)] + #[allow(dead_code)] + struct Row { + #[serde(rename = "in")] + input: In, + intermediate: Intermediate, + out: Out, + } + + fn read_tests() -> Vec { + use std::fs::File; + use std::io::BufReader; + + // Open the file in read-only mode with buffer. + let file = File::open(COSMOS_ED25519_TESTS_JSON).unwrap(); + let reader = BufReader::new(file); + + serde_json::from_reader(reader).unwrap() + } + + for Row { + input, + intermediate, + out: _, + } in read_tests() + { + let msg = input.msg.map(|msg| msg.into_bytes()).unwrap_or_default(); + let addr = instantiate2_address_impl( + &input.checksum, + &input.creator_data.into(), + &input.salt, + &msg, + ) + .unwrap(); + assert_eq!(addr, intermediate.address_data); + } + } + + #[test] + fn hash_works() { + // Test case from https://github.com/cosmos/cosmos-sdk/blob/v0.47.0-alpha1/types/address/hash_test.go#L19-L24 + let expected = [ + 195, 235, 23, 251, 9, 99, 177, 195, 81, 122, 182, 124, 36, 113, 245, 156, 76, 188, 221, + 83, 181, 192, 227, 82, 100, 177, 161, 133, 240, 160, 5, 25, + ]; + assert_eq!(hash("1", &[1]), expected); + } } diff --git a/packages/std/src/assertions.rs b/packages/std/src/assertions.rs index bc67312b7..fb02e26ab 100644 --- a/packages/std/src/assertions.rs +++ b/packages/std/src/assertions.rs @@ -30,7 +30,7 @@ macro_rules! ensure { ($cond:expr, $e:expr) => { if !($cond) { - return Err(std::convert::From::from($e)); + return Err(core::convert::From::from($e)); } }; } @@ -68,7 +68,7 @@ macro_rules! ensure_eq { ($a:expr, $b:expr, $e:expr) => { // Not implemented via `ensure!` because the caller would have to import both macros. if !($a == $b) { - return Err(std::convert::From::from($e)); + return Err(core::convert::From::from($e)); } }; } @@ -100,7 +100,7 @@ macro_rules! ensure_ne { ($a:expr, $b:expr, $e:expr) => { // Not implemented via `ensure!` because the caller would have to import both macros. if !($a != $b) { - return Err(std::convert::From::from($e)); + return Err(core::convert::From::from($e)); } }; } diff --git a/packages/std/src/binary.rs b/packages/std/src/binary.rs index 4ee4b253f..ec5954aeb 100644 --- a/packages/std/src/binary.rs +++ b/packages/std/src/binary.rs @@ -1,6 +1,7 @@ -use std::fmt; -use std::ops::Deref; +use core::fmt; +use core::ops::Deref; +use base64::engine::{Engine, GeneralPurpose}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; @@ -15,17 +16,29 @@ use crate::errors::{StdError, StdResult}; pub struct Binary(#[schemars(with = "String")] pub Vec); impl Binary { + /// Base64 encoding engine used in conversion to/from base64. + /// + /// The engine adds padding when encoding and accepts strings with or + /// without padding when decoding. + const B64_ENGINE: GeneralPurpose = GeneralPurpose::new( + &base64::alphabet::STANDARD, + base64::engine::GeneralPurposeConfig::new() + .with_decode_padding_mode(base64::engine::DecodePaddingMode::Indifferent), + ); + /// take an (untrusted) string and decode it into bytes. /// fails if it is not valid base64 pub fn from_base64(encoded: &str) -> StdResult { - let binary = base64::decode(encoded).map_err(StdError::invalid_base64)?; - Ok(Binary(binary)) + Self::B64_ENGINE + .decode(encoded.as_bytes()) + .map(Binary::from) + .map_err(StdError::invalid_base64) } /// encode to base64 string (guaranteed to be success as we control the data inside). /// this returns normalized form (with trailing = if needed) pub fn to_base64(&self) -> String { - base64::encode(&self.0) + Self::B64_ENGINE.encode(self.0.as_slice()) } pub fn as_slice(&self) -> &[u8] { @@ -76,19 +89,13 @@ impl fmt::Debug for Binary { // but with a custom implementation to avoid the need for an intemediate hex string. write!(f, "Binary(")?; for byte in self.0.iter() { - write!(f, "{:02x}", byte)?; + write!(f, "{byte:02x}")?; } write!(f, ")")?; Ok(()) } } -impl From<&[u8]> for Binary { - fn from(binary: &[u8]) -> Self { - Self(binary.to_vec()) - } -} - /// Just like Vec, Binary is a smart pointer to [u8]. /// This implements `*binary` for us and allows us to /// do `&*binary`, returning a `&[u8]` from a `&Binary`. @@ -102,14 +109,27 @@ impl Deref for Binary { } } -// Reference +impl AsRef<[u8]> for Binary { + fn as_ref(&self) -> &[u8] { + self.as_slice() + } +} + +// Slice +impl From<&[u8]> for Binary { + fn from(binary: &[u8]) -> Self { + Self(binary.to_vec()) + } +} + +// Array reference impl From<&[u8; LENGTH]> for Binary { fn from(source: &[u8; LENGTH]) -> Self { Self(source.to_vec()) } } -// Owned +// Owned array impl From<[u8; LENGTH]> for Binary { fn from(source: [u8; LENGTH]) -> Self { Self(source.into()) @@ -128,7 +148,7 @@ impl From for Vec { } } -/// Implement `encoding::Binary == std::vec::Vec` +/// Implement `encoding::Binary == alloc::vec::Vec` impl PartialEq> for Binary { fn eq(&self, rhs: &Vec) -> bool { // Use Vec == Vec @@ -136,7 +156,7 @@ impl PartialEq> for Binary { } } -/// Implement `std::vec::Vec == encoding::Binary` +/// Implement `alloc::vec::Vec == encoding::Binary` impl PartialEq for Vec { fn eq(&self, rhs: &Binary) -> bool { // Use Vec == Vec @@ -223,7 +243,7 @@ impl<'de> de::Visitor<'de> for Base64Visitor { { match Binary::from_base64(v) { Ok(binary) => Ok(binary), - Err(_) => Err(E::custom(format!("invalid base64: {}", v))), + Err(_) => Err(E::custom(format!("invalid base64: {v}"))), } } } @@ -231,29 +251,9 @@ impl<'de> de::Visitor<'de> for Base64Visitor { #[cfg(test)] mod tests { use super::*; + use crate::assert_hash_works; use crate::errors::StdError; use crate::serde::{from_slice, to_vec}; - use std::collections::hash_map::DefaultHasher; - use std::collections::HashSet; - use std::hash::{Hash, Hasher}; - - #[test] - fn encode_decode() { - let binary: &[u8] = b"hello"; - let encoded = Binary::from(binary).to_base64(); - assert_eq!(8, encoded.len()); - let decoded = Binary::from_base64(&encoded).unwrap(); - assert_eq!(binary, decoded.as_slice()); - } - - #[test] - fn encode_decode_non_ascii() { - let binary = vec![12u8, 187, 0, 17, 250, 1]; - let encoded = Binary(binary.clone()).to_base64(); - assert_eq!(8, encoded.len()); - let decoded = Binary::from_base64(&encoded).unwrap(); - assert_eq!(binary.deref(), decoded.deref()); - } #[test] fn to_array_works() { @@ -277,7 +277,7 @@ mod tests { assert_eq!(expected, 8); assert_eq!(actual, 3); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } // long array (32 bytes) @@ -307,29 +307,32 @@ mod tests { } #[test] - fn from_valid_string() { - let valid_base64 = "cmFuZG9taVo="; - let binary = Binary::from_base64(valid_base64).unwrap(); - assert_eq!(b"randomiZ", binary.as_slice()); - } - - // this accepts input without a trailing = but outputs normal form - #[test] - fn from_shortened_string() { - let short = "cmFuZG9taVo"; - let long = "cmFuZG9taVo="; - let binary = Binary::from_base64(short).unwrap(); - assert_eq!(b"randomiZ", binary.as_slice()); - assert_eq!(long, binary.to_base64()); + fn test_base64_encoding_success() { + for (value, encoded, encoded_no_pad) in [ + (&b""[..], "", ""), + (&b"hello"[..], "aGVsbG8=", "aGVsbG8"), + (&b"\x0C\xBB\x00\x11\xFA\x01"[..], "DLsAEfoB", "DLsAEfoB"), + (&b"rand"[..], "cmFuZA==", "cmFuZA"), + (&b"rand"[..], "cmFuZA==", "cmFuZA="), + (&b"randomiZ"[..], "cmFuZG9taVo=", "cmFuZG9taVo"), + ] { + let value = Binary::from(value); + assert_eq!(encoded, value.to_base64()); + assert_eq!(Ok(value.clone()), Binary::from_base64(encoded)); + assert_eq!(Ok(value.clone()), Binary::from_base64(encoded_no_pad)); + } } #[test] - fn from_invalid_string() { - let invalid_base64 = "cm%uZG9taVo"; - let res = Binary::from_base64(invalid_base64); - match res.unwrap_err() { - StdError::InvalidBase64 { msg, .. } => assert_eq!(msg, "Invalid byte 37, offset 2."), - _ => panic!("Unexpected error type"), + fn test_base64_encoding_error() { + for (invalid_base64, want) in [ + ("cm%uZG9taVo", "Invalid byte 37, offset 2."), + ("cmFuZ", "Encoded text cannot have a 6-bit remainder."), + ] { + match Binary::from_base64(invalid_base64) { + Err(StdError::InvalidBase64 { msg }) => assert_eq!(want, msg), + result => panic!("Unexpected result: {result:?}"), + } } } @@ -476,11 +479,11 @@ mod tests { fn binary_implements_debug() { // Some data let binary = Binary(vec![0x07, 0x35, 0xAA, 0xcb, 0x00, 0xff]); - assert_eq!(format!("{:?}", binary), "Binary(0735aacb00ff)",); + assert_eq!(format!("{binary:?}"), "Binary(0735aacb00ff)",); // Empty let binary = Binary(vec![]); - assert_eq!(format!("{:?}", binary), "Binary()",); + assert_eq!(format!("{binary:?}"), "Binary()",); } #[test] @@ -497,42 +500,20 @@ mod tests { } #[test] - fn binary_implements_hash() { - let a1 = Binary::from([0, 187, 61, 11, 250, 0]); - let mut hasher = DefaultHasher::new(); - a1.hash(&mut hasher); - let a1_hash = hasher.finish(); - - let a2 = Binary::from([0, 187, 61, 11, 250, 0]); - let mut hasher = DefaultHasher::new(); - a2.hash(&mut hasher); - let a2_hash = hasher.finish(); - - let b = Binary::from([16, 21, 33, 0, 255, 9]); - let mut hasher = DefaultHasher::new(); - b.hash(&mut hasher); - let b_hash = hasher.finish(); - - assert_eq!(a1_hash, a2_hash); - assert_ne!(a1_hash, b_hash); + fn binary_implements_as_ref() { + let want = &[7u8, 35, 49, 101, 0, 255]; + let data = Binary(want.to_vec()); + assert_eq!(want, AsRef::<[u8]>::as_ref(&data)); + assert_eq!(want, AsRef::<[u8]>::as_ref(&&data)); } - /// This requires Hash and Eq to be implemented + /// Tests that `Binary` implements `EQ` and `Hash` correctly and thus can be + /// used with hash maps and sets. #[test] - fn binary_can_be_used_in_hash_set() { - let a1 = Binary::from([0, 187, 61, 11, 250, 0]); - let a2 = Binary::from([0, 187, 61, 11, 250, 0]); + fn binary_implements_hash_eq() { + let a = Binary::from([0, 187, 61, 11, 250, 0]); let b = Binary::from([16, 21, 33, 0, 255, 9]); - - let mut set = HashSet::new(); - set.insert(a1.clone()); - set.insert(a2.clone()); - set.insert(b.clone()); - assert_eq!(set.len(), 2); - - let set1 = HashSet::::from_iter(vec![b.clone(), a1.clone()]); - let set2 = HashSet::from_iter(vec![a1, a2, b]); - assert_eq!(set1, set2); + assert_hash_works!(a, b); } #[test] diff --git a/packages/std/src/coin.rs b/packages/std/src/coin.rs index 289911dee..1a2848018 100644 --- a/packages/std/src/coin.rs +++ b/packages/std/src/coin.rs @@ -1,10 +1,10 @@ +use core::{fmt, str::FromStr}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::fmt; -use crate::math::Uint128; +use crate::{errors::CoinFromStrError, math::Uint128}; -#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Default, PartialEq, Eq, JsonSchema)] pub struct Coin { pub denom: String, pub amount: Uint128, @@ -19,6 +19,32 @@ impl Coin { } } +impl fmt::Debug for Coin { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Coin {{ {} \"{}\" }}", self.amount, self.denom) + } +} + +impl FromStr for Coin { + type Err = CoinFromStrError; + + fn from_str(s: &str) -> Result { + let pos = s + .find(|c: char| !c.is_ascii_digit()) + .ok_or(CoinFromStrError::MissingDenom)?; + let (amount, denom) = s.split_at(pos); + + if amount.is_empty() { + return Err(CoinFromStrError::MissingAmount); + } + + Ok(Coin { + amount: amount.parse::()?.into(), + denom: denom.to_string(), + }) + } +} + impl fmt::Display for Coin { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // We use the formatting without a space between amount and denom, @@ -94,7 +120,7 @@ mod tests { denom: "ucosm".to_string(), }; - let embedded = format!("Amount: {}", a); + let embedded = format!("Amount: {a}"); assert_eq!(embedded, "Amount: 123ucosm"); assert_eq!(a.to_string(), "123ucosm"); } @@ -166,4 +192,59 @@ mod tests { // less than same type assert!(has_coins(&wallet, &coin(777, "ETH"))); } + + #[test] + fn parse_coin() { + let expected = Coin::new(123, "ucosm"); + assert_eq!("123ucosm".parse::().unwrap(), expected); + // leading zeroes should be ignored + assert_eq!("00123ucosm".parse::().unwrap(), expected); + // 0 amount parses correctly + assert_eq!("0ucosm".parse::().unwrap(), Coin::new(0, "ucosm")); + // ibc denom should work + let ibc_str = "11111ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2"; + let ibc_coin = Coin::new( + 11111, + "ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2", + ); + assert_eq!(ibc_str.parse::().unwrap(), ibc_coin); + + // error cases + assert_eq!( + Coin::from_str("123").unwrap_err(), + CoinFromStrError::MissingDenom + ); + assert_eq!( + Coin::from_str("ucosm").unwrap_err(), // no amount + CoinFromStrError::MissingAmount + ); + assert_eq!( + Coin::from_str("-123ucosm").unwrap_err(), // negative amount + CoinFromStrError::MissingAmount + ); + assert_eq!( + Coin::from_str("").unwrap_err(), // empty input + CoinFromStrError::MissingDenom + ); + assert_eq!( + Coin::from_str(" 1ucosm").unwrap_err(), // unsupported whitespace + CoinFromStrError::MissingAmount + ); + assert_eq!( + Coin::from_str("�1ucosm").unwrap_err(), // other broken data + CoinFromStrError::MissingAmount + ); + assert_eq!( + Coin::from_str("340282366920938463463374607431768211456ucosm") + .unwrap_err() + .to_string(), + "Invalid amount: number too large to fit in target type" + ); + } + + #[test] + fn debug_coin() { + let coin = Coin::new(123, "ucosm"); + assert_eq!(format!("{coin:?}"), r#"Coin { 123 "ucosm" }"#); + } } diff --git a/packages/std/src/coins.rs b/packages/std/src/coins.rs new file mode 100644 index 000000000..08171a142 --- /dev/null +++ b/packages/std/src/coins.rs @@ -0,0 +1,535 @@ +use alloc::collections::BTreeMap; +use core::fmt; +use core::str::FromStr; + +use crate::{ + errors::CoinsError, Coin, OverflowError, OverflowOperation, StdError, StdResult, Uint128, +}; + +/// A collection of coins, similar to Cosmos SDK's `sdk.Coins` struct. +/// +/// Differently from `sdk.Coins`, which is a vector of `sdk.Coin`, here we +/// implement Coins as a BTreeMap that maps from coin denoms to `Coin`. +/// This has a number of advantages: +/// +/// - coins are naturally sorted alphabetically by denom +/// - duplicate denoms are automatically removed +/// - cheaper for searching/inserting/deleting: O(log(n)) compared to O(n) +#[derive(Clone, Default, Debug, PartialEq, Eq)] +pub struct Coins(BTreeMap); + +/// Casting a Vec to Coins. +/// The Vec can be out of order, but must not contain duplicate denoms. +/// If you want to sum up duplicates, create an empty instance using `Coins::default` and +/// use `Coins::add` to add your coins. +impl TryFrom> for Coins { + type Error = CoinsError; + + fn try_from(vec: Vec) -> Result { + let mut map = BTreeMap::new(); + for coin in vec { + if coin.amount.is_zero() { + continue; + } + + // if the insertion returns a previous value, we have a duplicate denom + if map.insert(coin.denom.clone(), coin).is_some() { + return Err(CoinsError::DuplicateDenom); + } + } + + Ok(Self(map)) + } +} + +impl TryFrom<&[Coin]> for Coins { + type Error = CoinsError; + + fn try_from(slice: &[Coin]) -> Result { + slice.to_vec().try_into() + } +} + +impl From for Coins { + fn from(value: Coin) -> Self { + let mut coins = Coins::default(); + // this can never overflow (because there are no coins in there yet), so we can unwrap + coins.add(value).unwrap(); + coins + } +} + +impl TryFrom<[Coin; N]> for Coins { + type Error = CoinsError; + + fn try_from(slice: [Coin; N]) -> Result { + slice.to_vec().try_into() + } +} + +impl From for Vec { + fn from(value: Coins) -> Self { + value.into_vec() + } +} + +impl FromStr for Coins { + type Err = StdError; + + fn from_str(s: &str) -> StdResult { + if s.is_empty() { + return Ok(Self::default()); + } + + Ok(s.split(',') + .map(Coin::from_str) + .collect::, _>>()? + .try_into()?) + } +} + +impl fmt::Display for Coins { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let s = self + .0 + .values() + .map(|coin| coin.to_string()) + .collect::>() + .join(","); + write!(f, "{s}") + } +} + +impl Coins { + /// Conversion to Vec, while NOT consuming the original object. + /// + /// This produces a vector of coins that is sorted alphabetically by denom with + /// no duplicate denoms. + pub fn to_vec(&self) -> Vec { + self.0.values().cloned().collect() + } + + /// Conversion to Vec, consuming the original object. + /// + /// This produces a vector of coins that is sorted alphabetically by denom with + /// no duplicate denoms. + pub fn into_vec(self) -> Vec { + self.0.into_values().collect() + } + + /// Returns the number of different denoms in this collection. + pub fn len(&self) -> usize { + self.0.len() + } + + /// Returns `true` if this collection contains no coins. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Returns the denoms as a vector of strings. + /// The vector is guaranteed to not contain duplicates and sorted alphabetically. + pub fn denoms(&self) -> Vec { + self.0.keys().cloned().collect() + } + + /// Returns the amount of the given denom or zero if the denom is not present. + pub fn amount_of(&self, denom: &str) -> Uint128 { + self.0 + .get(denom) + .map(|c| c.amount) + .unwrap_or_else(Uint128::zero) + } + + /// Returns the amount of the given denom if and only if this collection contains only + /// the given denom. Otherwise `None` is returned. + /// + /// # Examples + /// + /// ```rust + /// use cosmwasm_std::{Coin, Coins, coin}; + /// + /// let coins: Coins = [coin(100, "uatom")].try_into().unwrap(); + /// assert_eq!(coins.contains_only("uatom").unwrap().u128(), 100); + /// assert_eq!(coins.contains_only("uluna"), None); + /// ``` + /// + /// ```rust + /// use cosmwasm_std::{Coin, Coins, coin}; + /// + /// let coins: Coins = [coin(100, "uatom"), coin(200, "uusd")].try_into().unwrap(); + /// assert_eq!(coins.contains_only("uatom"), None); + /// ``` + pub fn contains_only(&self, denom: &str) -> Option { + if self.len() == 1 { + self.0.get(denom).map(|c| c.amount) + } else { + None + } + } + + /// Adds the given coin to this `Coins` instance. + /// Errors in case of overflow. + pub fn add(&mut self, coin: Coin) -> StdResult<()> { + if coin.amount.is_zero() { + return Ok(()); + } + + // if the coin is not present yet, insert it, otherwise add to existing amount + match self.0.get_mut(&coin.denom) { + None => { + self.0.insert(coin.denom.clone(), coin); + } + Some(existing) => { + existing.amount = existing.amount.checked_add(coin.amount)?; + } + } + Ok(()) + } + + /// Subtracts the given coin from this `Coins` instance. + /// Errors in case of overflow or if the denom is not present. + pub fn sub(&mut self, coin: Coin) -> StdResult<()> { + match self.0.get_mut(&coin.denom) { + Some(existing) => { + existing.amount = existing.amount.checked_sub(coin.amount)?; + // make sure to remove zero coin + if existing.amount.is_zero() { + self.0.remove(&coin.denom); + } + } + None => { + // ignore zero subtraction + if coin.amount.is_zero() { + return Ok(()); + } + return Err(OverflowError::new( + OverflowOperation::Sub, + Uint128::zero(), + coin.amount, + ) + .into()); + } + } + + Ok(()) + } + + /// Returns an iterator over the coins. + /// + /// # Examples + /// + /// ``` + /// # use cosmwasm_std::{coin, Coin, Coins, Uint128}; + /// let mut coins = Coins::default(); + /// coins.add(coin(500, "uluna")).unwrap(); + /// coins.add(coin(1000, "uatom")).unwrap(); + /// let mut iterator = coins.iter(); + /// + /// let uatom = iterator.next().unwrap(); + /// assert_eq!(uatom.denom, "uatom"); + /// assert_eq!(uatom.amount.u128(), 1000); + /// + /// let uluna = iterator.next().unwrap(); + /// assert_eq!(uluna.denom, "uluna"); + /// assert_eq!(uluna.amount.u128(), 500); + /// + /// assert_eq!(iterator.next(), None); + /// ``` + pub fn iter(&self) -> CoinsIter<'_> { + CoinsIter(self.0.iter()) + } +} + +impl IntoIterator for Coins { + type Item = Coin; + type IntoIter = CoinsIntoIter; + + fn into_iter(self) -> Self::IntoIter { + CoinsIntoIter(self.0.into_iter()) + } +} + +impl<'a> IntoIterator for &'a Coins { + type Item = &'a Coin; + type IntoIter = CoinsIter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +#[derive(Debug)] +pub struct CoinsIntoIter(alloc::collections::btree_map::IntoIter); + +impl Iterator for CoinsIntoIter { + type Item = Coin; + + fn next(&mut self) -> Option { + self.0.next().map(|(_, coin)| coin) + } + + fn size_hint(&self) -> (usize, Option) { + // Since btree_map::IntoIter implements ExactSizeIterator, this is guaranteed to return the exact length + self.0.size_hint() + } +} + +impl DoubleEndedIterator for CoinsIntoIter { + fn next_back(&mut self) -> Option { + self.0.next_back().map(|(_, coin)| coin) + } +} + +impl ExactSizeIterator for CoinsIntoIter { + fn len(&self) -> usize { + self.0.len() + } +} + +#[derive(Debug)] +pub struct CoinsIter<'a>(alloc::collections::btree_map::Iter<'a, String, Coin>); + +impl<'a> Iterator for CoinsIter<'a> { + type Item = &'a Coin; + + fn next(&mut self) -> Option { + self.0.next().map(|(_, coin)| coin) + } + + fn size_hint(&self) -> (usize, Option) { + // Since btree_map::Iter implements ExactSizeIterator, this is guaranteed to return the exact length + self.0.size_hint() + } +} + +impl<'a> DoubleEndedIterator for CoinsIter<'a> { + fn next_back(&mut self) -> Option { + self.0.next_back().map(|(_, coin)| coin) + } +} + +impl<'a> ExactSizeIterator for CoinsIter<'a> { + fn len(&self) -> usize { + self.0.len() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::coin; + + /// Sort a Vec by denom alphabetically + fn sort_by_denom(vec: &mut [Coin]) { + vec.sort_by(|a, b| a.denom.cmp(&b.denom)); + } + + /// Returns a mockup Vec. In this example, the coins are not in order + fn mock_vec() -> Vec { + vec![ + coin(12345, "uatom"), + coin(69420, "ibc/1234ABCD"), + coin(88888, "factory/osmo1234abcd/subdenom"), + ] + } + + /// Return a mockup Coins that contains the same coins as in `mock_vec` + fn mock_coins() -> Coins { + let mut coins = Coins::default(); + for coin in mock_vec() { + coins.add(coin).unwrap(); + } + coins + } + + #[test] + fn converting_vec() { + let mut vec = mock_vec(); + let coins = mock_coins(); + + // &[Coin] --> Coins + assert_eq!(Coins::try_from(vec.as_slice()).unwrap(), coins); + // Vec --> Coins + assert_eq!(Coins::try_from(vec.clone()).unwrap(), coins); + + sort_by_denom(&mut vec); + + // &Coins --> Vec + // NOTE: the returned vec should be sorted + assert_eq!(coins.to_vec(), vec); + // Coins --> Vec + // NOTE: the returned vec should be sorted + assert_eq!(coins.into_vec(), vec); + } + + #[test] + fn converting_str() { + // not in order + let s1 = "88888factory/osmo1234abcd/subdenom,12345uatom,69420ibc/1234ABCD"; + // in order + let s2 = "88888factory/osmo1234abcd/subdenom,69420ibc/1234ABCD,12345uatom"; + + let invalid = "12345uatom,noamount"; + + let coins = mock_coins(); + + // &str --> Coins + // NOTE: should generate the same Coins, regardless of input order + assert_eq!(Coins::from_str(s1).unwrap(), coins); + assert_eq!(Coins::from_str(s2).unwrap(), coins); + assert_eq!(Coins::from_str("").unwrap(), Coins::default()); + + // Coins --> String + // NOTE: the generated string should be sorted + assert_eq!(coins.to_string(), s2); + assert_eq!(Coins::default().to_string(), ""); + assert_eq!( + Coins::from_str(invalid).unwrap_err().to_string(), + "Generic error: Parsing Coin: Missing amount or non-digit characters in amount" + ); + } + + #[test] + fn handling_duplicates() { + // create a Vec that contains duplicate denoms + let mut vec = mock_vec(); + vec.push(coin(67890, "uatom")); + + let err = Coins::try_from(vec).unwrap_err(); + assert_eq!(err, CoinsError::DuplicateDenom); + } + + #[test] + fn handling_zero_amount() { + // create a Vec that contains zero amounts + let mut vec = mock_vec(); + vec[0].amount = Uint128::zero(); + + let coins = Coins::try_from(vec).unwrap(); + assert_eq!(coins.len(), 2); + assert_ne!(coins.amount_of("ibc/1234ABCD"), Uint128::zero()); + assert_ne!( + coins.amount_of("factory/osmo1234abcd/subdenom"), + Uint128::zero() + ); + + // adding a coin with zero amount should not be added + let mut coins = Coins::default(); + coins.add(coin(0, "uusd")).unwrap(); + assert!(coins.is_empty()); + } + + #[test] + fn length() { + let coins = Coins::default(); + assert_eq!(coins.len(), 0); + assert!(coins.is_empty()); + + let coins = mock_coins(); + assert_eq!(coins.len(), 3); + assert!(!coins.is_empty()); + } + + #[test] + fn add_coin() { + let mut coins = mock_coins(); + + // existing denom + coins.add(coin(12345, "uatom")).unwrap(); + assert_eq!(coins.len(), 3); + assert_eq!(coins.amount_of("uatom").u128(), 24690); + + // new denom + coins.add(coin(123, "uusd")).unwrap(); + assert_eq!(coins.len(), 4); + + // zero amount + coins.add(coin(0, "uusd")).unwrap(); + assert_eq!(coins.amount_of("uusd").u128(), 123); + + // zero amount, new denom + coins.add(coin(0, "utest")).unwrap(); + assert_eq!(coins.len(), 4); + } + + #[test] + fn sub_coins() { + let mut coins: Coins = coin(12345, "uatom").into(); + + // sub more than available + let err = coins.sub(coin(12346, "uatom")).unwrap_err(); + assert!(matches!(err, StdError::Overflow { .. })); + + // sub non-existent denom + let err = coins.sub(coin(12345, "uusd")).unwrap_err(); + assert!(matches!(err, StdError::Overflow { .. })); + + // partial sub + coins.sub(coin(1, "uatom")).unwrap(); + assert_eq!(coins.len(), 1); + assert_eq!(coins.amount_of("uatom").u128(), 12344); + + // full sub + coins.sub(coin(12344, "uatom")).unwrap(); + assert!(coins.is_empty()); + + // sub zero, existing denom + coins.sub(coin(0, "uusd")).unwrap(); + assert!(coins.is_empty()); + let mut coins: Coins = coin(12345, "uatom").into(); + + // sub zero, non-existent denom + coins.sub(coin(0, "uatom")).unwrap(); + assert_eq!(coins.len(), 1); + assert_eq!(coins.amount_of("uatom").u128(), 12345); + } + + #[test] + fn coin_to_coins() { + // zero coin results in empty collection + let coins: Coins = coin(0, "uusd").into(); + assert!(coins.is_empty()); + + // happy path + let coins = Coins::from(coin(12345, "uatom")); + assert_eq!(coins.len(), 1); + assert_eq!(coins.amount_of("uatom").u128(), 12345); + } + + #[test] + fn exact_size_iterator() { + let coins = mock_coins(); + let iter = coins.iter(); + assert_eq!(iter.len(), 3); + assert_eq!(iter.size_hint(), (3, Some(3))); + + let iter = coins.into_iter(); + assert_eq!(iter.len(), 3); + assert_eq!(iter.size_hint(), (3, Some(3))); + } + + #[test] + fn can_iterate_owned() { + let coins = mock_coins(); + let mut moved = Coins::default(); + for c in coins { + moved.add(c).unwrap(); + } + assert_eq!(moved.len(), 3); + + assert!(mock_coins().into_iter().eq(mock_coins().to_vec())); + } + + #[test] + fn can_iterate_borrowed() { + let coins = mock_coins(); + assert!(coins + .iter() + .map(|c| &c.denom) + .eq(coins.to_vec().iter().map(|c| &c.denom))); + + // can still use the coins afterwards + assert_eq!(coins.amount_of("uatom").u128(), 12345); + } +} diff --git a/packages/std/src/deps.rs b/packages/std/src/deps.rs index 4d9a9ecdc..cc7a4681a 100644 --- a/packages/std/src/deps.rs +++ b/packages/std/src/deps.rs @@ -1,4 +1,4 @@ -use std::marker::PhantomData; +use core::marker::PhantomData; use crate::query::CustomQuery; use crate::results::Empty; @@ -69,6 +69,28 @@ impl<'a, C: CustomQuery> DepsMut<'a, C> { querier: self.querier, } } + + /// This allows to convert any `DepsMut` into one generic over `Empty` custom + /// query type. + pub fn into_empty(self) -> DepsMut<'a, Empty> { + DepsMut { + storage: self.storage, + api: self.api, + querier: self.querier.into_empty(), + } + } +} + +impl<'a, C: CustomQuery> Deps<'a, C> { + /// This allows to convert any `Deps` into one generic over `Empty` custom + /// query type. + pub fn into_empty(self) -> Deps<'a, Empty> { + Deps { + storage: self.storage, + api: self.api, + querier: self.querier.into_empty(), + } + } } #[cfg(test)] @@ -98,12 +120,13 @@ mod tests { query(deps.as_ref()) } + #[derive(Clone, Serialize, Deserialize)] + struct MyQuery; + impl CustomQuery for MyQuery {} + #[test] fn deps_implements_copy() { impl CustomQuery for u64 {} - #[derive(Clone, Serialize, Deserialize)] - struct MyQuery; - impl CustomQuery for MyQuery {} // With C: Copy let owned = OwnedDeps::<_, _, _, u64> { @@ -127,4 +150,20 @@ mod tests { let _copy1 = deps; let _copy2 = deps; } + + #[test] + fn deps_to_empty() { + let mut owned = OwnedDeps::<_, _, _, MyQuery> { + storage: MockStorage::default(), + api: MockApi::default(), + querier: MockQuerier::::new(&[]), + custom_query_type: PhantomData, + }; + + let deps_mut: DepsMut = owned.as_mut(); + let _: DepsMut = deps_mut.into_empty(); + + let deps: Deps = owned.as_ref(); + let _: Deps = deps.into_empty(); + } } diff --git a/packages/std/src/errors/mod.rs b/packages/std/src/errors/mod.rs index d11c5604e..7bee00461 100644 --- a/packages/std/src/errors/mod.rs +++ b/packages/std/src/errors/mod.rs @@ -7,7 +7,8 @@ mod verification_error; pub use hash_calculation_error::HashCalculationError; pub use recover_pubkey_error::RecoverPubkeyError; pub use std_error::{ - CheckedFromRatioError, CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError, + CheckedFromRatioError, CheckedMultiplyFractionError, CheckedMultiplyRatioError, + CoinFromStrError, CoinsError, ConversionOverflowError, DivideByZeroError, DivisionError, OverflowError, OverflowOperation, RoundUpOverflowError, StdError, StdResult, }; pub use system_error::SystemError; diff --git a/packages/std/src/errors/recover_pubkey_error.rs b/packages/std/src/errors/recover_pubkey_error.rs index 4bbd060d8..c4269eb5c 100644 --- a/packages/std/src/errors/recover_pubkey_error.rs +++ b/packages/std/src/errors/recover_pubkey_error.rs @@ -1,8 +1,8 @@ +use core::fmt::Debug; #[cfg(not(target_arch = "wasm32"))] use cosmwasm_crypto::CryptoError; #[cfg(feature = "backtraces")] use std::backtrace::Backtrace; -use std::fmt::Debug; use thiserror::Error; #[derive(Error, Debug)] diff --git a/packages/std/src/errors/std_error.rs b/packages/std/src/errors/std_error.rs index ede4b87a5..9a9f2f58c 100644 --- a/packages/std/src/errors/std_error.rs +++ b/packages/std/src/errors/std_error.rs @@ -1,6 +1,6 @@ +use core::fmt; #[cfg(feature = "backtraces")] use std::backtrace::Backtrace; -use std::fmt; use thiserror::Error; use crate::errors::{HashCalculationError, RecoverPubkeyError, VerificationError}; @@ -463,14 +463,14 @@ impl PartialEq for StdError { } } -impl From for StdError { - fn from(source: std::str::Utf8Error) -> Self { +impl From for StdError { + fn from(source: core::str::Utf8Error) -> Self { Self::invalid_utf8(source) } } -impl From for StdError { - fn from(source: std::string::FromUtf8Error) -> Self { +impl From for StdError { + fn from(source: alloc::string::FromUtf8Error) -> Self { Self::invalid_utf8(source) } } @@ -524,7 +524,7 @@ pub enum OverflowOperation { impl fmt::Display for OverflowOperation { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) + write!(f, "{self:?}") } } @@ -553,7 +553,7 @@ impl OverflowError { /// The error returned by [`TryFrom`] conversions that overflow, for example /// when converting from [`Uint256`] to [`Uint128`]. /// -/// [`TryFrom`]: std::convert::TryFrom +/// [`TryFrom`]: core::convert::TryFrom /// [`Uint256`]: crate::Uint256 /// [`Uint128`]: crate::Uint128 #[derive(Error, Debug, PartialEq, Eq)] @@ -579,7 +579,7 @@ impl ConversionOverflowError { } #[derive(Error, Debug, PartialEq, Eq)] -#[error("Cannot devide {operand} by zero")] +#[error("Cannot divide {operand} by zero")] pub struct DivideByZeroError { pub operand: String, } @@ -592,6 +592,27 @@ impl DivideByZeroError { } } +#[derive(Error, Debug, PartialEq, Eq)] +pub enum DivisionError { + #[error("Divide by zero")] + DivideByZero, + + #[error("Overflow in division")] + Overflow, +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum CheckedMultiplyFractionError { + #[error("{0}")] + DivideByZero(#[from] DivideByZeroError), + + #[error("{0}")] + ConversionOverflow(#[from] ConversionOverflowError), + + #[error("{0}")] + Overflow(#[from] OverflowError), +} + #[derive(Error, Debug, PartialEq, Eq)] pub enum CheckedMultiplyRatioError { #[error("Denominator must not be zero")] @@ -614,10 +635,44 @@ pub enum CheckedFromRatioError { #[error("Round up operation failed because of overflow")] pub struct RoundUpOverflowError; +#[derive(Error, Debug, PartialEq, Eq)] +pub enum CoinsError { + #[error("Duplicate denom")] + DuplicateDenom, +} + +impl From for StdError { + fn from(value: CoinsError) -> Self { + Self::generic_err(format!("Creating Coins: {value}")) + } +} + +#[derive(Error, Debug, PartialEq, Eq)] +pub enum CoinFromStrError { + #[error("Missing denominator")] + MissingDenom, + #[error("Missing amount or non-digit characters in amount")] + MissingAmount, + #[error("Invalid amount: {0}")] + InvalidAmount(core::num::ParseIntError), +} + +impl From for CoinFromStrError { + fn from(value: core::num::ParseIntError) -> Self { + Self::InvalidAmount(value) + } +} + +impl From for StdError { + fn from(value: CoinFromStrError) -> Self { + Self::generic_err(format!("Parsing Coin: {value}")) + } +} + #[cfg(test)] mod tests { use super::*; - use std::str; + use core::str; // constructors @@ -625,12 +680,12 @@ mod tests { #[test] fn generic_err_owned() { let guess = 7; - let error = StdError::generic_err(format!("{} is too low", guess)); + let error = StdError::generic_err(format!("{guess} is too low")); match error { StdError::GenericErr { msg, .. } => { assert_eq!(msg, String::from("7 is too low")); } - e => panic!("unexpected error, {:?}", e), + e => panic!("unexpected error, {e:?}"), } } @@ -640,7 +695,7 @@ mod tests { let error = StdError::generic_err("not implemented"); match error { StdError::GenericErr { msg, .. } => assert_eq!(msg, "not implemented"), - e => panic!("unexpected error, {:?}", e), + e => panic!("unexpected error, {e:?}"), } } @@ -822,7 +877,7 @@ mod tests { #[test] fn implements_debug() { let error: StdError = StdError::from(OverflowError::new(OverflowOperation::Sub, 3, 5)); - let embedded = format!("Debug: {:?}", error); + let embedded = format!("Debug: {error:?}"); #[cfg(not(feature = "backtraces"))] let expected = r#"Debug: Overflow { source: OverflowError { operation: Sub, operand1: "3", operand2: "5" } }"#; #[cfg(feature = "backtraces")] @@ -833,7 +888,7 @@ mod tests { #[test] fn implements_display() { let error: StdError = StdError::from(OverflowError::new(OverflowOperation::Sub, 3, 5)); - let embedded = format!("Display: {}", error); + let embedded = format!("Display: {error}"); assert_eq!(embedded, "Display: Overflow: Cannot Sub with 3 and 5"); } @@ -854,14 +909,13 @@ mod tests { #[test] fn from_std_str_utf8error_works() { - let error: StdError = str::from_utf8(b"Hello \xF0\x90\x80World") - .unwrap_err() - .into(); + let broken = b"Hello \xF0\x90\x80World"; + let error: StdError = str::from_utf8(broken).unwrap_err().into(); match error { StdError::InvalidUtf8 { msg, .. } => { assert_eq!(msg, "invalid utf-8 sequence of 3 bytes from index 6") } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -874,7 +928,7 @@ mod tests { StdError::InvalidUtf8 { msg, .. } => { assert_eq!(msg, "invalid utf-8 sequence of 3 bytes from index 6") } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } } diff --git a/packages/std/src/errors/system_error.rs b/packages/std/src/errors/system_error.rs index 27cd40f12..98dc6f670 100644 --- a/packages/std/src/errors/system_error.rs +++ b/packages/std/src/errors/system_error.rs @@ -28,6 +28,11 @@ pub enum SystemError { /// The address that was attempted to query addr: String, }, + /// A Wasm code was not found. + NoSuchCode { + /// The code ID that is missing + code_id: u64, + }, Unknown {}, UnsupportedRequest { kind: String, @@ -36,8 +41,8 @@ pub enum SystemError { impl std::error::Error for SystemError {} -impl std::fmt::Display for SystemError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for SystemError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { SystemError::InvalidRequest { error, request } => write!( f, @@ -51,11 +56,57 @@ impl std::fmt::Display for SystemError { error, String::from_utf8_lossy(response) ), - SystemError::NoSuchContract { addr } => write!(f, "No such contract: {}", addr), + SystemError::NoSuchContract { addr } => write!(f, "No such contract: {addr}"), + SystemError::NoSuchCode { code_id } => write!(f, "No such code: {code_id}"), SystemError::Unknown {} => write!(f, "Unknown system error"), SystemError::UnsupportedRequest { kind } => { - write!(f, "Unsupported query type: {}", kind) + write!(f, "Unsupported query type: {kind}") } } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{from_slice, to_vec}; + + #[test] + fn system_error_no_such_contract_serialization() { + let err = SystemError::NoSuchContract { + addr: "gibtsnicht".to_string(), + }; + + // ser + let json = to_vec(&err).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"no_such_contract":{"addr":"gibtsnicht"}}"#, + ); + + // de + let err: SystemError = from_slice(br#"{"no_such_contract":{"addr":"nada"}}"#).unwrap(); + assert_eq!( + err, + SystemError::NoSuchContract { + addr: "nada".to_string() + } + ); + } + + #[test] + fn system_error_no_such_code_serialization() { + let err = SystemError::NoSuchCode { code_id: 13 }; + + // ser + let json = to_vec(&err).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"no_such_code":{"code_id":13}}"#, + ); + + // de + let err: SystemError = from_slice(br#"{"no_such_code":{"code_id":987}}"#).unwrap(); + assert_eq!(err, SystemError::NoSuchCode { code_id: 987 },); + } +} diff --git a/packages/std/src/errors/verification_error.rs b/packages/std/src/errors/verification_error.rs index 90f1f265c..80bb50d57 100644 --- a/packages/std/src/errors/verification_error.rs +++ b/packages/std/src/errors/verification_error.rs @@ -1,6 +1,6 @@ +use core::fmt::Debug; #[cfg(feature = "backtraces")] use std::backtrace::Backtrace; -use std::fmt::Debug; use thiserror::Error; #[cfg(not(target_arch = "wasm32"))] diff --git a/packages/std/src/exports.rs b/packages/std/src/exports.rs index a2c986806..8f057712d 100644 --- a/packages/std/src/exports.rs +++ b/packages/std/src/exports.rs @@ -7,8 +7,8 @@ //! and `do_sudo` should be wrapped with a extern "C" entry point including //! the contract-specific function pointer. This is done via the `#[entry_point]` //! macro attribute from cosmwasm-derive. -use std::marker::PhantomData; -use std::vec::Vec; +use alloc::vec::Vec; +use core::marker::PhantomData; use serde::de::DeserializeOwned; @@ -45,6 +45,18 @@ extern "C" fn requires_stargate() -> () {} #[no_mangle] extern "C" fn requires_cosmwasm_1_1() -> () {} +#[cfg(feature = "cosmwasm_1_2")] +#[no_mangle] +extern "C" fn requires_cosmwasm_1_2() -> () {} + +#[cfg(feature = "cosmwasm_1_3")] +#[no_mangle] +extern "C" fn requires_cosmwasm_1_3() -> () {} + +#[cfg(feature = "cosmwasm_1_4")] +#[no_mangle] +extern "C" fn requires_cosmwasm_1_4() -> () {} + /// interface_version_* exports mark which Wasm VM interface level this contract is compiled for. /// They can be checked by cosmwasm_vm. /// Update this whenever the Wasm VM interface breaks. diff --git a/packages/std/src/forward_ref.rs b/packages/std/src/forward_ref.rs new file mode 100644 index 000000000..16385fbc9 --- /dev/null +++ b/packages/std/src/forward_ref.rs @@ -0,0 +1,25 @@ +/// Given an implementation of `T == U`, implements: +/// - `&T == U` +/// - `T == &U` +/// +/// We don't need to add `&T == &U` here because this is implemented automatically. +#[macro_export] +macro_rules! forward_ref_partial_eq { + ($t:ty, $u:ty) => { + // `&T == U` + impl<'a> PartialEq<$u> for &'a $t { + #[inline] + fn eq(&self, rhs: &$u) -> bool { + **self == *rhs // Implement via T == U + } + } + + // `T == &U` + impl PartialEq<&$u> for $t { + #[inline] + fn eq(&self, rhs: &&$u) -> bool { + *self == **rhs // Implement via T == U + } + } + }; +} diff --git a/packages/std/src/hex_binary.rs b/packages/std/src/hex_binary.rs index 4aa5f7cc8..0def99b36 100644 --- a/packages/std/src/hex_binary.rs +++ b/packages/std/src/hex_binary.rs @@ -1,5 +1,5 @@ -use std::fmt; -use std::ops::Deref; +use core::fmt; +use core::ops::Deref; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; @@ -72,19 +72,13 @@ impl fmt::Debug for HexBinary { // but with a custom implementation to avoid the need for an intemediate hex string. write!(f, "HexBinary(")?; for byte in self.0.iter() { - write!(f, "{:02x}", byte)?; + write!(f, "{byte:02x}")?; } write!(f, ")")?; Ok(()) } } -impl From<&[u8]> for HexBinary { - fn from(binary: &[u8]) -> Self { - Self(binary.to_vec()) - } -} - /// Just like Vec, HexBinary is a smart pointer to [u8]. /// This implements `*data` for us and allows us to /// do `&*data`, returning a `&[u8]` from a `&HexBinary`. @@ -98,14 +92,27 @@ impl Deref for HexBinary { } } -// Reference +impl AsRef<[u8]> for HexBinary { + fn as_ref(&self) -> &[u8] { + self.as_slice() + } +} + +// Slice +impl From<&[u8]> for HexBinary { + fn from(binary: &[u8]) -> Self { + Self(binary.to_vec()) + } +} + +// Array reference impl From<&[u8; LENGTH]> for HexBinary { fn from(source: &[u8; LENGTH]) -> Self { Self(source.to_vec()) } } -// Owned +// Owned array impl From<[u8; LENGTH]> for HexBinary { fn from(source: [u8; LENGTH]) -> Self { Self(source.into()) @@ -136,7 +143,7 @@ impl From for Binary { } } -/// Implement `HexBinary == std::vec::Vec` +/// Implement `HexBinary == alloc::vec::Vec` impl PartialEq> for HexBinary { fn eq(&self, rhs: &Vec) -> bool { // Use Vec == Vec @@ -144,7 +151,7 @@ impl PartialEq> for HexBinary { } } -/// Implement `std::vec::Vec == HexBinary` +/// Implement `alloc::vec::Vec == HexBinary` impl PartialEq for Vec { fn eq(&self, rhs: &HexBinary) -> bool { // Use Vec == Vec @@ -231,7 +238,7 @@ impl<'de> de::Visitor<'de> for HexVisitor { { match HexBinary::from_hex(v) { Ok(data) => Ok(data), - Err(_) => Err(E::custom(format!("invalid hex: {}", v))), + Err(_) => Err(E::custom(format!("invalid hex: {v}"))), } } } @@ -240,10 +247,7 @@ impl<'de> de::Visitor<'de> for HexVisitor { mod tests { use super::*; - use crate::{from_slice, to_vec, StdError}; - use std::collections::hash_map::DefaultHasher; - use std::collections::HashSet; - use std::hash::{Hash, Hasher}; + use crate::{assert_hash_works, from_slice, to_vec, StdError}; #[test] fn from_hex_works() { @@ -338,7 +342,7 @@ mod tests { assert_eq!(expected, 8); assert_eq!(actual, 3); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } // long array (32 bytes) @@ -540,11 +544,11 @@ mod tests { fn hex_binary_implements_debug() { // Some data let data = HexBinary(vec![0x07, 0x35, 0xAA, 0xcb, 0x00, 0xff]); - assert_eq!(format!("{:?}", data), "HexBinary(0735aacb00ff)",); + assert_eq!(format!("{data:?}"), "HexBinary(0735aacb00ff)",); // Empty let data = HexBinary(vec![]); - assert_eq!(format!("{:?}", data), "HexBinary()",); + assert_eq!(format!("{data:?}"), "HexBinary()",); } #[test] @@ -561,42 +565,20 @@ mod tests { } #[test] - fn hex_binary_implements_hash() { - let a1 = HexBinary::from([0, 187, 61, 11, 250, 0]); - let mut hasher = DefaultHasher::new(); - a1.hash(&mut hasher); - let a1_hash = hasher.finish(); - - let a2 = HexBinary::from([0, 187, 61, 11, 250, 0]); - let mut hasher = DefaultHasher::new(); - a2.hash(&mut hasher); - let a2_hash = hasher.finish(); - - let b = HexBinary::from([16, 21, 33, 0, 255, 9]); - let mut hasher = DefaultHasher::new(); - b.hash(&mut hasher); - let b_hash = hasher.finish(); - - assert_eq!(a1_hash, a2_hash); - assert_ne!(a1_hash, b_hash); + fn hex_binary_implements_as_ref() { + let want = &[7u8, 35, 49, 101, 0, 255]; + let data = HexBinary(want.to_vec()); + assert_eq!(want, AsRef::<[u8]>::as_ref(&data)); + assert_eq!(want, AsRef::<[u8]>::as_ref(&&data)); } - /// This requires Hash and Eq to be implemented + /// Tests that `HexBinary` implements `EQ` and `Hash` correctly and thus can + /// be used with hash maps and sets. #[test] - fn hex_binary_can_be_used_in_hash_set() { - let a1 = HexBinary::from([0, 187, 61, 11, 250, 0]); - let a2 = HexBinary::from([0, 187, 61, 11, 250, 0]); + fn hex_binary_implements_hash_eq() { + let a = HexBinary::from([0, 187, 61, 11, 250, 0]); let b = HexBinary::from([16, 21, 33, 0, 255, 9]); - - let mut set = HashSet::new(); - set.insert(a1.clone()); - set.insert(a2.clone()); - set.insert(b.clone()); - assert_eq!(set.len(), 2); - - let set1 = HashSet::::from_iter(vec![b.clone(), a1.clone()]); - let set2 = HashSet::from_iter(vec![a1, a2, b]); - assert_eq!(set1, set2); + assert_hash_works!(a, b); } #[test] diff --git a/packages/std/src/ibc.rs b/packages/std/src/ibc.rs index 1ce06432a..dab621b71 100644 --- a/packages/std/src/ibc.rs +++ b/packages/std/src/ibc.rs @@ -1,10 +1,9 @@ -#![cfg(feature = "stargate")] // The CosmosMsg variants are defined in results/cosmos_msg.rs // The rest of the IBC related functionality is defined here +use core::cmp::{Ord, Ordering, PartialOrd}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::cmp::{Ord, Ordering, PartialOrd}; #[cfg(feature = "ibc3")] use crate::addresses::Addr; @@ -27,7 +26,7 @@ pub enum IbcMsg { /// We cannot select the port_id, this is whatever the local chain has bound the ibctransfer /// module to. Transfer { - /// exisiting channel to send the tokens over + /// existing channel to send the tokens over channel_id: String, /// address on the remote chain to receive these tokens to_address: String, @@ -165,7 +164,7 @@ pub enum IbcOrder { #[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct IbcTimeoutBlock { /// the version that the client is currently on - /// (eg. after reseting the chain this could increment 1 as height drops to 0) + /// (e.g. after resetting the chain this could increment 1 as height drops to 0) pub revision: u64, /// block height after which the packet times out. /// the height within the given revision @@ -493,18 +492,18 @@ pub struct IbcBasicResponse { /// /// More info about events (and their attributes) can be found in [*Cosmos SDK* docs]. /// - /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/main/core/events.html pub attributes: Vec, /// Extra, custom events separate from the main `wasm` one. These will have /// `wasm-` prepended to the type. /// /// More info about events can be found in [*Cosmos SDK* docs]. /// - /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/main/core/events.html pub events: Vec, } -// Custom imlementation in order to implement it for all `T`, even if `T` is not `Default`. +// Custom implementation in order to implement it for all `T`, even if `T` is not `Default`. impl Default for IbcBasicResponse { fn default() -> Self { IbcBasicResponse { @@ -533,7 +532,7 @@ impl IbcBasicResponse { self } - /// This takes an explicit SubMsg (creates via eg. `reply_on_error`) + /// This takes an explicit SubMsg (creates via e.g. `reply_on_error`) /// and adds it to the list of messages to process. pub fn add_submessage(mut self, msg: SubMsg) -> Self { self.messages.push(msg); @@ -603,7 +602,7 @@ impl IbcBasicResponse { /// } /// ``` pub fn add_submessages(mut self, msgs: impl IntoIterator>) -> Self { - self.messages.extend(msgs.into_iter()); + self.messages.extend(msgs); self } @@ -613,21 +612,21 @@ impl IbcBasicResponse { /// The `wasm-` prefix will be appended by the runtime to the provided types /// of events. pub fn add_events(mut self, events: impl IntoIterator) -> Self { - self.events.extend(events.into_iter()); + self.events.extend(events); self } } -// This defines the return value on packet response processing. -// This "success" case should be returned even in application-level errors, -// Where the acknowledgement bytes contain an encoded error message to be returned to -// the calling chain. (Returning ContractResult::Err will abort processing of this packet -// and not inform the calling chain). +/// This defines the return value on packet response processing. +/// This "success" case should be returned even in application-level errors, +/// Where the acknowledgement bytes contain an encoded error message to be returned to +/// the calling chain. (Returning ContractResult::Err will abort processing of this packet +/// and not inform the calling chain). #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[non_exhaustive] pub struct IbcReceiveResponse { /// The bytes we return to the contract that sent the packet. - /// This may represent a success or error of exection + /// This may represent a success or error of execution pub acknowledgement: Binary, /// Optional list of messages to pass. These will be executed in order. /// If the ReplyOn member is set, they will invoke this contract's `reply` entry point @@ -638,18 +637,18 @@ pub struct IbcReceiveResponse { /// /// More info about events (and their attributes) can be found in [*Cosmos SDK* docs]. /// - /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/main/core/events.html pub attributes: Vec, /// Extra, custom events separate from the main `wasm` one. These will have /// `wasm-` prepended to the type. /// /// More info about events can be found in [*Cosmos SDK* docs]. /// - /// [*Cosmos SDK* docs]: https://docs.cosmos.network/v0.42/core/events.html + /// [*Cosmos SDK* docs]: https://docs.cosmos.network/main/core/events.html pub events: Vec, } -// Custom imlementation in order to implement it for all `T`, even if `T` is not `Default`. +// Custom implementation in order to implement it for all `T`, even if `T` is not `Default`. impl Default for IbcReceiveResponse { fn default() -> Self { IbcReceiveResponse { @@ -667,6 +666,17 @@ impl IbcReceiveResponse { } /// Set the acknowledgement for this response. + /// + /// ## Examples + /// + /// ``` + /// use cosmwasm_std::{StdAck, IbcReceiveResponse}; + /// + /// fn make_response_with_ack() -> IbcReceiveResponse { + /// let ack = StdAck::success(b"\x01"); // 0x01 is a FungibleTokenPacketSuccess from ICS-20. + /// IbcReceiveResponse::new().set_ack(ack) + /// } + /// ``` pub fn set_ack(mut self, ack: impl Into) -> Self { self.acknowledgement = ack.into(); self @@ -685,7 +695,7 @@ impl IbcReceiveResponse { self } - /// This takes an explicit SubMsg (creates via eg. `reply_on_error`) + /// This takes an explicit SubMsg (creates via e.g. `reply_on_error`) /// and adds it to the list of messages to process. pub fn add_submessage(mut self, msg: SubMsg) -> Self { self.messages.push(msg); @@ -755,7 +765,7 @@ impl IbcReceiveResponse { /// } /// ``` pub fn add_submessages(mut self, msgs: impl IntoIterator>) -> Self { - self.messages.extend(msgs.into_iter()); + self.messages.extend(msgs); self } @@ -765,7 +775,7 @@ impl IbcReceiveResponse { /// The `wasm-` prefix will be appended by the runtime to the provided types /// of events. pub fn add_events(mut self, events: impl IntoIterator) -> Self { - self.events.extend(events.into_iter()); + self.events.extend(events); self } } @@ -834,7 +844,7 @@ mod tests { }; // basic checks - assert!(epoch1a == epoch1a); + assert_eq!(epoch1a, epoch1a); assert!(epoch1a < epoch1b); assert!(epoch1b > epoch1a); assert!(epoch2a > epoch1a); diff --git a/packages/std/src/imports.rs b/packages/std/src/imports.rs index b8b50bd05..3e4e81b4b 100644 --- a/packages/std/src/imports.rs +++ b/packages/std/src/imports.rs @@ -1,5 +1,4 @@ -use std::convert::TryInto; -use std::vec::Vec; +use alloc::vec::Vec; use crate::addresses::{Addr, CanonicalAddr}; use crate::errors::{ @@ -40,6 +39,10 @@ extern "C" { fn db_scan(start_ptr: u32, end_ptr: u32, order: i32) -> u32; #[cfg(feature = "iterator")] fn db_next(iterator_id: u32) -> u32; + #[cfg(all(feature = "iterator", feature = "cosmwasm_1_4"))] + fn db_next_key(iterator_id: u32) -> u32; + #[cfg(all(feature = "iterator", feature = "cosmwasm_1_4"))] + fn db_next_value(iterator_id: u32) -> u32; fn addr_validate(source_ptr: u32) -> u32; fn addr_canonicalize(source_ptr: u32, destination_ptr: u32) -> u32; @@ -133,16 +136,98 @@ impl Storage for ExternalStorage { end: Option<&[u8]>, order: Order, ) -> Box> { - // There is lots of gotchas on turning options into regions for FFI, thus this design - // See: https://github.com/CosmWasm/cosmwasm/pull/509 - let start_region = start.map(build_region); - let end_region = end.map(build_region); - let start_region_addr = get_optional_region_address(&start_region.as_ref()); - let end_region_addr = get_optional_region_address(&end_region.as_ref()); - let iterator_id = unsafe { db_scan(start_region_addr, end_region_addr, order as i32) }; + let iterator_id = create_iter(start, end, order); let iter = ExternalIterator { iterator_id }; Box::new(iter) } + + #[cfg(all(feature = "cosmwasm_1_4", feature = "iterator"))] + fn range_keys<'a>( + &'a self, + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, + ) -> Box> + 'a> { + let iterator_id = create_iter(start, end, order); + let iter = ExternalPartialIterator { + iterator_id, + partial_type: PartialType::Keys, + }; + Box::new(iter) + } + + #[cfg(all(feature = "cosmwasm_1_4", feature = "iterator"))] + fn range_values<'a>( + &'a self, + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, + ) -> Box> + 'a> { + let iterator_id = create_iter(start, end, order); + let iter = ExternalPartialIterator { + iterator_id, + partial_type: PartialType::Values, + }; + Box::new(iter) + } +} + +#[cfg(feature = "iterator")] +fn create_iter(start: Option<&[u8]>, end: Option<&[u8]>, order: Order) -> u32 { + // There is lots of gotchas on turning options into regions for FFI, thus this design + // See: https://github.com/CosmWasm/cosmwasm/pull/509 + let start_region = start.map(build_region); + let end_region = end.map(build_region); + let start_region_addr = get_optional_region_address(&start_region.as_ref()); + let end_region_addr = get_optional_region_address(&end_region.as_ref()); + unsafe { db_scan(start_region_addr, end_region_addr, order as i32) } +} + +#[cfg(all(feature = "cosmwasm_1_4", feature = "iterator"))] +enum PartialType { + Keys, + Values, +} + +/// ExternalPartialIterator makes a call out to `next_key` or `next_value` +/// depending on its `partial_type`. +/// Compared to `ExternalIterator`, it allows iterating only over the keys or +/// values instead of both. +#[cfg(all(feature = "cosmwasm_1_4", feature = "iterator"))] +struct ExternalPartialIterator { + iterator_id: u32, + partial_type: PartialType, +} + +#[cfg(all(feature = "cosmwasm_1_4", feature = "iterator"))] +impl Iterator for ExternalPartialIterator { + type Item = Vec; + + /// The default implementation calls `next` repeatedly, + /// which we can do a little more efficiently by using `db_next_key` instead. + /// It is used by `skip`, so it allows cheaper skipping. + #[cfg(feature = "cosmwasm_1_4")] + fn nth(&mut self, n: usize) -> Option { + skip_iter(self.iterator_id, n); + self.next() + } + + fn next(&mut self) -> Option { + // here we differentiate between the two types + let next_result = match self.partial_type { + PartialType::Keys => unsafe { db_next_key(self.iterator_id) }, + PartialType::Values => unsafe { db_next_value(self.iterator_id) }, + }; + + if next_result == 0 { + // iterator is done + return None; + } + + let data_region = next_result as *mut Region; + let data = unsafe { consume_region(data_region) }; + Some(data) + } } #[cfg(feature = "iterator")] @@ -156,6 +241,15 @@ struct ExternalIterator { impl Iterator for ExternalIterator { type Item = Record; + /// The default implementation calls `next` repeatedly, + /// which we can do a little more efficiently by using `db_next_key` instead. + /// It is used by `skip`, so it allows cheaper skipping. + #[cfg(feature = "cosmwasm_1_4")] + fn nth(&mut self, n: usize) -> Option { + skip_iter(self.iterator_id, n); + self.next() + } + fn next(&mut self) -> Option { let next_result = unsafe { db_next(self.iterator_id) }; let kv_region_ptr = next_result as *mut Region; @@ -169,6 +263,20 @@ impl Iterator for ExternalIterator { } } +/// Helper function to skip `count` elements of an iterator. +#[cfg(all(feature = "iterator", feature = "cosmwasm_1_4"))] +fn skip_iter(iter_id: u32, count: usize) { + for _ in 0..count { + let region = unsafe { db_next_key(iter_id) }; + if region == 0 { + // early return + return; + } + // just deallocate the region + unsafe { consume_region(region as *mut Region) }; + } +} + /// A stateless convenience wrapper around imports provided by the VM #[derive(Copy, Clone)] pub struct ExternalApi {} diff --git a/packages/std/src/iterator.rs b/packages/std/src/iterator.rs index e74758160..00190aa5c 100644 --- a/packages/std/src/iterator.rs +++ b/packages/std/src/iterator.rs @@ -6,7 +6,7 @@ use crate::errors::StdError; /// allows contracts to reuse the type when deserializing database records. pub type Record> = (Vec, V); -#[derive(Copy, Clone)] +#[derive(Copy, Clone, PartialEq, Eq)] // We assign these to integers to provide a stable API for passing over FFI (to wasm and Go) pub enum Order { Ascending = 1, diff --git a/packages/std/src/lib.rs b/packages/std/src/lib.rs index 683153f4d..e0589d8f7 100644 --- a/packages/std/src/lib.rs +++ b/packages/std/src/lib.rs @@ -1,4 +1,7 @@ -#![cfg_attr(feature = "backtraces", feature(backtrace))] +#![cfg_attr(feature = "backtraces", feature(error_generic_member_access))] +#![cfg_attr(feature = "backtraces", feature(provide_any))] + +extern crate alloc; // Exposed on all platforms @@ -6,37 +9,49 @@ mod addresses; mod assertions; mod binary; mod coin; +mod coins; mod conversion; mod deps; mod errors; +mod forward_ref; mod hex_binary; mod ibc; mod import_helpers; #[cfg(feature = "iterator")] mod iterator; mod math; +mod metadata; +mod never; +mod pagination; mod panic; mod query; mod results; mod sections; mod serde; +mod stdack; mod storage; mod timestamp; mod traits; mod types; mod uuid; -pub use crate::addresses::{Addr, CanonicalAddr}; +/// This modules is very advanced and will not be used directly by the vast majority of users. +/// We want to offer it to ensure a stable storage key composition system but don't encourage +/// contract devs to use it directly. +pub mod storage_keys; + +pub use crate::addresses::{instantiate2_address, Addr, CanonicalAddr, Instantiate2AddressError}; pub use crate::binary::Binary; pub use crate::coin::{coin, coins, has_coins, Coin}; +pub use crate::coins::Coins; pub use crate::deps::{Deps, DepsMut, OwnedDeps}; pub use crate::errors::{ - CheckedFromRatioError, CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError, + CheckedFromRatioError, CheckedMultiplyFractionError, CheckedMultiplyRatioError, + CoinFromStrError, CoinsError, ConversionOverflowError, DivideByZeroError, DivisionError, OverflowError, OverflowOperation, RecoverPubkeyError, StdError, StdResult, SystemError, VerificationError, }; pub use crate::hex_binary::HexBinary; -#[cfg(feature = "stargate")] pub use crate::ibc::{ Ibc3ChannelOpenResponse, IbcAcknowledgement, IbcBasicResponse, IbcChannel, IbcChannelCloseMsg, IbcChannelConnectMsg, IbcChannelOpenMsg, IbcChannelOpenResponse, IbcEndpoint, IbcMsg, IbcOrder, @@ -46,24 +61,25 @@ pub use crate::ibc::{ #[cfg(feature = "iterator")] pub use crate::iterator::{Order, Record}; pub use crate::math::{ - Decimal, Decimal256, Decimal256RangeExceeded, DecimalRangeExceeded, Fraction, Isqrt, Uint128, - Uint256, Uint512, Uint64, + Decimal, Decimal256, Decimal256RangeExceeded, DecimalRangeExceeded, Fraction, Int128, Int256, + Int512, Int64, Isqrt, Uint128, Uint256, Uint512, Uint64, }; -#[cfg(feature = "cosmwasm_1_1")] -pub use crate::query::SupplyResponse; +pub use crate::metadata::{DenomMetadata, DenomUnit}; +pub use crate::never::Never; +pub use crate::pagination::PageRequest; pub use crate::query::{ - AllBalanceResponse, BalanceResponse, BankQuery, ContractInfoResponse, CustomQuery, - QueryRequest, WasmQuery, + AllBalanceResponse, AllDelegationsResponse, AllDenomMetadataResponse, AllValidatorsResponse, + BalanceResponse, BankQuery, BondedDenomResponse, ChannelResponse, CodeInfoResponse, + ContractInfoResponse, CustomQuery, DecCoin, Delegation, DelegationResponse, + DelegationRewardsResponse, DelegationTotalRewardsResponse, DelegatorReward, + DelegatorValidatorsResponse, DelegatorWithdrawAddressResponse, DenomMetadataResponse, + DistributionQuery, FullDelegation, IbcQuery, ListChannelsResponse, PortIdResponse, + QueryRequest, StakingQuery, SupplyResponse, Validator, ValidatorResponse, WasmQuery, }; -#[cfg(feature = "staking")] -pub use crate::query::{ - AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation, - DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse, -}; -#[cfg(feature = "stargate")] -pub use crate::query::{ChannelResponse, IbcQuery, ListChannelsResponse, PortIdResponse}; #[allow(deprecated)] pub use crate::results::SubMsgExecutionResponse; +#[cfg(all(feature = "stargate", feature = "cosmwasm_1_2"))] +pub use crate::results::WeightedVoteOption; pub use crate::results::{ attr, wasm_execute, wasm_instantiate, Attribute, BankMsg, ContractResult, CosmosMsg, CustomMsg, Empty, Event, QueryResponse, Reply, ReplyOn, Response, SubMsg, SubMsgResponse, SubMsgResult, @@ -74,6 +90,7 @@ pub use crate::results::{DistributionMsg, StakingMsg}; #[cfg(feature = "stargate")] pub use crate::results::{GovMsg, VoteOption}; pub use crate::serde::{from_binary, from_slice, to_binary, to_vec}; +pub use crate::stdack::StdAck; pub use crate::storage::MemoryStorage; pub use crate::timestamp::Timestamp; pub use crate::traits::{Api, Querier, QuerierResult, QuerierWrapper, Storage}; @@ -99,8 +116,8 @@ pub use crate::exports::{ #[cfg(target_arch = "wasm32")] pub use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage}; -// Exposed for testing only -// Both unit tests and integration tests are compiled to native code, so everything in here does not need to compile to Wasm. +/// Exposed for testing only +/// Both unit tests and integration tests are compiled to native code, so everything in here does not need to compile to Wasm. #[cfg(not(target_arch = "wasm32"))] pub mod testing; diff --git a/packages/std/src/math/decimal.rs b/packages/std/src/math/decimal.rs index d3859c74a..b8de3e90b 100644 --- a/packages/std/src/math/decimal.rs +++ b/packages/std/src/math/decimal.rs @@ -1,16 +1,17 @@ +use core::cmp::Ordering; +use core::fmt::{self, Write}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}; +use core::str::FromStr; use forward_ref::{forward_ref_binop, forward_ref_op_assign}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; -use std::cmp::Ordering; -use std::fmt::{self, Write}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}; -use std::str::FromStr; use thiserror::Error; use crate::errors::{ CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError, OverflowOperation, RoundUpOverflowError, StdError, }; +use crate::{forward_ref_partial_eq, Decimal256}; use super::Fraction; use super::Isqrt; @@ -19,9 +20,11 @@ use super::{Uint128, Uint256}; /// A fixed-point decimal value with 18 fractional digits, i.e. Decimal(1_000_000_000_000_000_000) == 1.0 /// /// The greatest possible value that can be represented is 340282366920938463463.374607431768211455 (which is (2^128 - 1) / 10^18) -#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] +#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] pub struct Decimal(#[schemars(with = "String")] Uint128); +forward_ref_partial_eq!(Decimal, Decimal); + #[derive(Error, Debug, PartialEq, Eq)] #[error("Decimal range exceeded")] pub struct DecimalRangeExceeded; @@ -64,13 +67,56 @@ impl Decimal { } /// Convert x% into Decimal - pub fn percent(x: u64) -> Self { - Self(((x as u128) * 10_000_000_000_000_000).into()) + /// + /// ## Examples + /// + /// ``` + /// # use std::str::FromStr; + /// # use cosmwasm_std::Decimal; + /// const HALF: Decimal = Decimal::percent(50); + /// + /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap()); + /// ``` + pub const fn percent(x: u64) -> Self { + // multiplication does not overflow since `u64::MAX` * 10**16 is well in u128 range + let atomics = (x as u128) * 10_000_000_000_000_000; + Self(Uint128::new(atomics)) } /// Convert permille (x/1000) into Decimal - pub fn permille(x: u64) -> Self { - Self(((x as u128) * 1_000_000_000_000_000).into()) + /// + /// ## Examples + /// + /// ``` + /// # use std::str::FromStr; + /// # use cosmwasm_std::Decimal; + /// const HALF: Decimal = Decimal::permille(500); + /// + /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap()); + /// ``` + pub const fn permille(x: u64) -> Self { + // multiplication does not overflow since `u64::MAX` * 10**15 is well in u128 range + let atomics = (x as u128) * 1_000_000_000_000_000; + Self(Uint128::new(atomics)) + } + + /// Convert basis points (x/10000) into Decimal + /// + /// ## Examples + /// + /// ``` + /// # use std::str::FromStr; + /// # use cosmwasm_std::Decimal; + /// const TWO_BPS: Decimal = Decimal::bps(2); + /// const HALF: Decimal = Decimal::bps(5000); + /// + /// assert_eq!(TWO_BPS, Decimal::from_str("0.0002").unwrap()); + /// assert_eq!(HALF, Decimal::from_str("0.5").unwrap()); + /// ``` + pub const fn bps(x: u64) -> Self { + // multiplication does not overflow since `u64::MAX` * 10**14 is well in u128 range + let atomics = (x as u128) * 100_000_000_000_000; + Self(Uint128::new(atomics)) } /// Creates a decimal from a number of atomic units and the number @@ -100,7 +146,7 @@ impl Decimal { ) -> Result { let atomics = atomics.into(); const TEN: Uint128 = Uint128::new(10); - Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES)) { + Ok(match decimal_places.cmp(&Self::DECIMAL_PLACES) { Ordering::Less => { let digits = (Self::DECIMAL_PLACES) - decimal_places; // No overflow because decimal_places < DECIMAL_PLACES let factor = TEN.checked_pow(digits).unwrap(); // Safe because digits <= 17 @@ -155,6 +201,7 @@ impl Decimal { } } + #[must_use] pub const fn is_zero(&self) -> bool { self.0.is_zero() } @@ -166,7 +213,7 @@ impl Decimal { /// /// ``` /// # use cosmwasm_std::{Decimal, Uint128}; - /// # use std::str::FromStr; + /// # use core::str::FromStr; /// // Value with whole and fractional part /// let a = Decimal::from_str("1.234").unwrap(); /// assert_eq!(a.decimal_places(), 18); @@ -177,6 +224,7 @@ impl Decimal { /// assert_eq!(b.decimal_places(), 18); /// assert_eq!(b.atomics(), Uint128::new(1)); /// ``` + #[must_use] #[inline] pub const fn atomics(&self) -> Uint128 { self.0 @@ -186,17 +234,20 @@ impl Decimal { /// but this could potentially change as the type evolves. /// /// See also [`Decimal::atomics()`]. + #[must_use] #[inline] pub const fn decimal_places(&self) -> u32 { Self::DECIMAL_PLACES } /// Rounds value down after decimal places. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn floor(&self) -> Self { Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL) } /// Rounds value up after decimal places. Panics on overflow. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn ceil(&self) -> Self { match self.checked_ceil() { Ok(value) => value, @@ -245,6 +296,7 @@ impl Decimal { } /// Raises a value to the power of `exp`, panics if an overflow occurred. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn pow(self, exp: u32) -> Self { match self.checked_pow(exp) { Ok(value) => value, @@ -299,7 +351,7 @@ impl Decimal { /// Returns the approximate square root as a Decimal. /// /// This should not overflow or panic. - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn sqrt(&self) -> Self { // Algorithm described in https://hackmd.io/@webmaster128/SJThlukj_ // We start with the highest precision possible and lower it until @@ -319,6 +371,7 @@ impl Decimal { /// Precision *must* be a number between 0 and 9 (inclusive). /// /// Returns `None` if the internal multiplication overflows. + #[must_use = "this returns the result of the operation, without modifying the original"] fn sqrt_with_precision(&self, precision: u32) -> Option { let inner_mul = 100u128.pow(precision); self.0.checked_mul(inner_mul.into()).ok().map(|inner| { @@ -327,10 +380,12 @@ impl Decimal { }) } + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn abs_diff(self, other: Self) -> Self { Self(self.0.abs_diff(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_add(self, other: Self) -> Self { match self.checked_add(other) { Ok(value) => value, @@ -338,6 +393,7 @@ impl Decimal { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_sub(self, other: Self) -> Self { match self.checked_sub(other) { Ok(value) => value, @@ -345,6 +401,7 @@ impl Decimal { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_mul(self, other: Self) -> Self { match self.checked_mul(other) { Ok(value) => value, @@ -352,12 +409,67 @@ impl Decimal { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_pow(self, exp: u32) -> Self { match self.checked_pow(exp) { Ok(value) => value, Err(_) => Self::MAX, } } + + /// Converts this decimal to an unsigned integer by truncating + /// the fractional part, e.g. 22.5 becomes 22. + /// + /// ## Examples + /// + /// ``` + /// use core::str::FromStr; + /// use cosmwasm_std::{Decimal, Uint128}; + /// + /// let d = Decimal::from_str("12.345").unwrap(); + /// assert_eq!(d.to_uint_floor(), Uint128::new(12)); + /// + /// let d = Decimal::from_str("12.999").unwrap(); + /// assert_eq!(d.to_uint_floor(), Uint128::new(12)); + /// + /// let d = Decimal::from_str("75.0").unwrap(); + /// assert_eq!(d.to_uint_floor(), Uint128::new(75)); + /// ``` + #[must_use] + pub fn to_uint_floor(self) -> Uint128 { + self.0 / Self::DECIMAL_FRACTIONAL + } + + /// Converts this decimal to an unsigned integer by rounting up + /// to the next integer, e.g. 22.3 becomes 23. + /// + /// ## Examples + /// + /// ``` + /// use core::str::FromStr; + /// use cosmwasm_std::{Decimal, Uint128}; + /// + /// let d = Decimal::from_str("12.345").unwrap(); + /// assert_eq!(d.to_uint_ceil(), Uint128::new(13)); + /// + /// let d = Decimal::from_str("12.999").unwrap(); + /// assert_eq!(d.to_uint_ceil(), Uint128::new(13)); + /// + /// let d = Decimal::from_str("75.0").unwrap(); + /// assert_eq!(d.to_uint_ceil(), Uint128::new(75)); + /// ``` + #[must_use] + pub fn to_uint_ceil(self) -> Uint128 { + // Using `q = 1 + ((x - 1) / y); // if x != 0` with unsigned integers x, y, q + // from https://stackoverflow.com/a/2745086/2013738. We know `x + y` CAN overflow. + let x = self.0; + let y = Self::DECIMAL_FRACTIONAL; + if x.is_zero() { + Uint128::zero() + } else { + Uint128::one() + ((x - Uint128::one()) / y) + } + } } impl Fraction for Decimal { @@ -386,6 +498,18 @@ impl Fraction for Decimal { } } +impl TryFrom for Decimal { + type Error = DecimalRangeExceeded; + + fn try_from(value: Decimal256) -> Result { + value + .atomics() + .try_into() + .map(Decimal) + .map_err(|_| DecimalRangeExceeded) + } +} + impl FromStr for Decimal { type Err = StdError; @@ -443,7 +567,7 @@ impl fmt::Display for Decimal { let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap(); if fractional.is_zero() { - write!(f, "{}", whole) + write!(f, "{whole}") } else { let fractional_string = format!( "{:0>padding$}", @@ -458,6 +582,12 @@ impl fmt::Display for Decimal { } } +impl fmt::Debug for Decimal { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Decimal({self})") + } +} + impl Add for Decimal { type Output = Self; @@ -599,7 +729,7 @@ impl RemAssign for Decimal { } forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal, Decimal); -impl std::iter::Sum for Decimal +impl core::iter::Sum for Decimal where Self: Add, { @@ -643,23 +773,11 @@ impl<'de> de::Visitor<'de> for DecimalVisitor { { match Decimal::from_str(v) { Ok(d) => Ok(d), - Err(e) => Err(E::custom(format!("Error parsing decimal '{}': {}", v, e))), + Err(e) => Err(E::custom(format!("Error parsing decimal '{v}': {e}"))), } } } -impl PartialEq<&Decimal> for Decimal { - fn eq(&self, rhs: &&Decimal) -> bool { - self == *rhs - } -} - -impl PartialEq for &Decimal { - fn eq(&self, rhs: &Decimal) -> bool { - *self == rhs - } -} - #[cfg(test)] mod tests { use super::*; @@ -705,6 +823,28 @@ mod tests { assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(8u8)); } + #[test] + fn decimal_bps() { + let value = Decimal::bps(125); + assert_eq!(value.0, Decimal::DECIMAL_FRACTIONAL / Uint128::from(80u8)); + } + + #[test] + fn decimal_from_decimal256_works() { + let too_big = Decimal256::new(Uint256::from(Uint128::MAX) + Uint256::one()); + assert_eq!(Decimal::try_from(too_big), Err(DecimalRangeExceeded)); + + let just_right = Decimal256::new(Uint256::from(Uint128::MAX)); + assert_eq!(Decimal::try_from(just_right), Ok(Decimal::MAX)); + + assert_eq!(Decimal::try_from(Decimal256::zero()), Ok(Decimal::zero())); + assert_eq!(Decimal::try_from(Decimal256::one()), Ok(Decimal::one())); + assert_eq!( + Decimal::try_from(Decimal256::percent(50)), + Ok(Decimal::percent(50)) + ); + } + #[test] fn decimal_from_atomics_works() { let one = Decimal::one(); @@ -914,17 +1054,17 @@ mod tests { fn decimal_from_str_errors_for_broken_whole_part() { match Decimal::from_str("").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str(" ").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str("-1").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -932,22 +1072,22 @@ mod tests { fn decimal_from_str_errors_for_broken_fractinal_part() { match Decimal::from_str("1.").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str("1. ").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str("1.e").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str("1.2e3").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -957,7 +1097,7 @@ mod tests { StdError::GenericErr { msg, .. } => { assert_eq!(msg, "Cannot parse more than 18 fractional digits",) } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } // No special rules for trailing zeros. This could be changed but adds gas cost for the happy path. @@ -965,7 +1105,7 @@ mod tests { StdError::GenericErr { msg, .. } => { assert_eq!(msg, "Cannot parse more than 18 fractional digits") } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -973,12 +1113,12 @@ mod tests { fn decimal_from_str_errors_for_invalid_number_of_dots() { match Decimal::from_str("1.2.3").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str("1.2.3.4").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -987,17 +1127,17 @@ mod tests { // Integer match Decimal::from_str("340282366920938463464").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } // Decimal match Decimal::from_str("340282366920938463464.0").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal::from_str("340282366920938463463.374607431768211456").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1334,7 +1474,7 @@ mod tests { (Decimal::permille(6), Decimal::permille(13)), ]; - // The regular std::ops::Mul is our source of truth for these tests. + // The regular core::ops::Mul is our source of truth for these tests. for (x, y) in test_data.into_iter() { assert_eq!(x * y, x.checked_mul(y).unwrap()); } @@ -1928,7 +2068,7 @@ mod tests { #[test] #[should_panic] fn decimal_pow_overflow_panics() { - Decimal::MAX.pow(2u32); + _ = Decimal::MAX.pow(2u32); } #[test] @@ -1997,6 +2137,57 @@ mod tests { )); } + #[test] + fn decimal_to_uint_floor_works() { + let d = Decimal::from_str("12.000000000000000001").unwrap(); + assert_eq!(d.to_uint_floor(), Uint128::new(12)); + let d = Decimal::from_str("12.345").unwrap(); + assert_eq!(d.to_uint_floor(), Uint128::new(12)); + let d = Decimal::from_str("12.999").unwrap(); + assert_eq!(d.to_uint_floor(), Uint128::new(12)); + let d = Decimal::from_str("0.98451384").unwrap(); + assert_eq!(d.to_uint_floor(), Uint128::new(0)); + + let d = Decimal::from_str("75.0").unwrap(); + assert_eq!(d.to_uint_floor(), Uint128::new(75)); + let d = Decimal::from_str("0.0").unwrap(); + assert_eq!(d.to_uint_floor(), Uint128::new(0)); + + let d = Decimal::MAX; + assert_eq!(d.to_uint_floor(), Uint128::new(340282366920938463463)); + + // Does the same as the old workaround `Uint128::one() * my_decimal`. + // This block can be deleted as part of https://github.com/CosmWasm/cosmwasm/issues/1485. + let tests = vec![ + Decimal::from_str("12.345").unwrap(), + Decimal::from_str("0.98451384").unwrap(), + Decimal::from_str("178.0").unwrap(), + Decimal::MIN, + Decimal::MAX, + ]; + for my_decimal in tests.into_iter() { + assert_eq!(my_decimal.to_uint_floor(), Uint128::one() * my_decimal); + } + } + + #[test] + fn decimal_to_uint_ceil_works() { + let d = Decimal::from_str("12.000000000000000001").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint128::new(13)); + let d = Decimal::from_str("12.345").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint128::new(13)); + let d = Decimal::from_str("12.999").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint128::new(13)); + + let d = Decimal::from_str("75.0").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint128::new(75)); + let d = Decimal::from_str("0.0").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint128::new(0)); + + let d = Decimal::MAX; + assert_eq!(d.to_uint_ceil(), Uint128::new(340282366920938463464)); + } + #[test] fn decimal_partial_eq() { let test_cases = [ @@ -2016,4 +2207,17 @@ mod tests { assert_eq!(&lhs == &rhs, expected); } } + + #[test] + fn decimal_implements_debug() { + let decimal = Decimal::from_str("123.45").unwrap(); + assert_eq!(format!("{decimal:?}"), "Decimal(123.45)"); + + let test_cases = ["5", "5.01", "42", "0", "2"]; + for s in test_cases { + let decimal = Decimal::from_str(s).unwrap(); + let expected = format!("Decimal({s})"); + assert_eq!(format!("{decimal:?}"), expected); + } + } } diff --git a/packages/std/src/math/decimal256.rs b/packages/std/src/math/decimal256.rs index c39a4e3bd..f3fea968c 100644 --- a/packages/std/src/math/decimal256.rs +++ b/packages/std/src/math/decimal256.rs @@ -1,17 +1,17 @@ +use core::cmp::Ordering; +use core::fmt::{self, Write}; +use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}; +use core::str::FromStr; use forward_ref::{forward_ref_binop, forward_ref_op_assign}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; -use std::cmp::Ordering; -use std::fmt::{self, Write}; -use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Sub, SubAssign}; -use std::str::FromStr; use thiserror::Error; use crate::errors::{ CheckedFromRatioError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError, OverflowOperation, RoundUpOverflowError, StdError, }; -use crate::{Decimal, Uint512}; +use crate::{forward_ref_partial_eq, Decimal, Uint512}; use super::Fraction; use super::Isqrt; @@ -22,9 +22,11 @@ use super::Uint256; /// The greatest possible value that can be represented is /// 115792089237316195423570985008687907853269984665640564039457.584007913129639935 /// (which is (2^256 - 1) / 10^18) -#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] +#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] pub struct Decimal256(#[schemars(with = "String")] Uint256); +forward_ref_partial_eq!(Decimal256, Decimal256); + #[derive(Error, Debug, PartialEq, Eq)] #[error("Decimal256 range exceeded")] pub struct Decimal256RangeExceeded; @@ -74,13 +76,56 @@ impl Decimal256 { } /// Convert x% into Decimal256 - pub fn percent(x: u64) -> Self { - Self(Uint256::from(x) * Uint256::from(10_000_000_000_000_000u128)) + /// + /// ## Examples + /// + /// ``` + /// # use std::str::FromStr; + /// # use cosmwasm_std::Decimal256; + /// const HALF: Decimal256 = Decimal256::percent(50); + /// + /// assert_eq!(HALF, Decimal256::from_str("0.5").unwrap()); + /// ``` + pub const fn percent(x: u64) -> Self { + // multiplication does not overflow since `u64::MAX` * 10**16 is well in u128 range + let atomics = (x as u128) * 10_000_000_000_000_000; + Self(Uint256::from_u128(atomics)) } /// Convert permille (x/1000) into Decimal256 - pub fn permille(x: u64) -> Self { - Self(Uint256::from(x) * Uint256::from(1_000_000_000_000_000u128)) + /// + /// ## Examples + /// + /// ``` + /// # use std::str::FromStr; + /// # use cosmwasm_std::Decimal256; + /// const HALF: Decimal256 = Decimal256::permille(500); + /// + /// assert_eq!(HALF, Decimal256::from_str("0.5").unwrap()); + /// ``` + pub const fn permille(x: u64) -> Self { + // multiplication does not overflow since `u64::MAX` * 10**15 is well in u128 range + let atomics = (x as u128) * 1_000_000_000_000_000; + Self(Uint256::from_u128(atomics)) + } + + /// Convert basis points (x/10000) into Decimal256 + /// + /// ## Examples + /// + /// ``` + /// # use std::str::FromStr; + /// # use cosmwasm_std::Decimal256; + /// const TWO_BPS: Decimal256 = Decimal256::bps(2); + /// const HALF: Decimal256 = Decimal256::bps(5000); + /// + /// assert_eq!(TWO_BPS, Decimal256::from_str("0.0002").unwrap()); + /// assert_eq!(HALF, Decimal256::from_str("0.5").unwrap()); + /// ``` + pub const fn bps(x: u64) -> Self { + // multiplication does not overflow since `u64::MAX` * 10**14 is well in u128 range + let atomics = (x as u128) * 100_000_000_000_000; + Self(Uint256::from_u128(atomics)) } /// Creates a decimal from a number of atomic units and the number @@ -112,11 +157,14 @@ impl Decimal256 { decimal_places: u32, ) -> Result { let atomics = atomics.into(); - let ten = Uint256::from(10u64); // TODO: make const - Ok(match decimal_places.cmp(&(Self::DECIMAL_PLACES)) { + const TEN: Uint256 = Uint256::from_be_bytes([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, + ]); + Ok(match decimal_places.cmp(&Self::DECIMAL_PLACES) { Ordering::Less => { let digits = (Self::DECIMAL_PLACES) - decimal_places; // No overflow because decimal_places < DECIMAL_PLACES - let factor = ten.checked_pow(digits).unwrap(); // Safe because digits <= 17 + let factor = TEN.checked_pow(digits).unwrap(); // Safe because digits <= 17 Self( atomics .checked_mul(factor) @@ -126,7 +174,7 @@ impl Decimal256 { Ordering::Equal => Self(atomics), Ordering::Greater => { let digits = decimal_places - (Self::DECIMAL_PLACES); // No overflow because decimal_places > DECIMAL_PLACES - if let Ok(factor) = ten.checked_pow(digits) { + if let Ok(factor) = TEN.checked_pow(digits) { Self(atomics.checked_div(factor).unwrap()) // Safe because factor cannot be zero } else { // In this case `factor` exceeds the Uint256 range. @@ -168,6 +216,7 @@ impl Decimal256 { } } + #[must_use] pub const fn is_zero(&self) -> bool { self.0.is_zero() } @@ -179,7 +228,7 @@ impl Decimal256 { /// /// ``` /// # use cosmwasm_std::{Decimal256, Uint256}; - /// # use std::str::FromStr; + /// # use core::str::FromStr; /// // Value with whole and fractional part /// let a = Decimal256::from_str("1.234").unwrap(); /// assert_eq!(a.decimal_places(), 18); @@ -190,6 +239,7 @@ impl Decimal256 { /// assert_eq!(b.decimal_places(), 18); /// assert_eq!(b.atomics(), Uint256::from(1u128)); /// ``` + #[must_use] #[inline] pub const fn atomics(&self) -> Uint256 { self.0 @@ -199,17 +249,20 @@ impl Decimal256 { /// but this could potentially change as the type evolves. /// /// See also [`Decimal256::atomics()`]. + #[must_use] #[inline] pub const fn decimal_places(&self) -> u32 { Self::DECIMAL_PLACES } /// Rounds value down after decimal places. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn floor(&self) -> Self { Self((self.0 / Self::DECIMAL_FRACTIONAL) * Self::DECIMAL_FRACTIONAL) } /// Rounds value up after decimal places. Panics on overflow. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn ceil(&self) -> Self { match self.checked_ceil() { Ok(value) => value, @@ -258,6 +311,7 @@ impl Decimal256 { } /// Raises a value to the power of `exp`, panics if an overflow occurred. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn pow(self, exp: u32) -> Self { match self.checked_pow(exp) { Ok(value) => value, @@ -312,7 +366,7 @@ impl Decimal256 { /// Returns the approximate square root as a Decimal256. /// /// This should not overflow or panic. - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn sqrt(&self) -> Self { // Algorithm described in https://hackmd.io/@webmaster128/SJThlukj_ // We start with the highest precision possible and lower it until @@ -332,6 +386,7 @@ impl Decimal256 { /// Precision *must* be a number between 0 and 9 (inclusive). /// /// Returns `None` if the internal multiplication overflows. + #[must_use = "this returns the result of the operation, without modifying the original"] fn sqrt_with_precision(&self, precision: u32) -> Option { let inner_mul = Uint256::from(100u128).pow(precision); self.0.checked_mul(inner_mul).ok().map(|inner| { @@ -340,6 +395,7 @@ impl Decimal256 { }) } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn abs_diff(self, other: Self) -> Self { if self < other { other - self @@ -348,6 +404,7 @@ impl Decimal256 { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_add(self, other: Self) -> Self { match self.checked_add(other) { Ok(value) => value, @@ -355,6 +412,7 @@ impl Decimal256 { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_sub(self, other: Self) -> Self { match self.checked_sub(other) { Ok(value) => value, @@ -362,6 +420,7 @@ impl Decimal256 { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_mul(self, other: Self) -> Self { match self.checked_mul(other) { Ok(value) => value, @@ -369,12 +428,67 @@ impl Decimal256 { } } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_pow(self, exp: u32) -> Self { match self.checked_pow(exp) { Ok(value) => value, Err(_) => Self::MAX, } } + + /// Converts this decimal to an unsigned integer by truncating + /// the fractional part, e.g. 22.5 becomes 22. + /// + /// ## Examples + /// + /// ``` + /// use core::str::FromStr; + /// use cosmwasm_std::{Decimal256, Uint256}; + /// + /// let d = Decimal256::from_str("12.345").unwrap(); + /// assert_eq!(d.to_uint_floor(), Uint256::from(12u64)); + /// + /// let d = Decimal256::from_str("12.999").unwrap(); + /// assert_eq!(d.to_uint_floor(), Uint256::from(12u64)); + /// + /// let d = Decimal256::from_str("75.0").unwrap(); + /// assert_eq!(d.to_uint_floor(), Uint256::from(75u64)); + /// ``` + #[must_use] + pub fn to_uint_floor(self) -> Uint256 { + self.0 / Self::DECIMAL_FRACTIONAL + } + + /// Converts this decimal to an unsigned integer by rounting up + /// to the next integer, e.g. 22.3 becomes 23. + /// + /// ## Examples + /// + /// ``` + /// use core::str::FromStr; + /// use cosmwasm_std::{Decimal256, Uint256}; + /// + /// let d = Decimal256::from_str("12.345").unwrap(); + /// assert_eq!(d.to_uint_ceil(), Uint256::from(13u64)); + /// + /// let d = Decimal256::from_str("12.999").unwrap(); + /// assert_eq!(d.to_uint_ceil(), Uint256::from(13u64)); + /// + /// let d = Decimal256::from_str("75.0").unwrap(); + /// assert_eq!(d.to_uint_ceil(), Uint256::from(75u64)); + /// ``` + #[must_use] + pub fn to_uint_ceil(self) -> Uint256 { + // Using `q = 1 + ((x - 1) / y); // if x != 0` with unsigned integers x, y, q + // from https://stackoverflow.com/a/2745086/2013738. We know `x + y` CAN overflow. + let x = self.0; + let y = Self::DECIMAL_FRACTIONAL; + if x.is_zero() { + Uint256::zero() + } else { + Uint256::one() + ((x - Uint256::one()) / y) + } + } } impl Fraction for Decimal256 { @@ -468,7 +582,7 @@ impl fmt::Display for Decimal256 { let fractional = (self.0).checked_rem(Self::DECIMAL_FRACTIONAL).unwrap(); if fractional.is_zero() { - write!(f, "{}", whole) + write!(f, "{whole}") } else { let fractional_string = format!( "{:0>padding$}", @@ -483,6 +597,12 @@ impl fmt::Display for Decimal256 { } } +impl fmt::Debug for Decimal256 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Decimal256({self})") + } +} + impl Add for Decimal256 { type Output = Self; @@ -624,7 +744,7 @@ impl RemAssign for Decimal256 { } forward_ref_op_assign!(impl RemAssign, rem_assign for Decimal256, Decimal256); -impl std::iter::Sum for Decimal256 +impl core::iter::Sum for Decimal256 where Self: Add, { @@ -668,23 +788,11 @@ impl<'de> de::Visitor<'de> for Decimal256Visitor { { match Self::Value::from_str(v) { Ok(d) => Ok(d), - Err(e) => Err(E::custom(format!("Error parsing decimal '{}': {}", v, e))), + Err(e) => Err(E::custom(format!("Error parsing decimal '{v}': {e}"))), } } } -impl PartialEq<&Decimal256> for Decimal256 { - fn eq(&self, rhs: &&Decimal256) -> bool { - self == *rhs - } -} - -impl PartialEq for &Decimal256 { - fn eq(&self, rhs: &Decimal256) -> bool { - *self == rhs - } -} - #[cfg(test)] mod tests { use super::*; @@ -732,6 +840,15 @@ mod tests { assert_eq!(value.0, Decimal256::DECIMAL_FRACTIONAL / Uint256::from(8u8)); } + #[test] + fn decimal256_bps() { + let value = Decimal256::bps(125); + assert_eq!( + value.0, + Decimal256::DECIMAL_FRACTIONAL / Uint256::from(80u8) + ); + } + #[test] fn decimal256_from_atomics_works() { let one = Decimal256::one(); @@ -1013,17 +1130,17 @@ mod tests { fn decimal256_from_str_errors_for_broken_whole_part() { match Decimal256::from_str("").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str(" ").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str("-1").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing whole"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1031,22 +1148,22 @@ mod tests { fn decimal256_from_str_errors_for_broken_fractinal_part() { match Decimal256::from_str("1.").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str("1. ").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str("1.e").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str("1.2e3").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Error parsing fractional"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1056,7 +1173,7 @@ mod tests { StdError::GenericErr { msg, .. } => { assert_eq!(msg, "Cannot parse more than 18 fractional digits") } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } // No special rules for trailing zeros. This could be changed but adds gas cost for the happy path. @@ -1064,7 +1181,7 @@ mod tests { StdError::GenericErr { msg, .. } => { assert_eq!(msg, "Cannot parse more than 18 fractional digits") } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1072,12 +1189,12 @@ mod tests { fn decimal256_from_str_errors_for_invalid_number_of_dots() { match Decimal256::from_str("1.2.3").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str("1.2.3.4").unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Unexpected number of dots"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1088,7 +1205,7 @@ mod tests { .unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } // Decimal @@ -1096,7 +1213,7 @@ mod tests { .unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } match Decimal256::from_str( "115792089237316195423570985008687907853269984665640564039457.584007913129639936", @@ -1104,7 +1221,7 @@ mod tests { .unwrap_err() { StdError::GenericErr { msg, .. } => assert_eq!(msg, "Value too big"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1453,7 +1570,7 @@ mod tests { (Decimal256::permille(6), Decimal256::permille(13)), ]; - // The regular std::ops::Mul is our source of truth for these tests. + // The regular core::ops::Mul is our source of truth for these tests. for (x, y) in test_data.into_iter() { assert_eq!(x * y, x.checked_mul(y).unwrap()); } @@ -1994,7 +2111,7 @@ mod tests { } #[test] - #[should_panic(expected = "division by zero")] + #[should_panic(expected = "divisor of zero")] fn decimal256_rem_panics_for_zero() { let _ = Decimal256::percent(777) % Decimal256::zero(); } @@ -2078,7 +2195,7 @@ mod tests { #[test] #[should_panic] fn decimal256_pow_overflow_panics() { - Decimal256::MAX.pow(2u32); + _ = Decimal256::MAX.pow(2u32); } #[test] @@ -2144,6 +2261,65 @@ mod tests { assert_eq!(Decimal256::MAX.checked_ceil(), Err(RoundUpOverflowError)); } + #[test] + fn decimal256_to_uint_floor_works() { + let d = Decimal256::from_str("12.000000000000000001").unwrap(); + assert_eq!(d.to_uint_floor(), Uint256::from_u128(12)); + let d = Decimal256::from_str("12.345").unwrap(); + assert_eq!(d.to_uint_floor(), Uint256::from_u128(12)); + let d = Decimal256::from_str("12.999").unwrap(); + assert_eq!(d.to_uint_floor(), Uint256::from_u128(12)); + let d = Decimal256::from_str("0.98451384").unwrap(); + assert_eq!(d.to_uint_floor(), Uint256::from_u128(0)); + + let d = Decimal256::from_str("75.0").unwrap(); + assert_eq!(d.to_uint_floor(), Uint256::from_u128(75)); + let d = Decimal256::from_str("0.0").unwrap(); + assert_eq!(d.to_uint_floor(), Uint256::from_u128(0)); + + let d = Decimal256::MAX; + assert_eq!( + d.to_uint_floor(), + Uint256::from_str("115792089237316195423570985008687907853269984665640564039457") + .unwrap() + ); + + // Does the same as the old workaround `Uint256::one() * my_decimal`. + // This block can be deleted as part of https://github.com/CosmWasm/cosmwasm/issues/1485. + let tests = vec![ + Decimal256::from_str("12.345").unwrap(), + Decimal256::from_str("0.98451384").unwrap(), + Decimal256::from_str("178.0").unwrap(), + Decimal256::MIN, + Decimal256::MAX, + ]; + for my_decimal in tests.into_iter() { + assert_eq!(my_decimal.to_uint_floor(), Uint256::one() * my_decimal); + } + } + + #[test] + fn decimal256_to_uint_ceil_works() { + let d = Decimal256::from_str("12.000000000000000001").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint256::from_u128(13)); + let d = Decimal256::from_str("12.345").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint256::from_u128(13)); + let d = Decimal256::from_str("12.999").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint256::from_u128(13)); + + let d = Decimal256::from_str("75.0").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint256::from_u128(75)); + let d = Decimal256::from_str("0.0").unwrap(); + assert_eq!(d.to_uint_ceil(), Uint256::from_u128(0)); + + let d = Decimal256::MAX; + assert_eq!( + d.to_uint_ceil(), + Uint256::from_str("115792089237316195423570985008687907853269984665640564039458") + .unwrap() + ); + } + #[test] fn decimal256_partial_eq() { let test_cases = [ @@ -2163,4 +2339,17 @@ mod tests { assert_eq!(&lhs == &rhs, expected); } } + + #[test] + fn decimal256_implements_debug() { + let decimal = Decimal256::from_str("123.45").unwrap(); + assert_eq!(format!("{decimal:?}"), "Decimal256(123.45)"); + + let test_cases = ["5", "5.01", "42", "0", "2"]; + for s in test_cases { + let decimal256 = Decimal256::from_str(s).unwrap(); + let expected = format!("Decimal256({s})"); + assert_eq!(format!("{decimal256:?}"), expected); + } + } } diff --git a/packages/std/src/math/fraction.rs b/packages/std/src/math/fraction.rs index ca187ad78..c13c74618 100644 --- a/packages/std/src/math/fraction.rs +++ b/packages/std/src/math/fraction.rs @@ -10,5 +10,182 @@ pub trait Fraction: Sized { /// Returns the multiplicative inverse `q/p` for fraction `p/q`. /// /// If `p` is zero, None is returned. + #[must_use = "this returns the result of the operation, without modifying the original"] fn inv(&self) -> Option; } + +impl + PartialEq> Fraction for (T, T) { + fn numerator(&self) -> T { + self.0 + } + + fn denominator(&self) -> T { + self.1 + } + + fn inv(&self) -> Option { + if self.numerator() == 0u8.into() { + None + } else { + Some((self.1, self.0)) + } + } +} + +#[macro_export] +macro_rules! impl_mul_fraction { + ($Uint:ident) => { + impl $Uint { + /// Multiply `self` with a struct implementing [`Fraction`] (e.g. [`crate::Decimal`]). + /// Result is rounded down. + /// + /// ## Examples + /// + /// ``` + /// use cosmwasm_std::Uint128; + /// let fraction = (8u128, 21u128); + /// let res = Uint128::new(123456).checked_mul_floor(fraction).unwrap(); + /// assert_eq!(Uint128::new(47030), res); // 47030.8571 rounds down + /// ``` + pub fn checked_mul_floor, T: Into<$Uint>>( + self, + rhs: F, + ) -> Result { + let divisor = rhs.denominator().into(); + let res = self + .full_mul(rhs.numerator().into()) + .checked_div(divisor.into())?; + Ok(res.try_into()?) + } + + /// Same operation as `checked_mul_floor` except unwrapped + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn mul_floor, T: Into<$Uint>>(self, rhs: F) -> Self { + self.checked_mul_floor(rhs).unwrap() + } + + /// Multiply `self` with a struct implementing [`Fraction`] (e.g. [`crate::Decimal`]). + /// Result is rounded up. + /// + /// ## Examples + /// + /// ``` + /// use cosmwasm_std::Uint128; + /// let fraction = (8u128, 21u128); + /// let res = Uint128::new(123456).checked_mul_ceil(fraction).unwrap(); + /// assert_eq!(Uint128::new(47031), res); // 47030.8571 rounds up + /// ``` + pub fn checked_mul_ceil, T: Into<$Uint>>( + self, + rhs: F, + ) -> Result { + let dividend = self.full_mul(rhs.numerator().into()); + let divisor = rhs.denominator().into().into(); + let floor_result = dividend.checked_div(divisor)?.try_into()?; + let remainder = dividend.checked_rem(divisor)?; + if !remainder.is_zero() { + Ok($Uint::one().checked_add(floor_result)?) + } else { + Ok(floor_result) + } + } + + /// Same operation as `checked_mul_ceil` except unwrapped + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn mul_ceil, T: Into<$Uint>>(self, rhs: F) -> Self { + self.checked_mul_ceil(rhs).unwrap() + } + + /// Divide `self` with a struct implementing [`Fraction`] (e.g. [`crate::Decimal`]). + /// Result is rounded down. + /// + /// ## Examples + /// + /// ``` + /// use cosmwasm_std::Uint128; + /// let fraction = (4u128, 5u128); + /// let res = Uint128::new(789).checked_div_floor(fraction).unwrap(); + /// assert_eq!(Uint128::new(986), res); // 986.25 rounds down + /// ``` + pub fn checked_div_floor, T: Into<$Uint>>( + self, + rhs: F, + ) -> Result + where + Self: Sized, + { + let divisor = rhs.numerator().into(); + let res = self + .full_mul(rhs.denominator().into()) + .checked_div(divisor.into())?; + Ok(res.try_into()?) + } + + /// Same operation as `checked_div_floor` except unwrapped + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn div_floor, T: Into<$Uint>>(self, rhs: F) -> Self + where + Self: Sized, + { + self.checked_div_floor(rhs).unwrap() + } + + /// Divide `self` with a struct implementing [`Fraction`] (e.g. [`crate::Decimal`]). + /// Result is rounded up. + /// + /// ## Examples + /// + /// ``` + /// use cosmwasm_std::Uint128; + /// let fraction = (4u128, 5u128); + /// let res = Uint128::new(789).checked_div_ceil(fraction).unwrap(); + /// assert_eq!(Uint128::new(987), res); // 986.25 rounds up + /// ``` + pub fn checked_div_ceil, T: Into<$Uint>>( + self, + rhs: F, + ) -> Result + where + Self: Sized, + { + let dividend = self.full_mul(rhs.denominator().into()); + let divisor = rhs.numerator().into().into(); + let floor_result = dividend.checked_div(divisor)?.try_into()?; + let remainder = dividend.checked_rem(divisor)?; + if !remainder.is_zero() { + Ok($Uint::one().checked_add(floor_result)?) + } else { + Ok(floor_result) + } + } + + /// Same operation as `checked_div_ceil` except unwrapped + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn div_ceil, T: Into<$Uint>>(self, rhs: F) -> Self + where + Self: Sized, + { + self.checked_div_ceil(rhs).unwrap() + } + } + }; +} + +#[cfg(test)] +mod tests { + use crate::{Fraction, Uint128, Uint64}; + + #[test] + fn fraction_tuple_methods() { + let fraction = (Uint64::one(), Uint64::new(2)); + assert_eq!(Uint64::one(), fraction.numerator()); + assert_eq!(Uint64::new(2), fraction.denominator()); + assert_eq!(Some((Uint64::new(2), Uint64::one())), fraction.inv()); + } + + #[test] + fn inverse_with_zero_denominator() { + let fraction = (Uint128::zero(), Uint128::one()); + assert_eq!(None, fraction.inv()); + } +} diff --git a/packages/std/src/math/int128.rs b/packages/std/src/math/int128.rs new file mode 100644 index 000000000..cc0b7c83b --- /dev/null +++ b/packages/std/src/math/int128.rs @@ -0,0 +1,1113 @@ +use core::fmt; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, + ShrAssign, Sub, SubAssign, +}; +use core::str::FromStr; +use forward_ref::{forward_ref_binop, forward_ref_op_assign}; +use schemars::JsonSchema; +use serde::{de, ser, Deserialize, Deserializer, Serialize}; + +use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError}; +use crate::{forward_ref_partial_eq, Int64, Uint128, Uint64}; + +/// An implementation of i128 that is using strings for JSON encoding/decoding, +/// such that the full i128 range can be used for clients that convert JSON numbers to floats, +/// like JavaScript and jq. +/// +/// # Examples +/// +/// Use `from` to create instances of this and `i128` to get the value out: +/// +/// ``` +/// # use cosmwasm_std::Int128; +/// let a = Int128::from(258i128); +/// assert_eq!(a.i128(), 258); +/// ``` +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] +pub struct Int128(#[schemars(with = "String")] i128); + +forward_ref_partial_eq!(Int128, Int128); + +impl Int128 { + pub const MAX: Int128 = Int128(i128::MAX); + pub const MIN: Int128 = Int128(i128::MIN); + + /// Creates a Int128(value). + /// + /// This method is less flexible than `from` but can be called in a const context. + #[inline] + pub const fn new(value: i128) -> Self { + Self(value) + } + + /// Creates a Int128(0) + #[inline] + pub const fn zero() -> Self { + Int128(0) + } + + /// Creates a Int128(1) + #[inline] + pub const fn one() -> Self { + Self(1) + } + + /// Returns a copy of the internal data + pub const fn i128(&self) -> i128 { + self.0 + } + + #[must_use] + pub const fn from_be_bytes(data: [u8; 16]) -> Self { + Self(i128::from_be_bytes(data)) + } + + #[must_use] + pub const fn from_le_bytes(data: [u8; 16]) -> Self { + Self(i128::from_le_bytes(data)) + } + + /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_be_bytes(self) -> [u8; 16] { + self.0.to_be_bytes() + } + + /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_le_bytes(self) -> [u8; 16] { + self.0.to_le_bytes() + } + + #[must_use] + pub const fn is_zero(&self) -> bool { + self.0 == 0 + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn pow(self, exp: u32) -> Self { + Self(self.0.pow(exp)) + } + + pub fn checked_add(self, other: Self) -> Result { + self.0 + .checked_add(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Add, self, other)) + } + + pub fn checked_sub(self, other: Self) -> Result { + self.0 + .checked_sub(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Sub, self, other)) + } + + pub fn checked_mul(self, other: Self) -> Result { + self.0 + .checked_mul(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Mul, self, other)) + } + + pub fn checked_pow(self, exp: u32) -> Result { + self.0 + .checked_pow(exp) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp)) + } + + pub fn checked_div(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_div_euclid(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div_euclid(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_rem(self, other: Self) -> Result { + self.0 + .checked_rem(other.0) + .map(Self) + .ok_or_else(|| DivideByZeroError::new(self)) + } + + pub fn checked_shr(self, other: u32) -> Result { + if other >= 128 { + return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + } + + Ok(Self(self.0.shr(other))) + } + + pub fn checked_shl(self, other: u32) -> Result { + if other >= 128 { + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); + } + + Ok(Self(self.0.shl(other))) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self(self.0.wrapping_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_sub(self, other: Self) -> Self { + Self(self.0.wrapping_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_mul(self, other: Self) -> Self { + Self(self.0.wrapping_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_pow(self, other: u32) -> Self { + Self(self.0.wrapping_pow(other)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_add(self, other: Self) -> Self { + Self(self.0.saturating_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_sub(self, other: Self) -> Self { + Self(self.0.saturating_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_mul(self, other: Self) -> Self { + Self(self.0.saturating_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_pow(self, exp: u32) -> Self { + Self(self.0.saturating_pow(exp)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs_diff(self, other: Self) -> Uint128 { + Uint128(self.0.abs_diff(other.0)) + } +} + +impl From for Int128 { + fn from(val: Uint64) -> Self { + val.u64().into() + } +} + +impl From for Int128 { + fn from(val: u64) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: u32) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: u16) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: u8) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: Int64) -> Self { + val.i64().into() + } +} + +impl From for Int128 { + fn from(val: i128) -> Self { + Int128(val) + } +} + +impl From for Int128 { + fn from(val: i64) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: i32) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: i16) -> Self { + Int128(val.into()) + } +} + +impl From for Int128 { + fn from(val: i8) -> Self { + Int128(val.into()) + } +} + +impl TryFrom<&str> for Int128 { + type Error = StdError; + + fn try_from(val: &str) -> Result { + Self::from_str(val) + } +} + +impl FromStr for Int128 { + type Err = StdError; + + fn from_str(s: &str) -> Result { + match s.parse::() { + Ok(u) => Ok(Self(u)), + Err(e) => Err(StdError::generic_err(format!("Parsing Int128: {e}"))), + } + } +} + +impl From for String { + fn from(original: Int128) -> Self { + original.to_string() + } +} + +impl fmt::Display for Int128 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Add for Int128 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int128(self.0.checked_add(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Add, add for Int128, Int128); + +impl Sub for Int128 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + Int128(self.0.checked_sub(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Sub, sub for Int128, Int128); + +impl SubAssign for Int128 { + fn sub_assign(&mut self, rhs: Int128) { + self.0 = self.0.checked_sub(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl SubAssign, sub_assign for Int128, Int128); + +impl Div for Int128 { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + Self(self.0.checked_div(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Div, div for Int128, Int128); + +impl Rem for Int128 { + type Output = Self; + + /// # Panics + /// + /// This operation will panic if `rhs` is zero. + #[inline] + fn rem(self, rhs: Self) -> Self { + Self(self.0.rem(rhs.0)) + } +} +forward_ref_binop!(impl Rem, rem for Int128, Int128); + +impl Not for Int128 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl Neg for Int128 { + type Output = Self; + + fn neg(self) -> Self::Output { + Self(-self.0) + } +} + +impl RemAssign for Int128 { + fn rem_assign(&mut self, rhs: Int128) { + *self = *self % rhs; + } +} +forward_ref_op_assign!(impl RemAssign, rem_assign for Int128, Int128); + +impl Mul for Int128 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + Self(self.0.checked_mul(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Mul, mul for Int128, Int128); + +impl MulAssign for Int128 { + fn mul_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_mul(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl MulAssign, mul_assign for Int128, Int128); + +impl Shr for Int128 { + type Output = Self; + + fn shr(self, rhs: u32) -> Self::Output { + self.checked_shr(rhs).unwrap_or_else(|_| { + panic!("right shift error: {rhs} is larger or equal than the number of bits in Int128",) + }) + } +} +forward_ref_binop!(impl Shr, shr for Int128, u32); + +impl Shl for Int128 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + self.checked_shl(rhs).unwrap_or_else(|_| { + panic!("left shift error: {rhs} is larger or equal than the number of bits in Int128",) + }) + } +} +forward_ref_binop!(impl Shl, shl for Int128, u32); + +impl AddAssign for Int128 { + fn add_assign(&mut self, rhs: Int128) { + self.0 = self.0.checked_add(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl AddAssign, add_assign for Int128, Int128); + +impl DivAssign for Int128 { + fn div_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_div(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl DivAssign, div_assign for Int128, Int128); + +impl ShrAssign for Int128 { + fn shr_assign(&mut self, rhs: u32) { + *self = Shr::::shr(*self, rhs); + } +} +forward_ref_op_assign!(impl ShrAssign, shr_assign for Int128, u32); + +impl ShlAssign for Int128 { + fn shl_assign(&mut self, rhs: u32) { + *self = Shl::::shl(*self, rhs); + } +} +forward_ref_op_assign!(impl ShlAssign, shl_assign for Int128, u32); + +impl Serialize for Int128 { + /// Serializes as an integer string using base 10 + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl<'de> Deserialize<'de> for Int128 { + /// Deserialized from an integer string using base 10 + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(Int128Visitor) + } +} + +struct Int128Visitor; + +impl<'de> de::Visitor<'de> for Int128Visitor { + type Value = Int128; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string-encoded integer") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Int128::try_from(v).map_err(|e| E::custom(format!("invalid Int128 '{v}' - {e}"))) + } +} + +impl core::iter::Sum for Int128 +where + Self: Add, +{ + fn sum>(iter: I) -> Self { + iter.fold(Self::zero(), Add::add) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{from_slice, to_vec}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 16); + } + + #[test] + fn int128_from_be_bytes_works() { + let num = Int128::from_be_bytes([1; 16]); + let a: [u8; 16] = num.to_be_bytes(); + assert_eq!(a, [1; 16]); + + let be_bytes = [ + 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let num = Int128::from_be_bytes(be_bytes); + let resulting_bytes: [u8; 16] = num.to_be_bytes(); + assert_eq!(be_bytes, resulting_bytes); + } + + #[test] + fn int128_new_works() { + let num = Int128::new(222); + assert_eq!(num.i128(), 222); + + let num = Int128::new(-222); + assert_eq!(num.i128(), -222); + + let num = Int128::new(i128::MAX); + assert_eq!(num.i128(), i128::MAX); + + let num = Int128::new(i128::MIN); + assert_eq!(num.i128(), i128::MIN); + } + + #[test] + fn int128_not_works() { + assert_eq!(!Int128::new(222), Int128::new(!222)); + assert_eq!(!Int128::new(-222), Int128::new(!-222)); + + assert_eq!(!Int128::MAX, Int128::new(!i128::MAX)); + assert_eq!(!Int128::MIN, Int128::new(!i128::MIN)); + } + + #[test] + fn int128_zero_works() { + let zero = Int128::zero(); + assert_eq!(zero.to_be_bytes(), [0; 16]); + } + + #[test] + fn uint128_one_works() { + let one = Int128::one(); + let mut one_be = [0; 16]; + one_be[15] = 1; + + assert_eq!(one.to_be_bytes(), one_be); + } + + #[test] + fn int128_endianness() { + let be_bytes = [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let le_bytes = [ + 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]; + + // These should all be the same. + let num1 = Int128::from_be_bytes(be_bytes); + let num2 = Int128::from_le_bytes(le_bytes); + assert_eq!(num1, Int128::from(65536u32 + 512 + 3)); + assert_eq!(num1, num2); + } + + #[test] + fn int128_convert_from() { + let a = Int128::from(5i128); + assert_eq!(a.0, i128::from(5u32)); + + let a = Int128::from(5u64); + assert_eq!(a.0, i128::from(5u32)); + + let a = Int128::from(5u32); + assert_eq!(a.0, i128::from(5u32)); + + let a = Int128::from(5u16); + assert_eq!(a.0, i128::from(5u32)); + + let a = Int128::from(5u8); + assert_eq!(a.0, i128::from(5u32)); + + let a = Int128::from(-5i128); + assert_eq!(a.0, i128::from(-5i32)); + + let a = Int128::from(-5i64); + assert_eq!(a.0, i128::from(-5i32)); + + let a = Int128::from(-5i32); + assert_eq!(a.0, i128::from(-5i32)); + + let a = Int128::from(-5i16); + assert_eq!(a.0, i128::from(-5i32)); + + let a = Int128::from(-5i8); + assert_eq!(a.0, i128::from(-5i32)); + + let result = Int128::try_from("34567"); + assert_eq!(result.unwrap().0, "34567".parse::().unwrap()); + + let result = Int128::try_from("1.23"); + assert!(result.is_err()); + } + + #[test] + fn int128_implements_display() { + let a = Int128::from(12345u32); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); + assert_eq!(a.to_string(), "12345"); + + let a = Int128::from(-12345i32); + assert_eq!(format!("Embedded: {a}"), "Embedded: -12345"); + assert_eq!(a.to_string(), "-12345"); + + let a = Int128::zero(); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); + assert_eq!(a.to_string(), "0"); + } + + #[test] + fn int128_display_padding_works() { + // width > natural representation + let a = Int128::from(123u64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + let a = Int128::from(-123i64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123"); + + // width < natural representation + let a = Int128::from(123u64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); + let a = Int128::from(-123i64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123"); + } + + #[test] + fn int128_to_be_bytes_works() { + assert_eq!(Int128::zero().to_be_bytes(), [0; 16]); + + let mut max = [0xff; 16]; + max[0] = 0x7f; + assert_eq!(Int128::MAX.to_be_bytes(), max); + + let mut one = [0; 16]; + one[15] = 1; + assert_eq!(Int128::from(1i128).to_be_bytes(), one); + // Python: `[b for b in (70141183460469231731687303715884018880).to_bytes(16, "big")]` + assert_eq!( + Int128::from(70141183460469231731687303715884018880i128).to_be_bytes(), + [52, 196, 179, 87, 165, 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192] + ); + assert_eq!( + Int128::from_be_bytes([17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78]) + .to_be_bytes(), + [17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78] + ); + } + + #[test] + fn int128_to_le_bytes_works() { + assert_eq!(Int128::zero().to_le_bytes(), [0; 16]); + + let mut max = [0xff; 16]; + max[15] = 0x7f; + assert_eq!(Int128::MAX.to_le_bytes(), max); + + let mut one = [0; 16]; + one[0] = 1; + assert_eq!(Int128::from(1i128).to_le_bytes(), one); + // Python: `[b for b in (70141183460469231731687303715884018880).to_bytes(16, "little")]` + assert_eq!( + Int128::from(70141183460469231731687303715884018880i128).to_le_bytes(), + [192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 52] + ); + assert_eq!( + Int128::from_be_bytes([17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78]) + .to_le_bytes(), + [78, 67, 21, 33, 38, 0, 91, 58, 200, 123, 67, 87, 32, 23, 4, 17] + ); + } + + #[test] + fn int128_is_zero_works() { + assert!(Int128::zero().is_zero()); + assert!(Int128(i128::from(0u32)).is_zero()); + + assert!(!Int128::from(1u32).is_zero()); + assert!(!Int128::from(123u32).is_zero()); + assert!(!Int128::from(-123i32).is_zero()); + } + + #[test] + fn int128_wrapping_methods() { + // wrapping_add + assert_eq!( + Int128::from(2u32).wrapping_add(Int128::from(2u32)), + Int128::from(4u32) + ); // non-wrapping + assert_eq!(Int128::MAX.wrapping_add(Int128::from(1u32)), Int128::MIN); // wrapping + + // wrapping_sub + assert_eq!( + Int128::from(7u32).wrapping_sub(Int128::from(5u32)), + Int128::from(2u32) + ); // non-wrapping + assert_eq!(Int128::MIN.wrapping_sub(Int128::from(1u32)), Int128::MAX); // wrapping + + // wrapping_mul + assert_eq!( + Int128::from(3u32).wrapping_mul(Int128::from(2u32)), + Int128::from(6u32) + ); // non-wrapping + assert_eq!( + Int128::MAX.wrapping_mul(Int128::from(2u32)), + Int128::from(-2i32) + ); // wrapping + + // wrapping_pow + assert_eq!(Int128::from(2u32).wrapping_pow(3), Int128::from(8u32)); // non-wrapping + assert_eq!(Int128::MAX.wrapping_pow(2), Int128::from(1u32)); // wrapping + } + + #[test] + fn int128_json() { + let orig = Int128::from(1234567890987654321i128); + let serialized = to_vec(&orig).unwrap(); + assert_eq!(serialized.as_slice(), b"\"1234567890987654321\""); + let parsed: Int128 = from_slice(&serialized).unwrap(); + assert_eq!(parsed, orig); + } + + #[test] + fn int128_compare() { + let a = Int128::from(12345u32); + let b = Int128::from(23456u32); + + assert!(a < b); + assert!(b > a); + assert_eq!(a, Int128::from(12345u32)); + } + + #[test] + #[allow(clippy::op_ref)] + fn int128_math() { + let a = Int128::from(-12345i32); + let b = Int128::from(23456u32); + + // test + with owned and reference right hand side + assert_eq!(a + b, Int128::from(11111u32)); + assert_eq!(a + &b, Int128::from(11111u32)); + + // test - with owned and reference right hand side + assert_eq!(b - a, Int128::from(35801u32)); + assert_eq!(b - &a, Int128::from(35801u32)); + + // test += with owned and reference right hand side + let mut c = Int128::from(300000u32); + c += b; + assert_eq!(c, Int128::from(323456u32)); + let mut d = Int128::from(300000u32); + d += &b; + assert_eq!(d, Int128::from(323456u32)); + + // test -= with owned and reference right hand side + let mut c = Int128::from(300000u32); + c -= b; + assert_eq!(c, Int128::from(276544u32)); + let mut d = Int128::from(300000u32); + d -= &b; + assert_eq!(d, Int128::from(276544u32)); + + // test - with negative result + assert_eq!(a - b, Int128::from(-35801i32)); + } + + #[test] + #[should_panic] + fn int128_add_overflow_panics() { + let _ = Int128::MAX + Int128::from(12u32); + } + + #[test] + #[allow(clippy::op_ref)] + fn int128_sub_works() { + assert_eq!(Int128::from(2u32) - Int128::from(1u32), Int128::from(1u32)); + assert_eq!(Int128::from(2u32) - Int128::from(0u32), Int128::from(2u32)); + assert_eq!(Int128::from(2u32) - Int128::from(2u32), Int128::from(0u32)); + assert_eq!(Int128::from(2u32) - Int128::from(3u32), Int128::from(-1i32)); + + // works for refs + let a = Int128::from(10u32); + let b = Int128::from(3u32); + let expected = Int128::from(7u32); + assert_eq!(a - b, expected); + assert_eq!(a - &b, expected); + assert_eq!(&a - b, expected); + assert_eq!(&a - &b, expected); + } + + #[test] + #[should_panic] + fn int128_sub_overflow_panics() { + let _ = Int128::MIN + Int128::one() - Int128::from(2u32); + } + + #[test] + fn int128_sub_assign_works() { + let mut a = Int128::from(14u32); + a -= Int128::from(2u32); + assert_eq!(a, Int128::from(12u32)); + + // works for refs + let mut a = Int128::from(10u32); + let b = Int128::from(3u32); + let expected = Int128::from(7u32); + a -= &b; + assert_eq!(a, expected); + } + + #[test] + #[allow(clippy::op_ref)] + fn int128_mul_works() { + assert_eq!(Int128::from(2u32) * Int128::from(3u32), Int128::from(6u32)); + assert_eq!(Int128::from(2u32) * Int128::zero(), Int128::zero()); + + // works for refs + let a = Int128::from(11u32); + let b = Int128::from(3u32); + let expected = Int128::from(33u32); + assert_eq!(a * b, expected); + assert_eq!(a * &b, expected); + assert_eq!(&a * b, expected); + assert_eq!(&a * &b, expected); + } + + #[test] + fn int128_mul_assign_works() { + let mut a = Int128::from(14u32); + a *= Int128::from(2u32); + assert_eq!(a, Int128::from(28u32)); + + // works for refs + let mut a = Int128::from(10u32); + let b = Int128::from(3u32); + a *= &b; + assert_eq!(a, Int128::from(30u32)); + } + + #[test] + fn int128_pow_works() { + assert_eq!(Int128::from(2u32).pow(2), Int128::from(4u32)); + assert_eq!(Int128::from(2u32).pow(10), Int128::from(1024u32)); + } + + #[test] + #[should_panic] + fn int128_pow_overflow_panics() { + _ = Int128::MAX.pow(2u32); + } + + #[test] + fn int128_shr_works() { + let original = Int128::from_be_bytes([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8, + ]); + + let shifted = Int128::from_be_bytes([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8, + ]); + + assert_eq!(original >> 2u32, shifted); + } + + #[test] + #[should_panic] + fn int128_shr_overflow_panics() { + let _ = Int128::from(1u32) >> 128u32; + } + + #[test] + fn sum_works() { + let nums = vec![ + Int128::from(17u32), + Int128::from(123u32), + Int128::from(540u32), + Int128::from(82u32), + ]; + let expected = Int128::from(762u32); + + let sum_as_ref: Int128 = nums.iter().sum(); + assert_eq!(expected, sum_as_ref); + + let sum_as_owned: Int128 = nums.into_iter().sum(); + assert_eq!(expected, sum_as_owned); + } + + #[test] + fn int128_methods() { + // checked_* + assert!(matches!( + Int128::MAX.checked_add(Int128::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int128::from(1u32).checked_add(Int128::from(1u32)), + Ok(Int128::from(2u32)), + ); + assert!(matches!( + Int128::MIN.checked_sub(Int128::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int128::from(2u32).checked_sub(Int128::from(1u32)), + Ok(Int128::from(1u32)), + ); + assert!(matches!( + Int128::MAX.checked_mul(Int128::from(2u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int128::from(2u32).checked_mul(Int128::from(2u32)), + Ok(Int128::from(4u32)), + ); + assert!(matches!( + Int128::MAX.checked_pow(2u32), + Err(OverflowError { .. }) + )); + assert_eq!(Int128::from(2u32).checked_pow(3u32), Ok(Int128::from(8u32)),); + assert_eq!( + Int128::MAX.checked_div(Int128::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int128::from(6u32).checked_div(Int128::from(2u32)), + Ok(Int128::from(3u32)), + ); + assert_eq!( + Int128::MAX.checked_div_euclid(Int128::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int128::from(6u32).checked_div_euclid(Int128::from(2u32)), + Ok(Int128::from(3u32)), + ); + assert_eq!( + Int128::from(7u32).checked_div_euclid(Int128::from(2u32)), + Ok(Int128::from(3u32)), + ); + assert!(matches!( + Int128::MAX.checked_rem(Int128::from(0u32)), + Err(DivideByZeroError { .. }) + )); + // checked_* with negative numbers + assert_eq!( + Int128::from(-12i32).checked_div(Int128::from(10i32)), + Ok(Int128::from(-1i32)), + ); + assert_eq!( + Int128::from(-2i32).checked_pow(3u32), + Ok(Int128::from(-8i32)), + ); + assert_eq!( + Int128::from(-6i32).checked_mul(Int128::from(-7i32)), + Ok(Int128::from(42i32)), + ); + assert_eq!( + Int128::from(-2i32).checked_add(Int128::from(3i32)), + Ok(Int128::from(1i32)), + ); + assert_eq!( + Int128::from(-1i32).checked_div_euclid(Int128::from(-2i32)), + Ok(Int128::from(1u32)), + ); + + // saturating_* + assert_eq!(Int128::MAX.saturating_add(Int128::from(1u32)), Int128::MAX); + assert_eq!(Int128::MIN.saturating_sub(Int128::from(1u32)), Int128::MIN); + assert_eq!(Int128::MAX.saturating_mul(Int128::from(2u32)), Int128::MAX); + assert_eq!(Int128::from(4u32).saturating_pow(2u32), Int128::from(16u32)); + assert_eq!(Int128::MAX.saturating_pow(2u32), Int128::MAX); + } + + #[test] + #[allow(clippy::op_ref)] + fn int128_implements_rem() { + let a = Int128::from(10u32); + assert_eq!(a % Int128::from(10u32), Int128::zero()); + assert_eq!(a % Int128::from(2u32), Int128::zero()); + assert_eq!(a % Int128::from(1u32), Int128::zero()); + assert_eq!(a % Int128::from(3u32), Int128::from(1u32)); + assert_eq!(a % Int128::from(4u32), Int128::from(2u32)); + + assert_eq!( + Int128::from(-12i32) % Int128::from(10i32), + Int128::from(-2i32) + ); + assert_eq!( + Int128::from(12i32) % Int128::from(-10i32), + Int128::from(2i32) + ); + assert_eq!( + Int128::from(-12i32) % Int128::from(-10i32), + Int128::from(-2i32) + ); + + // works for refs + let a = Int128::from(10u32); + let b = Int128::from(3u32); + let expected = Int128::from(1u32); + assert_eq!(a % b, expected); + assert_eq!(a % &b, expected); + assert_eq!(&a % b, expected); + assert_eq!(&a % &b, expected); + } + + #[test] + #[should_panic(expected = "divisor of zero")] + fn int128_rem_panics_for_zero() { + let _ = Int128::from(10u32) % Int128::zero(); + } + + #[test] + fn int128_rem_assign_works() { + let mut a = Int128::from(30u32); + a %= Int128::from(4u32); + assert_eq!(a, Int128::from(2u32)); + + // works for refs + let mut a = Int128::from(25u32); + let b = Int128::from(6u32); + a %= &b; + assert_eq!(a, Int128::from(1u32)); + } + + #[test] + fn int128_shr() { + let x: Int128 = 0x4000_0000_0000_0000_0000_0000_0000_0000i128.into(); + assert_eq!(x >> 0, x); // right shift by 0 should be no-op + assert_eq!( + x >> 1, + Int128::from(0x2000_0000_0000_0000_0000_0000_0000_0000i128) + ); + assert_eq!( + x >> 4, + Int128::from(0x0400_0000_0000_0000_0000_0000_0000_0000i128) + ); + // right shift of MIN value by the maximum shift value should result in -1 (filled with 1s) + assert_eq!( + Int128::MIN >> (core::mem::size_of::() as u32 * 8 - 1), + -Int128::one() + ); + } + + #[test] + fn int128_shl() { + let x: Int128 = 0x0800_0000_0000_0000_0000_0000_0000_0000i128.into(); + assert_eq!(x << 0, x); // left shift by 0 should be no-op + assert_eq!( + x << 1, + Int128::from(0x1000_0000_0000_0000_0000_0000_0000_0000i128) + ); + assert_eq!( + x << 4, + Int128::from(0x0800_0000_0000_0000_0000_0000_0000_0000i128 << 4) + ); + // left shift by by the maximum shift value should result in MIN + assert_eq!( + Int128::one() << (core::mem::size_of::() as u32 * 8 - 1), + Int128::MIN + ); + } + + #[test] + fn int128_abs_diff_works() { + let a = Int128::from(42u32); + let b = Int128::from(5u32); + let expected = Uint128::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + + let c = Int128::from(-5i32); + assert_eq!(b.abs_diff(c), Uint128::from(10u32)); + assert_eq!(c.abs_diff(b), Uint128::from(10u32)); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int128_neg_min_panics() { + _ = -Int128::MIN; + } + + #[test] + fn int128_partial_eq() { + let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)] + .into_iter() + .map(|(lhs, rhs, expected): (u64, u64, bool)| { + (Int128::from(lhs), Int128::from(rhs), expected) + }); + + #[allow(clippy::op_ref)] + for (lhs, rhs, expected) in test_cases { + assert_eq!(lhs == rhs, expected); + assert_eq!(&lhs == rhs, expected); + assert_eq!(lhs == &rhs, expected); + assert_eq!(&lhs == &rhs, expected); + } + } +} diff --git a/packages/std/src/math/int256.rs b/packages/std/src/math/int256.rs new file mode 100644 index 000000000..5616fcc2e --- /dev/null +++ b/packages/std/src/math/int256.rs @@ -0,0 +1,1196 @@ +use core::fmt; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, + ShrAssign, Sub, SubAssign, +}; +use core::str::FromStr; +use forward_ref::{forward_ref_binop, forward_ref_op_assign}; +use schemars::JsonSchema; +use serde::{de, ser, Deserialize, Deserializer, Serialize}; + +use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError}; +use crate::{forward_ref_partial_eq, Int128, Int64, Uint128, Uint256, Uint64}; + +/// Used internally - we don't want to leak this type since we might change +/// the implementation in the future. +use bnum::types::{I256, U256}; + +/// An implementation of i256 that is using strings for JSON encoding/decoding, +/// such that the full i256 range can be used for clients that convert JSON numbers to floats, +/// like JavaScript and jq. +/// +/// # Examples +/// +/// Use `from` to create instances out of primitive uint types or `new` to provide big +/// endian bytes: +/// +/// ``` +/// # use cosmwasm_std::Int256; +/// let a = Int256::from(258u128); +/// let b = Int256::new([ +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, +/// ]); +/// assert_eq!(a, b); +/// ``` +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] +pub struct Int256(#[schemars(with = "String")] I256); + +forward_ref_partial_eq!(Int256, Int256); + +impl Int256 { + pub const MAX: Int256 = Int256(I256::MAX); + pub const MIN: Int256 = Int256(I256::MIN); + + /// Creates a Int256(value) from a big endian representation. It's just an alias for + /// `from_be_bytes`. + #[inline] + pub const fn new(value: [u8; 32]) -> Self { + Self::from_be_bytes(value) + } + + /// Creates a Int256(0) + #[inline] + pub const fn zero() -> Self { + Int256(I256::ZERO) + } + + /// Creates a Int256(1) + #[inline] + pub const fn one() -> Self { + Self(I256::ONE) + } + + #[must_use] + pub const fn from_be_bytes(data: [u8; 32]) -> Self { + let words: [u64; 4] = [ + u64::from_le_bytes([ + data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24], + ]), + u64::from_le_bytes([ + data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16], + ]), + u64::from_le_bytes([ + data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8], + ]), + u64::from_le_bytes([ + data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0], + ]), + ]; + Self(I256::from_bits(U256::from_digits(words))) + } + + #[must_use] + pub const fn from_le_bytes(data: [u8; 32]) -> Self { + let words: [u64; 4] = [ + u64::from_le_bytes([ + data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], + ]), + u64::from_le_bytes([ + data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], + ]), + u64::from_le_bytes([ + data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], + ]), + u64::from_le_bytes([ + data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], + ]), + ]; + Self(I256::from_bits(U256::from_digits(words))) + } + + /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_be_bytes(self) -> [u8; 32] { + let bits = self.0.to_bits(); + let words = bits.digits(); + let words = [ + words[3].to_be_bytes(), + words[2].to_be_bytes(), + words[1].to_be_bytes(), + words[0].to_be_bytes(), + ]; + unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) } + } + + /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_le_bytes(self) -> [u8; 32] { + let bits = self.0.to_bits(); + let words = bits.digits(); + let words = [ + words[0].to_le_bytes(), + words[1].to_le_bytes(), + words[2].to_le_bytes(), + words[3].to_le_bytes(), + ]; + unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) } + } + + #[must_use] + pub const fn is_zero(&self) -> bool { + self.0.is_zero() + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn pow(self, exp: u32) -> Self { + Self(self.0.pow(exp)) + } + + pub fn checked_add(self, other: Self) -> Result { + self.0 + .checked_add(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Add, self, other)) + } + + pub fn checked_sub(self, other: Self) -> Result { + self.0 + .checked_sub(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Sub, self, other)) + } + + pub fn checked_mul(self, other: Self) -> Result { + self.0 + .checked_mul(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Mul, self, other)) + } + + pub fn checked_pow(self, exp: u32) -> Result { + self.0 + .checked_pow(exp) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp)) + } + + pub fn checked_div(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_div_euclid(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div_euclid(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_rem(self, other: Self) -> Result { + self.0 + .checked_rem(other.0) + .map(Self) + .ok_or_else(|| DivideByZeroError::new(self)) + } + + pub fn checked_shr(self, other: u32) -> Result { + if other >= 256 { + return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + } + + Ok(Self(self.0.shr(other))) + } + + pub fn checked_shl(self, other: u32) -> Result { + if other >= 256 { + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); + } + + Ok(Self(self.0.shl(other))) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self(self.0.wrapping_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_sub(self, other: Self) -> Self { + Self(self.0.wrapping_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_mul(self, other: Self) -> Self { + Self(self.0.wrapping_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_pow(self, other: u32) -> Self { + Self(self.0.wrapping_pow(other)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_add(self, other: Self) -> Self { + Self(self.0.saturating_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_sub(self, other: Self) -> Self { + Self(self.0.saturating_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_mul(self, other: Self) -> Self { + Self(self.0.saturating_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_pow(self, exp: u32) -> Self { + Self(self.0.saturating_pow(exp)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs_diff(self, other: Self) -> Uint256 { + Uint256(self.0.abs_diff(other.0)) + } +} + +impl From for Int256 { + fn from(val: Uint128) -> Self { + val.u128().into() + } +} + +impl From for Int256 { + fn from(val: Uint64) -> Self { + val.u64().into() + } +} + +impl From for Int256 { + fn from(val: u128) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: u64) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: u32) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: u16) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: u8) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: Int128) -> Self { + val.i128().into() + } +} + +impl From for Int256 { + fn from(val: Int64) -> Self { + val.i64().into() + } +} + +impl From for Int256 { + fn from(val: i128) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: i64) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: i32) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: i16) -> Self { + Int256(val.into()) + } +} + +impl From for Int256 { + fn from(val: i8) -> Self { + Int256(val.into()) + } +} + +impl TryFrom<&str> for Int256 { + type Error = StdError; + + fn try_from(val: &str) -> Result { + Self::from_str(val) + } +} + +impl FromStr for Int256 { + type Err = StdError; + + fn from_str(s: &str) -> Result { + match I256::from_str_radix(s, 10) { + Ok(u) => Ok(Self(u)), + Err(e) => Err(StdError::generic_err(format!("Parsing Int256: {e}"))), + } + } +} + +impl From for String { + fn from(original: Int256) -> Self { + original.to_string() + } +} + +impl fmt::Display for Int256 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Add for Int256 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int256(self.0.checked_add(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Add, add for Int256, Int256); + +impl Sub for Int256 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + Int256(self.0.checked_sub(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Sub, sub for Int256, Int256); + +impl SubAssign for Int256 { + fn sub_assign(&mut self, rhs: Int256) { + self.0 = self.0.checked_sub(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl SubAssign, sub_assign for Int256, Int256); + +impl Div for Int256 { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + Self(self.0.checked_div(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Div, div for Int256, Int256); + +impl Rem for Int256 { + type Output = Self; + + /// # Panics + /// + /// This operation will panic if `rhs` is zero. + #[inline] + fn rem(self, rhs: Self) -> Self { + Self(self.0.rem(rhs.0)) + } +} +forward_ref_binop!(impl Rem, rem for Int256, Int256); + +impl Not for Int256 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl Neg for Int256 { + type Output = Self; + + fn neg(self) -> Self::Output { + Self(-self.0) + } +} + +impl RemAssign for Int256 { + fn rem_assign(&mut self, rhs: Int256) { + *self = *self % rhs; + } +} +forward_ref_op_assign!(impl RemAssign, rem_assign for Int256, Int256); + +impl Mul for Int256 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + Self(self.0.checked_mul(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Mul, mul for Int256, Int256); + +impl MulAssign for Int256 { + fn mul_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_mul(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl MulAssign, mul_assign for Int256, Int256); + +impl Shr for Int256 { + type Output = Self; + + fn shr(self, rhs: u32) -> Self::Output { + self.checked_shr(rhs).unwrap_or_else(|_| { + panic!("right shift error: {rhs} is larger or equal than the number of bits in Int256",) + }) + } +} +forward_ref_binop!(impl Shr, shr for Int256, u32); + +impl Shl for Int256 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + self.checked_shl(rhs).unwrap_or_else(|_| { + panic!("left shift error: {rhs} is larger or equal than the number of bits in Int256",) + }) + } +} +forward_ref_binop!(impl Shl, shl for Int256, u32); + +impl AddAssign for Int256 { + fn add_assign(&mut self, rhs: Int256) { + self.0 = self.0.checked_add(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl AddAssign, add_assign for Int256, Int256); + +impl DivAssign for Int256 { + fn div_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_div(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl DivAssign, div_assign for Int256, Int256); + +impl ShrAssign for Int256 { + fn shr_assign(&mut self, rhs: u32) { + *self = Shr::::shr(*self, rhs); + } +} +forward_ref_op_assign!(impl ShrAssign, shr_assign for Int256, u32); + +impl ShlAssign for Int256 { + fn shl_assign(&mut self, rhs: u32) { + *self = Shl::::shl(*self, rhs); + } +} +forward_ref_op_assign!(impl ShlAssign, shl_assign for Int256, u32); + +impl Serialize for Int256 { + /// Serializes as an integer string using base 10 + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl<'de> Deserialize<'de> for Int256 { + /// Deserialized from an integer string using base 10 + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(Int256Visitor) + } +} + +struct Int256Visitor; + +impl<'de> de::Visitor<'de> for Int256Visitor { + type Value = Int256; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string-encoded integer") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Int256::try_from(v).map_err(|e| E::custom(format!("invalid Int256 '{v}' - {e}"))) + } +} + +impl core::iter::Sum for Int256 +where + Self: Add, +{ + fn sum>(iter: I) -> Self { + iter.fold(Self::zero(), Add::add) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{from_slice, to_vec}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 32); + } + + #[test] + fn int256_new_works() { + let num = Int256::new([1; 32]); + let a: [u8; 32] = num.to_be_bytes(); + assert_eq!(a, [1; 32]); + + let be_bytes = [ + 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let num = Int256::new(be_bytes); + let resulting_bytes: [u8; 32] = num.to_be_bytes(); + assert_eq!(be_bytes, resulting_bytes); + } + + #[test] + fn int256_not_works() { + let num = Int256::new([1; 32]); + let a = (!num).to_be_bytes(); + assert_eq!(a, [254; 32]); + + assert_eq!(!Int256::from(-1234806i128), Int256::from(!-1234806i128)); + + assert_eq!(!Int256::MAX, Int256::MIN); + assert_eq!(!Int256::MIN, Int256::MAX); + } + + #[test] + fn int256_zero_works() { + let zero = Int256::zero(); + assert_eq!(zero.to_be_bytes(), [0; 32]); + } + + #[test] + fn uint256_one_works() { + let one = Int256::one(); + let mut one_be = [0; 32]; + one_be[31] = 1; + + assert_eq!(one.to_be_bytes(), one_be); + } + + #[test] + fn int256_endianness() { + let be_bytes = [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let le_bytes = [ + 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]; + + // These should all be the same. + let num1 = Int256::new(be_bytes); + let num2 = Int256::from_be_bytes(be_bytes); + let num3 = Int256::from_le_bytes(le_bytes); + assert_eq!(num1, Int256::from(65536u32 + 512 + 3)); + assert_eq!(num1, num2); + assert_eq!(num1, num3); + } + + #[test] + fn int256_convert_from() { + let a = Int256::from(5u128); + assert_eq!(a.0, I256::from(5u32)); + + let a = Int256::from(5u64); + assert_eq!(a.0, I256::from(5u32)); + + let a = Int256::from(5u32); + assert_eq!(a.0, I256::from(5u32)); + + let a = Int256::from(5u16); + assert_eq!(a.0, I256::from(5u32)); + + let a = Int256::from(5u8); + assert_eq!(a.0, I256::from(5u32)); + + let a = Int256::from(-5i128); + assert_eq!(a.0, I256::from(-5i32)); + + let a = Int256::from(-5i64); + assert_eq!(a.0, I256::from(-5i32)); + + let a = Int256::from(-5i32); + assert_eq!(a.0, I256::from(-5i32)); + + let a = Int256::from(-5i16); + assert_eq!(a.0, I256::from(-5i32)); + + let a = Int256::from(-5i8); + assert_eq!(a.0, I256::from(-5i32)); + + let result = Int256::try_from("34567"); + assert_eq!( + result.unwrap().0, + I256::from_str_radix("34567", 10).unwrap() + ); + + let result = Int256::try_from("1.23"); + assert!(result.is_err()); + } + + #[test] + fn int256_implements_display() { + let a = Int256::from(12345u32); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); + assert_eq!(a.to_string(), "12345"); + + let a = Int256::from(-12345i32); + assert_eq!(format!("Embedded: {a}"), "Embedded: -12345"); + assert_eq!(a.to_string(), "-12345"); + + let a = Int256::zero(); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); + assert_eq!(a.to_string(), "0"); + } + + #[test] + fn int256_display_padding_works() { + // width > natural representation + let a = Int256::from(123u64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + let a = Int256::from(-123i64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123"); + + // width < natural representation + let a = Int256::from(123u64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); + let a = Int256::from(-123i64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123"); + } + + #[test] + fn int256_to_be_bytes_works() { + assert_eq!(Int256::zero().to_be_bytes(), [0; 32]); + + let mut max = [0xff; 32]; + max[0] = 0x7f; + assert_eq!(Int256::MAX.to_be_bytes(), max); + + let mut one = [0; 32]; + one[31] = 1; + assert_eq!(Int256::from(1u128).to_be_bytes(), one); + // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(32, "big")]` + assert_eq!( + Int256::from(240282366920938463463374607431768124608u128).to_be_bytes(), + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165, 121, 59, + 133, 246, 117, 221, 191, 255, 254, 172, 192 + ] + ); + assert_eq!( + Int256::from_be_bytes([ + 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54, + 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240 + ]) + .to_be_bytes(), + [ + 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54, + 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240 + ] + ); + } + + #[test] + fn int256_to_le_bytes_works() { + assert_eq!(Int256::zero().to_le_bytes(), [0; 32]); + + let mut max = [0xff; 32]; + max[31] = 0x7f; + assert_eq!(Int256::MAX.to_le_bytes(), max); + + let mut one = [0; 32]; + one[0] = 1; + assert_eq!(Int256::from(1u128).to_le_bytes(), one); + // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(64, "little")]` + assert_eq!( + Int256::from(240282366920938463463374607431768124608u128).to_le_bytes(), + [ + 192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ] + ); + assert_eq!( + Int256::from_be_bytes([ + 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54, + 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240 + ]) + .to_le_bytes(), + [ + 240, 150, 115, 200, 240, 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21, + 33, 38, 0, 91, 58, 200, 123, 67, 87, 32, 23, 4, 17 + ] + ); + } + + #[test] + fn int256_is_zero_works() { + assert!(Int256::zero().is_zero()); + assert!(Int256(I256::from(0u32)).is_zero()); + + assert!(!Int256::from(1u32).is_zero()); + assert!(!Int256::from(123u32).is_zero()); + assert!(!Int256::from(-123i32).is_zero()); + } + + #[test] + fn int256_wrapping_methods() { + // wrapping_add + assert_eq!( + Int256::from(2u32).wrapping_add(Int256::from(2u32)), + Int256::from(4u32) + ); // non-wrapping + assert_eq!(Int256::MAX.wrapping_add(Int256::from(1u32)), Int256::MIN); // wrapping + + // wrapping_sub + assert_eq!( + Int256::from(7u32).wrapping_sub(Int256::from(5u32)), + Int256::from(2u32) + ); // non-wrapping + assert_eq!(Int256::MIN.wrapping_sub(Int256::from(1u32)), Int256::MAX); // wrapping + + // wrapping_mul + assert_eq!( + Int256::from(3u32).wrapping_mul(Int256::from(2u32)), + Int256::from(6u32) + ); // non-wrapping + assert_eq!( + Int256::MAX.wrapping_mul(Int256::from(2u32)), + Int256::from(-2i32) + ); // wrapping + + // wrapping_pow + assert_eq!(Int256::from(2u32).wrapping_pow(3), Int256::from(8u32)); // non-wrapping + assert_eq!(Int256::MAX.wrapping_pow(2), Int256::from(1u32)); // wrapping + } + + #[test] + fn int256_json() { + let orig = Int256::from(1234567890987654321u128); + let serialized = to_vec(&orig).unwrap(); + assert_eq!(serialized.as_slice(), b"\"1234567890987654321\""); + let parsed: Int256 = from_slice(&serialized).unwrap(); + assert_eq!(parsed, orig); + } + + #[test] + fn int256_compare() { + let a = Int256::from(12345u32); + let b = Int256::from(23456u32); + + assert!(a < b); + assert!(b > a); + assert_eq!(a, Int256::from(12345u32)); + } + + #[test] + #[allow(clippy::op_ref)] + fn int256_math() { + let a = Int256::from(-12345i32); + let b = Int256::from(23456u32); + + // test + with owned and reference right hand side + assert_eq!(a + b, Int256::from(11111u32)); + assert_eq!(a + &b, Int256::from(11111u32)); + + // test - with owned and reference right hand side + assert_eq!(b - a, Int256::from(35801u32)); + assert_eq!(b - &a, Int256::from(35801u32)); + + // test += with owned and reference right hand side + let mut c = Int256::from(300000u32); + c += b; + assert_eq!(c, Int256::from(323456u32)); + let mut d = Int256::from(300000u32); + d += &b; + assert_eq!(d, Int256::from(323456u32)); + + // test -= with owned and reference right hand side + let mut c = Int256::from(300000u32); + c -= b; + assert_eq!(c, Int256::from(276544u32)); + let mut d = Int256::from(300000u32); + d -= &b; + assert_eq!(d, Int256::from(276544u32)); + + // test - with negative result + assert_eq!(a - b, Int256::from(-35801i32)); + } + + #[test] + #[should_panic] + fn int256_add_overflow_panics() { + let _ = Int256::MAX + Int256::from(12u32); + } + + #[test] + #[allow(clippy::op_ref)] + fn int256_sub_works() { + assert_eq!(Int256::from(2u32) - Int256::from(1u32), Int256::from(1u32)); + assert_eq!(Int256::from(2u32) - Int256::from(0u32), Int256::from(2u32)); + assert_eq!(Int256::from(2u32) - Int256::from(2u32), Int256::from(0u32)); + assert_eq!(Int256::from(2u32) - Int256::from(3u32), Int256::from(-1i32)); + + // works for refs + let a = Int256::from(10u32); + let b = Int256::from(3u32); + let expected = Int256::from(7u32); + assert_eq!(a - b, expected); + assert_eq!(a - &b, expected); + assert_eq!(&a - b, expected); + assert_eq!(&a - &b, expected); + } + + #[test] + #[should_panic] + fn int256_sub_overflow_panics() { + let _ = Int256::MIN + Int256::one() - Int256::from(2u32); + } + + #[test] + fn int256_sub_assign_works() { + let mut a = Int256::from(14u32); + a -= Int256::from(2u32); + assert_eq!(a, Int256::from(12u32)); + + // works for refs + let mut a = Int256::from(10u32); + let b = Int256::from(3u32); + let expected = Int256::from(7u32); + a -= &b; + assert_eq!(a, expected); + } + + #[test] + #[allow(clippy::op_ref)] + fn int256_mul_works() { + assert_eq!(Int256::from(2u32) * Int256::from(3u32), Int256::from(6u32)); + assert_eq!(Int256::from(2u32) * Int256::zero(), Int256::zero()); + + // works for refs + let a = Int256::from(11u32); + let b = Int256::from(3u32); + let expected = Int256::from(33u32); + assert_eq!(a * b, expected); + assert_eq!(a * &b, expected); + assert_eq!(&a * b, expected); + assert_eq!(&a * &b, expected); + } + + #[test] + fn int256_mul_assign_works() { + let mut a = Int256::from(14u32); + a *= Int256::from(2u32); + assert_eq!(a, Int256::from(28u32)); + + // works for refs + let mut a = Int256::from(10u32); + let b = Int256::from(3u32); + a *= &b; + assert_eq!(a, Int256::from(30u32)); + } + + #[test] + fn int256_pow_works() { + assert_eq!(Int256::from(2u32).pow(2), Int256::from(4u32)); + assert_eq!(Int256::from(2u32).pow(10), Int256::from(1024u32)); + } + + #[test] + #[should_panic] + fn int256_pow_overflow_panics() { + _ = Int256::MAX.pow(2u32); + } + + #[test] + fn int256_shr_works() { + let original = Int256::new([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8, + ]); + + let shifted = Int256::new([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8, + ]); + + assert_eq!(original >> 2u32, shifted); + } + + #[test] + #[should_panic] + fn int256_shr_overflow_panics() { + let _ = Int256::from(1u32) >> 256u32; + } + + #[test] + fn sum_works() { + let nums = vec![ + Int256::from(17u32), + Int256::from(123u32), + Int256::from(540u32), + Int256::from(82u32), + ]; + let expected = Int256::from(762u32); + + let sum_as_ref: Int256 = nums.iter().sum(); + assert_eq!(expected, sum_as_ref); + + let sum_as_owned: Int256 = nums.into_iter().sum(); + assert_eq!(expected, sum_as_owned); + } + + #[test] + fn int256_methods() { + // checked_* + assert!(matches!( + Int256::MAX.checked_add(Int256::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int256::from(1u32).checked_add(Int256::from(1u32)), + Ok(Int256::from(2u32)), + ); + assert!(matches!( + Int256::MIN.checked_sub(Int256::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int256::from(2u32).checked_sub(Int256::from(1u32)), + Ok(Int256::from(1u32)), + ); + assert!(matches!( + Int256::MAX.checked_mul(Int256::from(2u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int256::from(2u32).checked_mul(Int256::from(2u32)), + Ok(Int256::from(4u32)), + ); + assert!(matches!( + Int256::MAX.checked_pow(2u32), + Err(OverflowError { .. }) + )); + assert_eq!(Int256::from(2u32).checked_pow(3u32), Ok(Int256::from(8u32)),); + assert_eq!( + Int256::MAX.checked_div(Int256::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int256::from(6u32).checked_div(Int256::from(2u32)), + Ok(Int256::from(3u32)), + ); + assert_eq!( + Int256::MAX.checked_div_euclid(Int256::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int256::from(6u32).checked_div_euclid(Int256::from(2u32)), + Ok(Int256::from(3u32)), + ); + assert_eq!( + Int256::from(7u32).checked_div_euclid(Int256::from(2u32)), + Ok(Int256::from(3u32)), + ); + assert!(matches!( + Int256::MAX.checked_rem(Int256::from(0u32)), + Err(DivideByZeroError { .. }) + )); + // checked_* with negative numbers + assert_eq!( + Int256::from(-12i32).checked_div(Int256::from(10i32)), + Ok(Int256::from(-1i32)), + ); + assert_eq!( + Int256::from(-2i32).checked_pow(3u32), + Ok(Int256::from(-8i32)), + ); + assert_eq!( + Int256::from(-6i32).checked_mul(Int256::from(-7i32)), + Ok(Int256::from(42i32)), + ); + assert_eq!( + Int256::from(-2i32).checked_add(Int256::from(3i32)), + Ok(Int256::from(1i32)), + ); + assert_eq!( + Int256::from(-1i32).checked_div_euclid(Int256::from(-2i32)), + Ok(Int256::from(1u32)), + ); + + // saturating_* + assert_eq!(Int256::MAX.saturating_add(Int256::from(1u32)), Int256::MAX); + assert_eq!(Int256::MIN.saturating_sub(Int256::from(1u32)), Int256::MIN); + assert_eq!(Int256::MAX.saturating_mul(Int256::from(2u32)), Int256::MAX); + assert_eq!(Int256::from(4u32).saturating_pow(2u32), Int256::from(16u32)); + assert_eq!(Int256::MAX.saturating_pow(2u32), Int256::MAX); + } + + #[test] + #[allow(clippy::op_ref)] + fn int256_implements_rem() { + let a = Int256::from(10u32); + assert_eq!(a % Int256::from(10u32), Int256::zero()); + assert_eq!(a % Int256::from(2u32), Int256::zero()); + assert_eq!(a % Int256::from(1u32), Int256::zero()); + assert_eq!(a % Int256::from(3u32), Int256::from(1u32)); + assert_eq!(a % Int256::from(4u32), Int256::from(2u32)); + + assert_eq!( + Int256::from(-12i32) % Int256::from(10i32), + Int256::from(-2i32) + ); + assert_eq!( + Int256::from(12i32) % Int256::from(-10i32), + Int256::from(2i32) + ); + assert_eq!( + Int256::from(-12i32) % Int256::from(-10i32), + Int256::from(-2i32) + ); + + // works for refs + let a = Int256::from(10u32); + let b = Int256::from(3u32); + let expected = Int256::from(1u32); + assert_eq!(a % b, expected); + assert_eq!(a % &b, expected); + assert_eq!(&a % b, expected); + assert_eq!(&a % &b, expected); + } + + #[test] + #[should_panic(expected = "divisor of zero")] + fn int256_rem_panics_for_zero() { + let _ = Int256::from(10u32) % Int256::zero(); + } + + #[test] + fn int256_rem_assign_works() { + let mut a = Int256::from(30u32); + a %= Int256::from(4u32); + assert_eq!(a, Int256::from(2u32)); + + // works for refs + let mut a = Int256::from(25u32); + let b = Int256::from(6u32); + a %= &b; + assert_eq!(a, Int256::from(1u32)); + } + + #[test] + fn int256_shr() { + let x: Int256 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128.into(); + assert_eq!(x >> 0, x); // right shift by 0 should be no-op + assert_eq!( + x >> 1, + Int256::from(0x4000_0000_0000_0000_0000_0000_0000_0000u128) + ); + assert_eq!( + x >> 4, + Int256::from(0x0800_0000_0000_0000_0000_0000_0000_0000u128) + ); + // right shift of MIN value by the maximum shift value should result in -1 (filled with 1s) + assert_eq!( + Int256::MIN >> (core::mem::size_of::() as u32 * 8 - 1), + -Int256::one() + ); + } + + #[test] + fn int256_shl() { + let x: Int256 = 0x0800_0000_0000_0000_0000_0000_0000_0000u128.into(); + assert_eq!(x << 0, x); // left shift by 0 should be no-op + assert_eq!( + x << 1, + Int256::from(0x1000_0000_0000_0000_0000_0000_0000_0000u128) + ); + assert_eq!( + x << 4, + Int256::from(0x8000_0000_0000_0000_0000_0000_0000_0000u128) + ); + // left shift by by the maximum shift value should result in MIN + assert_eq!( + Int256::one() << (core::mem::size_of::() as u32 * 8 - 1), + Int256::MIN + ); + } + + #[test] + fn int256_abs_diff_works() { + let a = Int256::from(42u32); + let b = Int256::from(5u32); + let expected = Uint256::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + + let c = Int256::from(-5i32); + assert_eq!(b.abs_diff(c), Uint256::from(10u32)); + assert_eq!(c.abs_diff(b), Uint256::from(10u32)); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int256_neg_min_panics() { + _ = -Int256::MIN; + } + + #[test] + fn int256_partial_eq() { + let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)] + .into_iter() + .map(|(lhs, rhs, expected): (u64, u64, bool)| { + (Int256::from(lhs), Int256::from(rhs), expected) + }); + + #[allow(clippy::op_ref)] + for (lhs, rhs, expected) in test_cases { + assert_eq!(lhs == rhs, expected); + assert_eq!(&lhs == rhs, expected); + assert_eq!(lhs == &rhs, expected); + assert_eq!(&lhs == &rhs, expected); + } + } +} diff --git a/packages/std/src/math/int512.rs b/packages/std/src/math/int512.rs new file mode 100644 index 000000000..2b122418e --- /dev/null +++ b/packages/std/src/math/int512.rs @@ -0,0 +1,1249 @@ +use core::fmt; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, + ShrAssign, Sub, SubAssign, +}; +use core::str::FromStr; +use forward_ref::{forward_ref_binop, forward_ref_op_assign}; +use schemars::JsonSchema; +use serde::{de, ser, Deserialize, Deserializer, Serialize}; + +use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError}; +use crate::{forward_ref_partial_eq, Uint128, Uint256, Uint512, Uint64}; + +/// Used internally - we don't want to leak this type since we might change +/// the implementation in the future. +use bnum::types::{I512, U512}; + +/// An implementation of i512 that is using strings for JSON encoding/decoding, +/// such that the full i512 range can be used for clients that convert JSON numbers to floats, +/// like JavaScript and jq. +/// +/// # Examples +/// +/// Use `from` to create instances out of primitive uint types or `new` to provide big +/// endian bytes: +/// +/// ``` +/// # use cosmwasm_std::Int512; +/// let a = Int512::from(258u128); +/// let b = Int512::new([ +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, +/// 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, +/// ]); +/// assert_eq!(a, b); +/// ``` +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] +pub struct Int512(#[schemars(with = "String")] I512); + +forward_ref_partial_eq!(Int512, Int512); + +impl Int512 { + pub const MAX: Int512 = Int512(I512::MAX); + pub const MIN: Int512 = Int512(I512::MIN); + + /// Creates a Int512(value) from a big endian representation. It's just an alias for + /// `from_be_bytes`. + #[inline] + pub const fn new(value: [u8; 64]) -> Self { + Self::from_be_bytes(value) + } + + /// Creates a Int512(0) + #[inline] + pub const fn zero() -> Self { + Int512(I512::ZERO) + } + + /// Creates a Int512(1) + #[inline] + pub const fn one() -> Self { + Self(I512::ONE) + } + + #[must_use] + pub const fn from_be_bytes(data: [u8; 64]) -> Self { + let words: [u64; 8] = [ + u64::from_le_bytes([ + data[63], data[62], data[61], data[60], data[59], data[58], data[57], data[56], + ]), + u64::from_le_bytes([ + data[55], data[54], data[53], data[52], data[51], data[50], data[49], data[48], + ]), + u64::from_le_bytes([ + data[47], data[46], data[45], data[44], data[43], data[42], data[41], data[40], + ]), + u64::from_le_bytes([ + data[39], data[38], data[37], data[36], data[35], data[34], data[33], data[32], + ]), + u64::from_le_bytes([ + data[31], data[30], data[29], data[28], data[27], data[26], data[25], data[24], + ]), + u64::from_le_bytes([ + data[23], data[22], data[21], data[20], data[19], data[18], data[17], data[16], + ]), + u64::from_le_bytes([ + data[15], data[14], data[13], data[12], data[11], data[10], data[9], data[8], + ]), + u64::from_le_bytes([ + data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0], + ]), + ]; + Self(I512::from_bits(U512::from_digits(words))) + } + + #[must_use] + pub const fn from_le_bytes(data: [u8; 64]) -> Self { + let words: [u64; 8] = [ + u64::from_le_bytes([ + data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], + ]), + u64::from_le_bytes([ + data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15], + ]), + u64::from_le_bytes([ + data[16], data[17], data[18], data[19], data[20], data[21], data[22], data[23], + ]), + u64::from_le_bytes([ + data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], + ]), + u64::from_le_bytes([ + data[32], data[33], data[34], data[35], data[36], data[37], data[38], data[39], + ]), + u64::from_le_bytes([ + data[40], data[41], data[42], data[43], data[44], data[45], data[46], data[47], + ]), + u64::from_le_bytes([ + data[48], data[49], data[50], data[51], data[52], data[53], data[54], data[55], + ]), + u64::from_le_bytes([ + data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63], + ]), + ]; + Self(I512::from_bits(U512::from_digits(words))) + } + + /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_be_bytes(self) -> [u8; 64] { + let bits = self.0.to_bits(); + let words = bits.digits(); + let words = [ + words[7].to_be_bytes(), + words[6].to_be_bytes(), + words[5].to_be_bytes(), + words[4].to_be_bytes(), + words[3].to_be_bytes(), + words[2].to_be_bytes(), + words[1].to_be_bytes(), + words[0].to_be_bytes(), + ]; + unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) } + } + + /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_le_bytes(self) -> [u8; 64] { + let bits = self.0.to_bits(); + let words = bits.digits(); + let words = [ + words[0].to_le_bytes(), + words[1].to_le_bytes(), + words[2].to_le_bytes(), + words[3].to_le_bytes(), + words[4].to_le_bytes(), + words[5].to_le_bytes(), + words[6].to_le_bytes(), + words[7].to_le_bytes(), + ]; + unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) } + } + + #[must_use] + pub const fn is_zero(&self) -> bool { + self.0.is_zero() + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn pow(self, exp: u32) -> Self { + Self(self.0.pow(exp)) + } + + pub fn checked_add(self, other: Self) -> Result { + self.0 + .checked_add(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Add, self, other)) + } + + pub fn checked_sub(self, other: Self) -> Result { + self.0 + .checked_sub(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Sub, self, other)) + } + + pub fn checked_mul(self, other: Self) -> Result { + self.0 + .checked_mul(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Mul, self, other)) + } + + pub fn checked_pow(self, exp: u32) -> Result { + self.0 + .checked_pow(exp) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp)) + } + + pub fn checked_div(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_div_euclid(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div_euclid(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_rem(self, other: Self) -> Result { + self.0 + .checked_rem(other.0) + .map(Self) + .ok_or_else(|| DivideByZeroError::new(self)) + } + + pub fn checked_shr(self, other: u32) -> Result { + if other >= 512 { + return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + } + + Ok(Self(self.0.shr(other))) + } + + pub fn checked_shl(self, other: u32) -> Result { + if other >= 512 { + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); + } + + Ok(Self(self.0.shl(other))) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self(self.0.wrapping_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_sub(self, other: Self) -> Self { + Self(self.0.wrapping_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_mul(self, other: Self) -> Self { + Self(self.0.wrapping_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_pow(self, other: u32) -> Self { + Self(self.0.wrapping_pow(other)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_add(self, other: Self) -> Self { + Self(self.0.saturating_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_sub(self, other: Self) -> Self { + Self(self.0.saturating_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_mul(self, other: Self) -> Self { + Self(self.0.saturating_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_pow(self, exp: u32) -> Self { + Self(self.0.saturating_pow(exp)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs_diff(self, other: Self) -> Uint512 { + Uint512(self.0.abs_diff(other.0)) + } +} + +impl From for Int512 { + fn from(val: Uint256) -> Self { + let mut bytes = [0u8; 64]; + bytes[32..].copy_from_slice(&val.to_be_bytes()); + + Self::from_be_bytes(bytes) + } +} + +impl From for Int512 { + fn from(val: Uint128) -> Self { + val.u128().into() + } +} + +impl From for Int512 { + fn from(val: Uint64) -> Self { + val.u64().into() + } +} + +impl From for Int512 { + fn from(val: u128) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: u64) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: u32) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: u16) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: u8) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: i128) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: i64) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: i32) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: i16) -> Self { + Int512(val.into()) + } +} + +impl From for Int512 { + fn from(val: i8) -> Self { + Int512(val.into()) + } +} + +impl TryFrom<&str> for Int512 { + type Error = StdError; + + fn try_from(val: &str) -> Result { + Self::from_str(val) + } +} + +impl FromStr for Int512 { + type Err = StdError; + + fn from_str(s: &str) -> Result { + match I512::from_str_radix(s, 10) { + Ok(u) => Ok(Self(u)), + Err(e) => Err(StdError::generic_err(format!("Parsing Int512: {e}"))), + } + } +} + +impl From for String { + fn from(original: Int512) -> Self { + original.to_string() + } +} + +impl fmt::Display for Int512 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Add for Int512 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int512(self.0.checked_add(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Add, add for Int512, Int512); + +impl Sub for Int512 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + Int512(self.0.checked_sub(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Sub, sub for Int512, Int512); + +impl SubAssign for Int512 { + fn sub_assign(&mut self, rhs: Int512) { + self.0 = self.0.checked_sub(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl SubAssign, sub_assign for Int512, Int512); + +impl Div for Int512 { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + Self(self.0.checked_div(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Div, div for Int512, Int512); + +impl Rem for Int512 { + type Output = Self; + + /// # Panics + /// + /// This operation will panic if `rhs` is zero. + #[inline] + fn rem(self, rhs: Self) -> Self { + Self(self.0.rem(rhs.0)) + } +} +forward_ref_binop!(impl Rem, rem for Int512, Int512); + +impl Not for Int512 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl Neg for Int512 { + type Output = Self; + + fn neg(self) -> Self::Output { + Self(-self.0) + } +} + +impl RemAssign for Int512 { + fn rem_assign(&mut self, rhs: Int512) { + *self = *self % rhs; + } +} +forward_ref_op_assign!(impl RemAssign, rem_assign for Int512, Int512); + +impl Mul for Int512 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + Self(self.0.checked_mul(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Mul, mul for Int512, Int512); + +impl MulAssign for Int512 { + fn mul_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_mul(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl MulAssign, mul_assign for Int512, Int512); + +impl Shr for Int512 { + type Output = Self; + + fn shr(self, rhs: u32) -> Self::Output { + self.checked_shr(rhs).unwrap_or_else(|_| { + panic!("right shift error: {rhs} is larger or equal than the number of bits in Int512",) + }) + } +} +forward_ref_binop!(impl Shr, shr for Int512, u32); + +impl Shl for Int512 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + self.checked_shl(rhs).unwrap_or_else(|_| { + panic!("left shift error: {rhs} is larger or equal than the number of bits in Int512",) + }) + } +} +forward_ref_binop!(impl Shl, shl for Int512, u32); + +impl AddAssign for Int512 { + fn add_assign(&mut self, rhs: Int512) { + self.0 = self.0.checked_add(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl AddAssign, add_assign for Int512, Int512); + +impl DivAssign for Int512 { + fn div_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_div(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl DivAssign, div_assign for Int512, Int512); + +impl ShrAssign for Int512 { + fn shr_assign(&mut self, rhs: u32) { + *self = Shr::::shr(*self, rhs); + } +} +forward_ref_op_assign!(impl ShrAssign, shr_assign for Int512, u32); + +impl ShlAssign for Int512 { + fn shl_assign(&mut self, rhs: u32) { + *self = Shl::::shl(*self, rhs); + } +} +forward_ref_op_assign!(impl ShlAssign, shl_assign for Int512, u32); + +impl Serialize for Int512 { + /// Serializes as an integer string using base 10 + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl<'de> Deserialize<'de> for Int512 { + /// Deserialized from an integer string using base 10 + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(Int512Visitor) + } +} + +struct Int512Visitor; + +impl<'de> de::Visitor<'de> for Int512Visitor { + type Value = Int512; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string-encoded integer") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Int512::try_from(v).map_err(|e| E::custom(format!("invalid Int512 '{v}' - {e}"))) + } +} + +impl core::iter::Sum for Int512 +where + Self: Add, +{ + fn sum>(iter: I) -> Self { + iter.fold(Self::zero(), Add::add) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{from_slice, to_vec}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 64); + } + + #[test] + fn int512_new_works() { + let num = Int512::new([1; 64]); + let a: [u8; 64] = num.to_be_bytes(); + assert_eq!(a, [1; 64]); + + let be_bytes = [ + 0u8, 222u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let num = Int512::new(be_bytes); + let resulting_bytes: [u8; 64] = num.to_be_bytes(); + assert_eq!(be_bytes, resulting_bytes); + } + + #[test] + fn int512_not_works() { + let num = Int512::new([1; 64]); + let a = (!num).to_be_bytes(); + assert_eq!(a, [254; 64]); + + assert_eq!(!Int512::from(-1234806i128), Int512::from(!-1234806i128)); + + assert_eq!(!Int512::MAX, Int512::MIN); + assert_eq!(!Int512::MIN, Int512::MAX); + } + + #[test] + fn int512_zero_works() { + let zero = Int512::zero(); + assert_eq!(zero.to_be_bytes(), [0; 64]); + } + + #[test] + fn uint512_one_works() { + let one = Int512::one(); + let mut one_be = [0; 64]; + one_be[63] = 1; + + assert_eq!(one.to_be_bytes(), one_be); + } + + #[test] + fn int512_endianness() { + let be_bytes = [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8, + ]; + let le_bytes = [ + 3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]; + + // These should all be the same. + let num1 = Int512::new(be_bytes); + let num2 = Int512::from_be_bytes(be_bytes); + let num3 = Int512::from_le_bytes(le_bytes); + assert_eq!(num1, Int512::from(65536u32 + 512 + 3)); + assert_eq!(num1, num2); + assert_eq!(num1, num3); + } + + #[test] + fn int512_convert_from() { + let a = Int512::from(5u128); + assert_eq!(a.0, I512::from(5u32)); + + let a = Int512::from(5u64); + assert_eq!(a.0, I512::from(5u32)); + + let a = Int512::from(5u32); + assert_eq!(a.0, I512::from(5u32)); + + let a = Int512::from(5u16); + assert_eq!(a.0, I512::from(5u32)); + + let a = Int512::from(5u8); + assert_eq!(a.0, I512::from(5u32)); + + let a = Int512::from(-5i128); + assert_eq!(a.0, I512::from(-5i32)); + + let a = Int512::from(-5i64); + assert_eq!(a.0, I512::from(-5i32)); + + let a = Int512::from(-5i32); + assert_eq!(a.0, I512::from(-5i32)); + + let a = Int512::from(-5i16); + assert_eq!(a.0, I512::from(-5i32)); + + let a = Int512::from(-5i8); + assert_eq!(a.0, I512::from(-5i32)); + + let result = Int512::try_from("34567"); + assert_eq!( + result.unwrap().0, + I512::from_str_radix("34567", 10).unwrap() + ); + + let result = Int512::try_from("1.23"); + assert!(result.is_err()); + } + + #[test] + fn int512_implements_display() { + let a = Int512::from(12345u32); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); + assert_eq!(a.to_string(), "12345"); + + let a = Int512::from(-12345i32); + assert_eq!(format!("Embedded: {a}"), "Embedded: -12345"); + assert_eq!(a.to_string(), "-12345"); + + let a = Int512::zero(); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); + assert_eq!(a.to_string(), "0"); + } + + #[test] + fn int512_display_padding_works() { + // width > natural representation + let a = Int512::from(123u64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + let a = Int512::from(-123i64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123"); + + // width < natural representation + let a = Int512::from(123u64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); + let a = Int512::from(-123i64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123"); + } + + #[test] + fn int512_to_be_bytes_works() { + assert_eq!(Int512::zero().to_be_bytes(), [0; 64]); + + let mut max = [0xff; 64]; + max[0] = 0x7f; + assert_eq!(Int512::MAX.to_be_bytes(), max); + + let mut one = [0; 64]; + one[63] = 1; + assert_eq!(Int512::from(1u128).to_be_bytes(), one); + // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(64, "big")]` + assert_eq!( + Int512::from(240282366920938463463374607431768124608u128).to_be_bytes(), + [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 180, 196, 179, 87, 165, + 121, 59, 133, 246, 117, 221, 191, 255, 254, 172, 192 + ] + ); + assert_eq!( + Int512::from_be_bytes([ + 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54, + 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134, + 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8, + 252, 96, 230, 187, 38, 29 + ]) + .to_be_bytes(), + [ + 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54, + 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134, + 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8, + 252, 96, 230, 187, 38, 29 + ] + ); + } + + #[test] + fn int512_to_le_bytes_works() { + assert_eq!(Int512::zero().to_le_bytes(), [0; 64]); + + let mut max = [0xff; 64]; + max[63] = 0x7f; + assert_eq!(Int512::MAX.to_le_bytes(), max); + + let mut one = [0; 64]; + one[0] = 1; + assert_eq!(Int512::from(1u128).to_le_bytes(), one); + // Python: `[b for b in (240282366920938463463374607431768124608).to_bytes(64, "little")]` + assert_eq!( + Int512::from(240282366920938463463374607431768124608u128).to_le_bytes(), + [ + 192, 172, 254, 255, 191, 221, 117, 246, 133, 59, 121, 165, 87, 179, 196, 180, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ] + ); + assert_eq!( + Int512::from_be_bytes([ + 17, 4, 23, 32, 87, 67, 123, 200, 58, 91, 0, 38, 33, 21, 67, 78, 87, 76, 65, 54, + 211, 201, 192, 7, 42, 233, 2, 240, 200, 115, 150, 240, 218, 88, 106, 45, 208, 134, + 238, 119, 85, 22, 14, 88, 166, 195, 154, 73, 64, 10, 44, 59, 13, 22, 47, 12, 99, 8, + 252, 96, 230, 187, 38, 29 + ]) + .to_le_bytes(), + [ + 29, 38, 187, 230, 96, 252, 8, 99, 12, 47, 22, 13, 59, 44, 10, 64, 73, 154, 195, + 166, 88, 14, 22, 85, 119, 238, 134, 208, 45, 106, 88, 218, 240, 150, 115, 200, 240, + 2, 233, 42, 7, 192, 201, 211, 54, 65, 76, 87, 78, 67, 21, 33, 38, 0, 91, 58, 200, + 123, 67, 87, 32, 23, 4, 17 + ] + ); + } + + #[test] + fn int512_is_zero_works() { + assert!(Int512::zero().is_zero()); + assert!(Int512(I512::from(0u32)).is_zero()); + + assert!(!Int512::from(1u32).is_zero()); + assert!(!Int512::from(123u32).is_zero()); + assert!(!Int512::from(-123i32).is_zero()); + } + + #[test] + fn int512_wrapping_methods() { + // wrapping_add + assert_eq!( + Int512::from(2u32).wrapping_add(Int512::from(2u32)), + Int512::from(4u32) + ); // non-wrapping + assert_eq!(Int512::MAX.wrapping_add(Int512::from(1u32)), Int512::MIN); // wrapping + + // wrapping_sub + assert_eq!( + Int512::from(7u32).wrapping_sub(Int512::from(5u32)), + Int512::from(2u32) + ); // non-wrapping + assert_eq!(Int512::MIN.wrapping_sub(Int512::from(1u32)), Int512::MAX); // wrapping + + // wrapping_mul + assert_eq!( + Int512::from(3u32).wrapping_mul(Int512::from(2u32)), + Int512::from(6u32) + ); // non-wrapping + assert_eq!( + Int512::MAX.wrapping_mul(Int512::from(2u32)), + Int512::from(-2i32) + ); // wrapping + + // wrapping_pow + assert_eq!(Int512::from(2u32).wrapping_pow(3), Int512::from(8u32)); // non-wrapping + assert_eq!(Int512::MAX.wrapping_pow(2), Int512::from(1u32)); // wrapping + } + + #[test] + fn int512_json() { + let orig = Int512::from(1234567890987654321u128); + let serialized = to_vec(&orig).unwrap(); + assert_eq!(serialized.as_slice(), b"\"1234567890987654321\""); + let parsed: Int512 = from_slice(&serialized).unwrap(); + assert_eq!(parsed, orig); + } + + #[test] + fn int512_compare() { + let a = Int512::from(12345u32); + let b = Int512::from(23456u32); + + assert!(a < b); + assert!(b > a); + assert_eq!(a, Int512::from(12345u32)); + } + + #[test] + #[allow(clippy::op_ref)] + fn int512_math() { + let a = Int512::from(-12345i32); + let b = Int512::from(23456u32); + + // test + with owned and reference right hand side + assert_eq!(a + b, Int512::from(11111u32)); + assert_eq!(a + &b, Int512::from(11111u32)); + + // test - with owned and reference right hand side + assert_eq!(b - a, Int512::from(35801u32)); + assert_eq!(b - &a, Int512::from(35801u32)); + + // test += with owned and reference right hand side + let mut c = Int512::from(300000u32); + c += b; + assert_eq!(c, Int512::from(323456u32)); + let mut d = Int512::from(300000u32); + d += &b; + assert_eq!(d, Int512::from(323456u32)); + + // test -= with owned and reference right hand side + let mut c = Int512::from(300000u32); + c -= b; + assert_eq!(c, Int512::from(276544u32)); + let mut d = Int512::from(300000u32); + d -= &b; + assert_eq!(d, Int512::from(276544u32)); + + // test - with negative result + assert_eq!(a - b, Int512::from(-35801i32)); + } + + #[test] + #[should_panic] + fn int512_add_overflow_panics() { + let _ = Int512::MAX + Int512::from(12u32); + } + + #[test] + #[allow(clippy::op_ref)] + fn int512_sub_works() { + assert_eq!(Int512::from(2u32) - Int512::from(1u32), Int512::from(1u32)); + assert_eq!(Int512::from(2u32) - Int512::from(0u32), Int512::from(2u32)); + assert_eq!(Int512::from(2u32) - Int512::from(2u32), Int512::from(0u32)); + assert_eq!(Int512::from(2u32) - Int512::from(3u32), Int512::from(-1i32)); + + // works for refs + let a = Int512::from(10u32); + let b = Int512::from(3u32); + let expected = Int512::from(7u32); + assert_eq!(a - b, expected); + assert_eq!(a - &b, expected); + assert_eq!(&a - b, expected); + assert_eq!(&a - &b, expected); + } + + #[test] + #[should_panic] + fn int512_sub_overflow_panics() { + let _ = Int512::MIN + Int512::one() - Int512::from(2u32); + } + + #[test] + fn int512_sub_assign_works() { + let mut a = Int512::from(14u32); + a -= Int512::from(2u32); + assert_eq!(a, Int512::from(12u32)); + + // works for refs + let mut a = Int512::from(10u32); + let b = Int512::from(3u32); + let expected = Int512::from(7u32); + a -= &b; + assert_eq!(a, expected); + } + + #[test] + #[allow(clippy::op_ref)] + fn int512_mul_works() { + assert_eq!(Int512::from(2u32) * Int512::from(3u32), Int512::from(6u32)); + assert_eq!(Int512::from(2u32) * Int512::zero(), Int512::zero()); + + // works for refs + let a = Int512::from(11u32); + let b = Int512::from(3u32); + let expected = Int512::from(33u32); + assert_eq!(a * b, expected); + assert_eq!(a * &b, expected); + assert_eq!(&a * b, expected); + assert_eq!(&a * &b, expected); + } + + #[test] + fn int512_mul_assign_works() { + let mut a = Int512::from(14u32); + a *= Int512::from(2u32); + assert_eq!(a, Int512::from(28u32)); + + // works for refs + let mut a = Int512::from(10u32); + let b = Int512::from(3u32); + a *= &b; + assert_eq!(a, Int512::from(30u32)); + } + + #[test] + fn int512_pow_works() { + assert_eq!(Int512::from(2u32).pow(2), Int512::from(4u32)); + assert_eq!(Int512::from(2u32).pow(10), Int512::from(1024u32)); + } + + #[test] + #[should_panic] + fn int512_pow_overflow_panics() { + _ = Int512::MAX.pow(2u32); + } + + #[test] + fn int512_shr_works() { + let original = Int512::new([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8, + ]); + + let shifted = Int512::new([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8, + ]); + + assert_eq!(original >> 2u32, shifted); + } + + #[test] + #[should_panic] + fn int512_shr_overflow_panics() { + let _ = Int512::from(1u32) >> 512u32; + } + + #[test] + fn sum_works() { + let nums = vec![ + Int512::from(17u32), + Int512::from(123u32), + Int512::from(540u32), + Int512::from(82u32), + ]; + let expected = Int512::from(762u32); + + let sum_as_ref: Int512 = nums.iter().sum(); + assert_eq!(expected, sum_as_ref); + + let sum_as_owned: Int512 = nums.into_iter().sum(); + assert_eq!(expected, sum_as_owned); + } + + #[test] + fn int512_methods() { + // checked_* + assert!(matches!( + Int512::MAX.checked_add(Int512::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int512::from(1u32).checked_add(Int512::from(1u32)), + Ok(Int512::from(2u32)), + ); + assert!(matches!( + Int512::MIN.checked_sub(Int512::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int512::from(2u32).checked_sub(Int512::from(1u32)), + Ok(Int512::from(1u32)), + ); + assert!(matches!( + Int512::MAX.checked_mul(Int512::from(2u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int512::from(2u32).checked_mul(Int512::from(2u32)), + Ok(Int512::from(4u32)), + ); + assert!(matches!( + Int512::MAX.checked_pow(2u32), + Err(OverflowError { .. }) + )); + assert_eq!(Int512::from(2u32).checked_pow(3u32), Ok(Int512::from(8u32)),); + assert_eq!( + Int512::MAX.checked_div(Int512::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int512::from(6u32).checked_div(Int512::from(2u32)), + Ok(Int512::from(3u32)), + ); + assert_eq!( + Int512::MAX.checked_div_euclid(Int512::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int512::from(6u32).checked_div_euclid(Int512::from(2u32)), + Ok(Int512::from(3u32)), + ); + assert_eq!( + Int512::from(7u32).checked_div_euclid(Int512::from(2u32)), + Ok(Int512::from(3u32)), + ); + assert!(matches!( + Int512::MAX.checked_rem(Int512::from(0u32)), + Err(DivideByZeroError { .. }) + )); + // checked_* with negative numbers + assert_eq!( + Int512::from(-12i32).checked_div(Int512::from(10i32)), + Ok(Int512::from(-1i32)), + ); + assert_eq!( + Int512::from(-2i32).checked_pow(3u32), + Ok(Int512::from(-8i32)), + ); + assert_eq!( + Int512::from(-6i32).checked_mul(Int512::from(-7i32)), + Ok(Int512::from(42i32)), + ); + assert_eq!( + Int512::from(-2i32).checked_add(Int512::from(3i32)), + Ok(Int512::from(1i32)), + ); + assert_eq!( + Int512::from(-1i32).checked_div_euclid(Int512::from(-2i32)), + Ok(Int512::from(1u32)), + ); + + // saturating_* + assert_eq!(Int512::MAX.saturating_add(Int512::from(1u32)), Int512::MAX); + assert_eq!(Int512::MIN.saturating_sub(Int512::from(1u32)), Int512::MIN); + assert_eq!(Int512::MAX.saturating_mul(Int512::from(2u32)), Int512::MAX); + assert_eq!(Int512::from(4u32).saturating_pow(2u32), Int512::from(16u32)); + assert_eq!(Int512::MAX.saturating_pow(2u32), Int512::MAX); + } + + #[test] + #[allow(clippy::op_ref)] + fn int512_implements_rem() { + let a = Int512::from(10u32); + assert_eq!(a % Int512::from(10u32), Int512::zero()); + assert_eq!(a % Int512::from(2u32), Int512::zero()); + assert_eq!(a % Int512::from(1u32), Int512::zero()); + assert_eq!(a % Int512::from(3u32), Int512::from(1u32)); + assert_eq!(a % Int512::from(4u32), Int512::from(2u32)); + + assert_eq!( + Int512::from(-12i32) % Int512::from(10i32), + Int512::from(-2i32) + ); + assert_eq!( + Int512::from(12i32) % Int512::from(-10i32), + Int512::from(2i32) + ); + assert_eq!( + Int512::from(-12i32) % Int512::from(-10i32), + Int512::from(-2i32) + ); + + // works for refs + let a = Int512::from(10u32); + let b = Int512::from(3u32); + let expected = Int512::from(1u32); + assert_eq!(a % b, expected); + assert_eq!(a % &b, expected); + assert_eq!(&a % b, expected); + assert_eq!(&a % &b, expected); + } + + #[test] + #[should_panic(expected = "divisor of zero")] + fn int512_rem_panics_for_zero() { + let _ = Int512::from(10u32) % Int512::zero(); + } + + #[test] + fn int512_rem_assign_works() { + let mut a = Int512::from(30u32); + a %= Int512::from(4u32); + assert_eq!(a, Int512::from(2u32)); + + // works for refs + let mut a = Int512::from(25u32); + let b = Int512::from(6u32); + a %= &b; + assert_eq!(a, Int512::from(1u32)); + } + + #[test] + fn int512_shr() { + let x: Int512 = 0x8000_0000_0000_0000_0000_0000_0000_0000u128.into(); + assert_eq!(x >> 0, x); // right shift by 0 should be no-op + assert_eq!( + x >> 1, + Int512::from(0x4000_0000_0000_0000_0000_0000_0000_0000u128) + ); + assert_eq!( + x >> 4, + Int512::from(0x0800_0000_0000_0000_0000_0000_0000_0000u128) + ); + // right shift of MIN value by the maximum shift value should result in -1 (filled with 1s) + assert_eq!( + Int512::MIN >> (core::mem::size_of::() as u32 * 8 - 1), + -Int512::one() + ); + } + + #[test] + fn int512_shl() { + let x: Int512 = 0x0800_0000_0000_0000_0000_0000_0000_0000u128.into(); + assert_eq!(x << 0, x); // left shift by 0 should be no-op + assert_eq!( + x << 1, + Int512::from(0x1000_0000_0000_0000_0000_0000_0000_0000u128) + ); + assert_eq!( + x << 4, + Int512::from(0x8000_0000_0000_0000_0000_0000_0000_0000u128) + ); + // left shift by by the maximum shift value should result in MIN + assert_eq!( + Int512::one() << (core::mem::size_of::() as u32 * 8 - 1), + Int512::MIN + ); + } + + #[test] + fn int512_abs_diff_works() { + let a = Int512::from(42u32); + let b = Int512::from(5u32); + let expected = Uint512::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + + let c = Int512::from(-5i32); + assert_eq!(b.abs_diff(c), Uint512::from(10u32)); + assert_eq!(c.abs_diff(b), Uint512::from(10u32)); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int512_neg_min_panics() { + _ = -Int512::MIN; + } + + #[test] + fn int512_partial_eq() { + let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)] + .into_iter() + .map(|(lhs, rhs, expected): (u64, u64, bool)| { + (Int512::from(lhs), Int512::from(rhs), expected) + }); + + #[allow(clippy::op_ref)] + for (lhs, rhs, expected) in test_cases { + assert_eq!(lhs == rhs, expected); + assert_eq!(&lhs == rhs, expected); + assert_eq!(lhs == &rhs, expected); + assert_eq!(&lhs == &rhs, expected); + } + } +} diff --git a/packages/std/src/math/int64.rs b/packages/std/src/math/int64.rs new file mode 100644 index 000000000..2e9ac7f68 --- /dev/null +++ b/packages/std/src/math/int64.rs @@ -0,0 +1,1056 @@ +use core::fmt; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Not, Rem, RemAssign, Shl, ShlAssign, Shr, + ShrAssign, Sub, SubAssign, +}; +use core::str::FromStr; +use forward_ref::{forward_ref_binop, forward_ref_op_assign}; +use schemars::JsonSchema; +use serde::{de, ser, Deserialize, Deserializer, Serialize}; + +use crate::errors::{DivideByZeroError, DivisionError, OverflowError, OverflowOperation, StdError}; +use crate::{forward_ref_partial_eq, Uint64}; + +/// An implementation of i64 that is using strings for JSON encoding/decoding, +/// such that the full i64 range can be used for clients that convert JSON numbers to floats, +/// like JavaScript and jq. +/// +/// # Examples +/// +/// Use `from` to create instances of this and `i64` to get the value out: +/// +/// ``` +/// # use cosmwasm_std::Int64; +/// let a = Int64::from(258i64); +/// assert_eq!(a.i64(), 258); +/// ``` +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] +pub struct Int64(#[schemars(with = "String")] i64); + +forward_ref_partial_eq!(Int64, Int64); + +impl Int64 { + pub const MAX: Int64 = Int64(i64::MAX); + pub const MIN: Int64 = Int64(i64::MIN); + + /// Creates a Int64(value). + /// + /// This method is less flexible than `from` but can be called in a const context. + #[inline] + pub const fn new(value: i64) -> Self { + Self(value) + } + + /// Creates a Int64(0) + #[inline] + pub const fn zero() -> Self { + Int64(0) + } + + /// Creates a Int64(1) + #[inline] + pub const fn one() -> Self { + Self(1) + } + + /// Returns a copy of the internal data + pub const fn i64(&self) -> i64 { + self.0 + } + + #[must_use] + pub const fn from_be_bytes(data: [u8; 8]) -> Self { + Self(i64::from_be_bytes(data)) + } + + #[must_use] + pub const fn from_le_bytes(data: [u8; 8]) -> Self { + Self(i64::from_le_bytes(data)) + } + + /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_be_bytes(self) -> [u8; 8] { + self.0.to_be_bytes() + } + + /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn to_le_bytes(self) -> [u8; 8] { + self.0.to_le_bytes() + } + + #[must_use] + pub const fn is_zero(&self) -> bool { + self.0 == 0 + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn pow(self, exp: u32) -> Self { + Self(self.0.pow(exp)) + } + + pub fn checked_add(self, other: Self) -> Result { + self.0 + .checked_add(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Add, self, other)) + } + + pub fn checked_sub(self, other: Self) -> Result { + self.0 + .checked_sub(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Sub, self, other)) + } + + pub fn checked_mul(self, other: Self) -> Result { + self.0 + .checked_mul(other.0) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Mul, self, other)) + } + + pub fn checked_pow(self, exp: u32) -> Result { + self.0 + .checked_pow(exp) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp)) + } + + pub fn checked_div(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_div_euclid(self, other: Self) -> Result { + if other.is_zero() { + return Err(DivisionError::DivideByZero); + } + self.0 + .checked_div_euclid(other.0) + .map(Self) + .ok_or(DivisionError::Overflow) + } + + pub fn checked_rem(self, other: Self) -> Result { + self.0 + .checked_rem(other.0) + .map(Self) + .ok_or_else(|| DivideByZeroError::new(self)) + } + + pub fn checked_shr(self, other: u32) -> Result { + if other >= 64 { + return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + } + + Ok(Self(self.0.shr(other))) + } + + pub fn checked_shl(self, other: u32) -> Result { + if other >= 64 { + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); + } + + Ok(Self(self.0.shl(other))) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_add(self, other: Self) -> Self { + Self(self.0.wrapping_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_sub(self, other: Self) -> Self { + Self(self.0.wrapping_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_mul(self, other: Self) -> Self { + Self(self.0.wrapping_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub fn wrapping_pow(self, other: u32) -> Self { + Self(self.0.wrapping_pow(other)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_add(self, other: Self) -> Self { + Self(self.0.saturating_add(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_sub(self, other: Self) -> Self { + Self(self.0.saturating_sub(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_mul(self, other: Self) -> Self { + Self(self.0.saturating_mul(other.0)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub fn saturating_pow(self, exp: u32) -> Self { + Self(self.0.saturating_pow(exp)) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs_diff(self, other: Self) -> Uint64 { + Uint64(self.0.abs_diff(other.0)) + } +} + +impl From for Int64 { + fn from(val: u32) -> Self { + Int64(val.into()) + } +} + +impl From for Int64 { + fn from(val: u16) -> Self { + Int64(val.into()) + } +} + +impl From for Int64 { + fn from(val: u8) -> Self { + Int64(val.into()) + } +} + +impl From for Int64 { + fn from(val: i64) -> Self { + Int64(val) + } +} + +impl From for Int64 { + fn from(val: i32) -> Self { + Int64(val.into()) + } +} + +impl From for Int64 { + fn from(val: i16) -> Self { + Int64(val.into()) + } +} + +impl From for Int64 { + fn from(val: i8) -> Self { + Int64(val.into()) + } +} + +impl TryFrom<&str> for Int64 { + type Error = StdError; + + fn try_from(val: &str) -> Result { + Self::from_str(val) + } +} + +impl FromStr for Int64 { + type Err = StdError; + + fn from_str(s: &str) -> Result { + match s.parse::() { + Ok(u) => Ok(Self(u)), + Err(e) => Err(StdError::generic_err(format!("Parsing Int64: {e}"))), + } + } +} + +impl From for String { + fn from(original: Int64) -> Self { + original.to_string() + } +} + +impl fmt::Display for Int64 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl Add for Int64 { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Int64(self.0.checked_add(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Add, add for Int64, Int64); + +impl Sub for Int64 { + type Output = Self; + + fn sub(self, rhs: Self) -> Self { + Int64(self.0.checked_sub(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Sub, sub for Int64, Int64); + +impl SubAssign for Int64 { + fn sub_assign(&mut self, rhs: Int64) { + self.0 = self.0.checked_sub(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl SubAssign, sub_assign for Int64, Int64); + +impl Div for Int64 { + type Output = Self; + + fn div(self, rhs: Self) -> Self::Output { + Self(self.0.checked_div(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Div, div for Int64, Int64); + +impl Rem for Int64 { + type Output = Self; + + /// # Panics + /// + /// This operation will panic if `rhs` is zero. + #[inline] + fn rem(self, rhs: Self) -> Self { + Self(self.0.rem(rhs.0)) + } +} +forward_ref_binop!(impl Rem, rem for Int64, Int64); + +impl Not for Int64 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl Neg for Int64 { + type Output = Self; + + fn neg(self) -> Self::Output { + Self(-self.0) + } +} + +impl RemAssign for Int64 { + fn rem_assign(&mut self, rhs: Int64) { + *self = *self % rhs; + } +} +forward_ref_op_assign!(impl RemAssign, rem_assign for Int64, Int64); + +impl Mul for Int64 { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + Self(self.0.checked_mul(rhs.0).unwrap()) + } +} +forward_ref_binop!(impl Mul, mul for Int64, Int64); + +impl MulAssign for Int64 { + fn mul_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_mul(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl MulAssign, mul_assign for Int64, Int64); + +impl Shr for Int64 { + type Output = Self; + + fn shr(self, rhs: u32) -> Self::Output { + self.checked_shr(rhs).unwrap_or_else(|_| { + panic!("right shift error: {rhs} is larger or equal than the number of bits in Int64",) + }) + } +} +forward_ref_binop!(impl Shr, shr for Int64, u32); + +impl Shl for Int64 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + self.checked_shl(rhs).unwrap_or_else(|_| { + panic!("left shift error: {rhs} is larger or equal than the number of bits in Int64",) + }) + } +} +forward_ref_binop!(impl Shl, shl for Int64, u32); + +impl AddAssign for Int64 { + fn add_assign(&mut self, rhs: Int64) { + self.0 = self.0.checked_add(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl AddAssign, add_assign for Int64, Int64); + +impl DivAssign for Int64 { + fn div_assign(&mut self, rhs: Self) { + self.0 = self.0.checked_div(rhs.0).unwrap(); + } +} +forward_ref_op_assign!(impl DivAssign, div_assign for Int64, Int64); + +impl ShrAssign for Int64 { + fn shr_assign(&mut self, rhs: u32) { + *self = Shr::::shr(*self, rhs); + } +} +forward_ref_op_assign!(impl ShrAssign, shr_assign for Int64, u32); + +impl ShlAssign for Int64 { + fn shl_assign(&mut self, rhs: u32) { + *self = Shl::::shl(*self, rhs); + } +} +forward_ref_op_assign!(impl ShlAssign, shl_assign for Int64, u32); + +impl Serialize for Int64 { + /// Serializes as an integer string using base 10 + fn serialize(&self, serializer: S) -> Result + where + S: ser::Serializer, + { + serializer.serialize_str(&self.to_string()) + } +} + +impl<'de> Deserialize<'de> for Int64 { + /// Deserialized from an integer string using base 10 + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(Int64Visitor) + } +} + +struct Int64Visitor; + +impl<'de> de::Visitor<'de> for Int64Visitor { + type Value = Int64; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("string-encoded integer") + } + + fn visit_str(self, v: &str) -> Result + where + E: de::Error, + { + Int64::try_from(v).map_err(|e| E::custom(format!("invalid Int64 '{v}' - {e}"))) + } +} + +impl core::iter::Sum for Int64 +where + Self: Add, +{ + fn sum>(iter: I) -> Self { + iter.fold(Self::zero(), Add::add) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{from_slice, to_vec}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 8); + } + + #[test] + fn int64_from_be_bytes_works() { + let num = Int64::from_be_bytes([1; 8]); + let a: [u8; 8] = num.to_be_bytes(); + assert_eq!(a, [1; 8]); + + let be_bytes = [0u8, 222u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; + let num = Int64::from_be_bytes(be_bytes); + let resulting_bytes: [u8; 8] = num.to_be_bytes(); + assert_eq!(be_bytes, resulting_bytes); + } + + #[test] + fn int64_new_works() { + let num = Int64::new(222); + assert_eq!(num.i64(), 222); + + let num = Int64::new(-222); + assert_eq!(num.i64(), -222); + + let num = Int64::new(i64::MAX); + assert_eq!(num.i64(), i64::MAX); + + let num = Int64::new(i64::MIN); + assert_eq!(num.i64(), i64::MIN); + } + + #[test] + fn int64_not_works() { + assert_eq!(!Int64::new(222), Int64::new(!222)); + assert_eq!(!Int64::new(-222), Int64::new(!-222)); + + assert_eq!(!Int64::MAX, Int64::new(!i64::MAX)); + assert_eq!(!Int64::MIN, Int64::new(!i64::MIN)); + } + + #[test] + fn int64_zero_works() { + let zero = Int64::zero(); + assert_eq!(zero.to_be_bytes(), [0; 8]); + } + + #[test] + fn uint64_one_works() { + let one = Int64::one(); + let mut one_be = [0; 8]; + one_be[7] = 1; + + assert_eq!(one.to_be_bytes(), one_be); + } + + #[test] + fn int64_endianness() { + let be_bytes = [0u8, 0u8, 0u8, 0u8, 0u8, 1u8, 2u8, 3u8]; + let le_bytes = [3u8, 2u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8]; + + // These should all be the same. + let num1 = Int64::from_be_bytes(be_bytes); + let num2 = Int64::from_le_bytes(le_bytes); + assert_eq!(num1, Int64::from(65536u32 + 512 + 3)); + assert_eq!(num1, num2); + } + + #[test] + fn int64_convert_from() { + let a = Int64::from(5i64); + assert_eq!(a.0, i64::from(5u32)); + + let a = Int64::from(5i64); + assert_eq!(a.0, i64::from(5u32)); + + let a = Int64::from(5u32); + assert_eq!(a.0, i64::from(5u32)); + + let a = Int64::from(5u16); + assert_eq!(a.0, i64::from(5u32)); + + let a = Int64::from(5u8); + assert_eq!(a.0, i64::from(5u32)); + + let a = Int64::from(-5i64); + assert_eq!(a.0, i64::from(-5i32)); + + let a = Int64::from(-5i64); + assert_eq!(a.0, i64::from(-5i32)); + + let a = Int64::from(-5i32); + assert_eq!(a.0, i64::from(-5i32)); + + let a = Int64::from(-5i16); + assert_eq!(a.0, i64::from(-5i32)); + + let a = Int64::from(-5i8); + assert_eq!(a.0, i64::from(-5i32)); + + let result = Int64::try_from("34567"); + assert_eq!(result.unwrap().0, "34567".parse::().unwrap()); + + let result = Int64::try_from("1.23"); + assert!(result.is_err()); + } + + #[test] + fn int64_implements_display() { + let a = Int64::from(12345u32); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); + assert_eq!(a.to_string(), "12345"); + + let a = Int64::from(-12345i32); + assert_eq!(format!("Embedded: {a}"), "Embedded: -12345"); + assert_eq!(a.to_string(), "-12345"); + + let a = Int64::zero(); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); + assert_eq!(a.to_string(), "0"); + } + + #[test] + fn int64_display_padding_works() { + // width > natural representation + let a = Int64::from(123i64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + let a = Int64::from(-123i64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: -0123"); + + // width < natural representation + let a = Int64::from(123i64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); + let a = Int64::from(-123i64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: -123"); + } + + #[test] + fn int64_to_be_bytes_works() { + assert_eq!(Int64::zero().to_be_bytes(), [0; 8]); + + let mut max = [0xff; 8]; + max[0] = 0x7f; + assert_eq!(Int64::MAX.to_be_bytes(), max); + + let mut one = [0; 8]; + one[7] = 1; + assert_eq!(Int64::from(1i64).to_be_bytes(), one); + // Python: `[b for b in (8535972485454015680).to_bytes(8, "big")]` + assert_eq!( + Int64::from(8535972485454015680i64).to_be_bytes(), + [118, 117, 221, 191, 255, 254, 172, 192] + ); + assert_eq!( + Int64::from_be_bytes([17, 4, 23, 32, 87, 67, 123, 200]).to_be_bytes(), + [17, 4, 23, 32, 87, 67, 123, 200] + ); + } + + #[test] + fn int64_to_le_bytes_works() { + assert_eq!(Int64::zero().to_le_bytes(), [0; 8]); + + let mut max = [0xff; 8]; + max[7] = 0x7f; + assert_eq!(Int64::MAX.to_le_bytes(), max); + + let mut one = [0; 8]; + one[0] = 1; + assert_eq!(Int64::from(1i64).to_le_bytes(), one); + // Python: `[b for b in (8535972485454015680).to_bytes(8, "little")]` + assert_eq!( + Int64::from(8535972485454015680i64).to_le_bytes(), + [192, 172, 254, 255, 191, 221, 117, 118] + ); + assert_eq!( + Int64::from_be_bytes([17, 4, 23, 32, 87, 67, 123, 200]).to_le_bytes(), + [200, 123, 67, 87, 32, 23, 4, 17] + ); + } + + #[test] + fn int64_is_zero_works() { + assert!(Int64::zero().is_zero()); + assert!(Int64(i64::from(0u32)).is_zero()); + + assert!(!Int64::from(1u32).is_zero()); + assert!(!Int64::from(123u32).is_zero()); + assert!(!Int64::from(-123i32).is_zero()); + } + + #[test] + fn int64_wrapping_methods() { + // wrapping_add + assert_eq!( + Int64::from(2u32).wrapping_add(Int64::from(2u32)), + Int64::from(4u32) + ); // non-wrapping + assert_eq!(Int64::MAX.wrapping_add(Int64::from(1u32)), Int64::MIN); // wrapping + + // wrapping_sub + assert_eq!( + Int64::from(7u32).wrapping_sub(Int64::from(5u32)), + Int64::from(2u32) + ); // non-wrapping + assert_eq!(Int64::MIN.wrapping_sub(Int64::from(1u32)), Int64::MAX); // wrapping + + // wrapping_mul + assert_eq!( + Int64::from(3u32).wrapping_mul(Int64::from(2u32)), + Int64::from(6u32) + ); // non-wrapping + assert_eq!( + Int64::MAX.wrapping_mul(Int64::from(2u32)), + Int64::from(-2i32) + ); // wrapping + + // wrapping_pow + assert_eq!(Int64::from(2u32).wrapping_pow(3), Int64::from(8u32)); // non-wrapping + assert_eq!(Int64::MAX.wrapping_pow(2), Int64::from(1u32)); // wrapping + } + + #[test] + fn int64_json() { + let orig = Int64::from(1234567890987654321i64); + let serialized = to_vec(&orig).unwrap(); + assert_eq!(serialized.as_slice(), b"\"1234567890987654321\""); + let parsed: Int64 = from_slice(&serialized).unwrap(); + assert_eq!(parsed, orig); + } + + #[test] + fn int64_compare() { + let a = Int64::from(12345u32); + let b = Int64::from(23456u32); + + assert!(a < b); + assert!(b > a); + assert_eq!(a, Int64::from(12345u32)); + } + + #[test] + #[allow(clippy::op_ref)] + fn int64_math() { + let a = Int64::from(-12345i32); + let b = Int64::from(23456u32); + + // test + with owned and reference right hand side + assert_eq!(a + b, Int64::from(11111u32)); + assert_eq!(a + &b, Int64::from(11111u32)); + + // test - with owned and reference right hand side + assert_eq!(b - a, Int64::from(35801u32)); + assert_eq!(b - &a, Int64::from(35801u32)); + + // test += with owned and reference right hand side + let mut c = Int64::from(300000u32); + c += b; + assert_eq!(c, Int64::from(323456u32)); + let mut d = Int64::from(300000u32); + d += &b; + assert_eq!(d, Int64::from(323456u32)); + + // test -= with owned and reference right hand side + let mut c = Int64::from(300000u32); + c -= b; + assert_eq!(c, Int64::from(276544u32)); + let mut d = Int64::from(300000u32); + d -= &b; + assert_eq!(d, Int64::from(276544u32)); + + // test - with negative result + assert_eq!(a - b, Int64::from(-35801i32)); + } + + #[test] + #[should_panic] + fn int64_add_overflow_panics() { + let _ = Int64::MAX + Int64::from(12u32); + } + + #[test] + #[allow(clippy::op_ref)] + fn int64_sub_works() { + assert_eq!(Int64::from(2u32) - Int64::from(1u32), Int64::from(1u32)); + assert_eq!(Int64::from(2u32) - Int64::from(0u32), Int64::from(2u32)); + assert_eq!(Int64::from(2u32) - Int64::from(2u32), Int64::from(0u32)); + assert_eq!(Int64::from(2u32) - Int64::from(3u32), Int64::from(-1i32)); + + // works for refs + let a = Int64::from(10u32); + let b = Int64::from(3u32); + let expected = Int64::from(7u32); + assert_eq!(a - b, expected); + assert_eq!(a - &b, expected); + assert_eq!(&a - b, expected); + assert_eq!(&a - &b, expected); + } + + #[test] + #[should_panic] + fn int64_sub_overflow_panics() { + let _ = Int64::MIN + Int64::one() - Int64::from(2u32); + } + + #[test] + fn int64_sub_assign_works() { + let mut a = Int64::from(14u32); + a -= Int64::from(2u32); + assert_eq!(a, Int64::from(12u32)); + + // works for refs + let mut a = Int64::from(10u32); + let b = Int64::from(3u32); + let expected = Int64::from(7u32); + a -= &b; + assert_eq!(a, expected); + } + + #[test] + #[allow(clippy::op_ref)] + fn int64_mul_works() { + assert_eq!(Int64::from(2u32) * Int64::from(3u32), Int64::from(6u32)); + assert_eq!(Int64::from(2u32) * Int64::zero(), Int64::zero()); + + // works for refs + let a = Int64::from(11u32); + let b = Int64::from(3u32); + let expected = Int64::from(33u32); + assert_eq!(a * b, expected); + assert_eq!(a * &b, expected); + assert_eq!(&a * b, expected); + assert_eq!(&a * &b, expected); + } + + #[test] + fn int64_mul_assign_works() { + let mut a = Int64::from(14u32); + a *= Int64::from(2u32); + assert_eq!(a, Int64::from(28u32)); + + // works for refs + let mut a = Int64::from(10u32); + let b = Int64::from(3u32); + a *= &b; + assert_eq!(a, Int64::from(30u32)); + } + + #[test] + fn int64_pow_works() { + assert_eq!(Int64::from(2u32).pow(2), Int64::from(4u32)); + assert_eq!(Int64::from(2u32).pow(10), Int64::from(1024u32)); + } + + #[test] + #[should_panic] + fn int64_pow_overflow_panics() { + _ = Int64::MAX.pow(2u32); + } + + #[test] + fn int64_shr_works() { + let original = Int64::from_be_bytes([0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8]); + + let shifted = Int64::from_be_bytes([0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8]); + + assert_eq!(original >> 2u32, shifted); + } + + #[test] + #[should_panic] + fn int64_shr_overflow_panics() { + let _ = Int64::from(1u32) >> 64u32; + } + + #[test] + fn sum_works() { + let nums = vec![ + Int64::from(17u32), + Int64::from(123u32), + Int64::from(540u32), + Int64::from(82u32), + ]; + let expected = Int64::from(762u32); + + let sum_as_ref: Int64 = nums.iter().sum(); + assert_eq!(expected, sum_as_ref); + + let sum_as_owned: Int64 = nums.into_iter().sum(); + assert_eq!(expected, sum_as_owned); + } + + #[test] + fn int64_methods() { + // checked_* + assert!(matches!( + Int64::MAX.checked_add(Int64::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int64::from(1u32).checked_add(Int64::from(1u32)), + Ok(Int64::from(2u32)), + ); + assert!(matches!( + Int64::MIN.checked_sub(Int64::from(1u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int64::from(2u32).checked_sub(Int64::from(1u32)), + Ok(Int64::from(1u32)), + ); + assert!(matches!( + Int64::MAX.checked_mul(Int64::from(2u32)), + Err(OverflowError { .. }) + )); + assert_eq!( + Int64::from(2u32).checked_mul(Int64::from(2u32)), + Ok(Int64::from(4u32)), + ); + assert!(matches!( + Int64::MAX.checked_pow(2u32), + Err(OverflowError { .. }) + )); + assert_eq!(Int64::from(2u32).checked_pow(3u32), Ok(Int64::from(8u32)),); + assert_eq!( + Int64::MAX.checked_div(Int64::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int64::from(6u32).checked_div(Int64::from(2u32)), + Ok(Int64::from(3u32)), + ); + assert_eq!( + Int64::MAX.checked_div_euclid(Int64::from(0u32)), + Err(DivisionError::DivideByZero) + ); + assert_eq!( + Int64::from(6u32).checked_div_euclid(Int64::from(2u32)), + Ok(Int64::from(3u32)), + ); + assert_eq!( + Int64::from(7u32).checked_div_euclid(Int64::from(2u32)), + Ok(Int64::from(3u32)), + ); + assert!(matches!( + Int64::MAX.checked_rem(Int64::from(0u32)), + Err(DivideByZeroError { .. }) + )); + // checked_* with negative numbers + assert_eq!( + Int64::from(-12i32).checked_div(Int64::from(10i32)), + Ok(Int64::from(-1i32)), + ); + assert_eq!(Int64::from(-2i32).checked_pow(3u32), Ok(Int64::from(-8i32)),); + assert_eq!( + Int64::from(-6i32).checked_mul(Int64::from(-7i32)), + Ok(Int64::from(42i32)), + ); + assert_eq!( + Int64::from(-2i32).checked_add(Int64::from(3i32)), + Ok(Int64::from(1i32)), + ); + assert_eq!( + Int64::from(-1i32).checked_div_euclid(Int64::from(-2i32)), + Ok(Int64::from(1u32)), + ); + + // saturating_* + assert_eq!(Int64::MAX.saturating_add(Int64::from(1u32)), Int64::MAX); + assert_eq!(Int64::MIN.saturating_sub(Int64::from(1u32)), Int64::MIN); + assert_eq!(Int64::MAX.saturating_mul(Int64::from(2u32)), Int64::MAX); + assert_eq!(Int64::from(4u32).saturating_pow(2u32), Int64::from(16u32)); + assert_eq!(Int64::MAX.saturating_pow(2u32), Int64::MAX); + } + + #[test] + #[allow(clippy::op_ref)] + fn int64_implements_rem() { + let a = Int64::from(10u32); + assert_eq!(a % Int64::from(10u32), Int64::zero()); + assert_eq!(a % Int64::from(2u32), Int64::zero()); + assert_eq!(a % Int64::from(1u32), Int64::zero()); + assert_eq!(a % Int64::from(3u32), Int64::from(1u32)); + assert_eq!(a % Int64::from(4u32), Int64::from(2u32)); + + assert_eq!(Int64::from(-12i32) % Int64::from(10i32), Int64::from(-2i32)); + assert_eq!(Int64::from(12i32) % Int64::from(-10i32), Int64::from(2i32)); + assert_eq!( + Int64::from(-12i32) % Int64::from(-10i32), + Int64::from(-2i32) + ); + + // works for refs + let a = Int64::from(10u32); + let b = Int64::from(3u32); + let expected = Int64::from(1u32); + assert_eq!(a % b, expected); + assert_eq!(a % &b, expected); + assert_eq!(&a % b, expected); + assert_eq!(&a % &b, expected); + } + + #[test] + #[should_panic(expected = "divisor of zero")] + fn int64_rem_panics_for_zero() { + let _ = Int64::from(10u32) % Int64::zero(); + } + + #[test] + fn int64_rem_assign_works() { + let mut a = Int64::from(30u32); + a %= Int64::from(4u32); + assert_eq!(a, Int64::from(2u32)); + + // works for refs + let mut a = Int64::from(25u32); + let b = Int64::from(6u32); + a %= &b; + assert_eq!(a, Int64::from(1u32)); + } + + #[test] + fn int64_shr() { + let x: Int64 = 0x4000_0000_0000_0000i64.into(); + assert_eq!(x >> 0, x); // right shift by 0 should be no-op + assert_eq!(x >> 1, Int64::from(0x2000_0000_0000_0000i64)); + assert_eq!(x >> 4, Int64::from(0x0400_0000_0000_0000i64)); + // right shift of MIN value by the maximum shift value should result in -1 (filled with 1s) + assert_eq!( + Int64::MIN >> (core::mem::size_of::() as u32 * 8 - 1), + -Int64::one() + ); + } + + #[test] + fn int64_shl() { + let x: Int64 = 0x0800_0000_0000_0000i64.into(); + assert_eq!(x << 0, x); // left shift by 0 should be no-op + assert_eq!(x << 1, Int64::from(0x1000_0000_0000_0000i64)); + assert_eq!(x << 4, Int64::from(0x0800_0000_0000_0000i64 << 4)); + // left shift by by the maximum shift value should result in MIN + assert_eq!( + Int64::one() << (core::mem::size_of::() as u32 * 8 - 1), + Int64::MIN + ); + } + + #[test] + fn int64_abs_diff_works() { + let a = Int64::from(42u32); + let b = Int64::from(5u32); + let expected = Uint64::from(37u32); + assert_eq!(a.abs_diff(b), expected); + assert_eq!(b.abs_diff(a), expected); + + let c = Int64::from(-5i32); + assert_eq!(b.abs_diff(c), Uint64::from(10u32)); + assert_eq!(c.abs_diff(b), Uint64::from(10u32)); + } + + #[test] + #[should_panic = "attempt to negate with overflow"] + fn int64_neg_min_panics() { + _ = -Int64::MIN; + } + + #[test] + fn int64_partial_eq() { + let test_cases = [(1, 1, true), (42, 42, true), (42, 24, false), (0, 0, true)] + .into_iter() + .map(|(lhs, rhs, expected): (i64, i64, bool)| { + (Int64::from(lhs), Int64::from(rhs), expected) + }); + + #[allow(clippy::op_ref)] + for (lhs, rhs, expected) in test_cases { + assert_eq!(lhs == rhs, expected); + assert_eq!(&lhs == rhs, expected); + assert_eq!(lhs == &rhs, expected); + assert_eq!(&lhs == &rhs, expected); + } + } +} diff --git a/packages/std/src/math/isqrt.rs b/packages/std/src/math/isqrt.rs index 6bf4b01f6..6fd58c397 100644 --- a/packages/std/src/math/isqrt.rs +++ b/packages/std/src/math/isqrt.rs @@ -1,4 +1,4 @@ -use std::{cmp, ops}; +use core::{cmp, ops}; use crate::{Uint128, Uint256, Uint512, Uint64}; @@ -6,6 +6,7 @@ use crate::{Uint128, Uint256, Uint512, Uint64}; /// [integer square root](https://en.wikipedia.org/wiki/Integer_square_root). pub trait Isqrt { /// The [integer square root](https://en.wikipedia.org/wiki/Integer_square_root). + #[must_use = "this returns the result of the operation, without modifying the original"] fn isqrt(self) -> Self; } diff --git a/packages/std/src/math/mod.rs b/packages/std/src/math/mod.rs index 706d23005..a6cf8af3c 100644 --- a/packages/std/src/math/mod.rs +++ b/packages/std/src/math/mod.rs @@ -1,6 +1,10 @@ mod decimal; mod decimal256; mod fraction; +mod int128; +mod int256; +mod int512; +mod int64; mod isqrt; mod uint128; mod uint256; @@ -10,6 +14,10 @@ mod uint64; pub use decimal::{Decimal, DecimalRangeExceeded}; pub use decimal256::{Decimal256, Decimal256RangeExceeded}; pub use fraction::Fraction; +pub use int128::Int128; +pub use int256::Int256; +pub use int512::Int512; +pub use int64::Int64; pub use isqrt::Isqrt; pub use uint128::Uint128; pub use uint256::Uint256; @@ -19,9 +27,9 @@ pub use uint64::Uint64; #[cfg(test)] mod tests { use super::*; - use std::ops::*; + use core::ops::*; - /// An trait that ensures other traits are implemented for our number types + /// A trait that ensures other traits are implemented for our number types trait AllImpl<'a>: Add + Add<&'a Self> @@ -50,10 +58,46 @@ mod tests { { } + /// A trait that ensures other traits are implemented for our integer types + trait IntImpl<'a>: + AllImpl<'a> + + Shl + + Shl<&'a u32> + + ShlAssign + + ShlAssign<&'a u32> + + Shr + + Shr<&'a u32> + + ShrAssign + + ShrAssign<&'a u32> + + Not + { + } + + trait SignedImpl<'a>: IntImpl<'a> + Neg {} + impl AllImpl<'_> for Uint64 {} impl AllImpl<'_> for Uint128 {} impl AllImpl<'_> for Uint256 {} impl AllImpl<'_> for Uint512 {} + impl AllImpl<'_> for Int64 {} + impl AllImpl<'_> for Int128 {} + impl AllImpl<'_> for Int256 {} + impl AllImpl<'_> for Int512 {} + + impl IntImpl<'_> for Int64 {} + impl IntImpl<'_> for Int128 {} + impl IntImpl<'_> for Int256 {} + impl IntImpl<'_> for Int512 {} + impl IntImpl<'_> for Uint64 {} + impl IntImpl<'_> for Uint128 {} + impl IntImpl<'_> for Uint256 {} + impl IntImpl<'_> for Uint512 {} + impl AllImpl<'_> for Decimal {} impl AllImpl<'_> for Decimal256 {} + + impl SignedImpl<'_> for Int64 {} + impl SignedImpl<'_> for Int128 {} + impl SignedImpl<'_> for Int256 {} + impl SignedImpl<'_> for Int512 {} } diff --git a/packages/std/src/math/uint128.rs b/packages/std/src/math/uint128.rs index 34f7c7f2d..0aebf6b99 100644 --- a/packages/std/src/math/uint128.rs +++ b/packages/std/src/math/uint128.rs @@ -1,16 +1,22 @@ +use core::fmt::{self}; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, + Sub, SubAssign, +}; +use core::str::FromStr; +use std::ops::Not; + use forward_ref::{forward_ref_binop, forward_ref_op_assign}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; -use std::fmt::{self}; -use std::ops::{ - Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shr, ShrAssign, Sub, SubAssign, -}; -use std::str::FromStr; use crate::errors::{ - CheckedMultiplyRatioError, DivideByZeroError, OverflowError, OverflowOperation, StdError, + CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError, + OverflowOperation, StdError, +}; +use crate::{ + forward_ref_partial_eq, impl_mul_fraction, ConversionOverflowError, Fraction, Uint256, Uint64, }; -use crate::{ConversionOverflowError, Uint256, Uint64}; /// A thin wrapper around u128 that is using strings for JSON encoding/decoding, /// such that the full u128 range can be used for clients that convert JSON numbers to floats, @@ -32,7 +38,9 @@ use crate::{ConversionOverflowError, Uint256, Uint64}; /// assert_eq!(c.u128(), 70); /// ``` #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] -pub struct Uint128(#[schemars(with = "String")] u128); +pub struct Uint128(#[schemars(with = "String")] pub(crate) u128); + +forward_ref_partial_eq!(Uint128, Uint128); impl Uint128 { pub const MAX: Self = Self(u128::MAX); @@ -63,19 +71,23 @@ impl Uint128 { } /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_be_bytes(self) -> [u8; 16] { self.0.to_be_bytes() } /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_le_bytes(self) -> [u8; 16] { self.0.to_le_bytes() } + #[must_use] pub const fn is_zero(&self) -> bool { self.0 == 0 } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn pow(self, exp: u32) -> Self { self.0.pow(exp).into() } @@ -84,6 +96,7 @@ impl Uint128 { /// /// Due to the nature of the integer division involved, the result is always floored. /// E.g. 5 * 99/100 = 4. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn multiply_ratio, B: Into>( &self, numerator: A, @@ -130,6 +143,7 @@ impl Uint128 { /// let result = a.full_mul(2u32); /// assert_eq!(result.to_string(), "680564733841876926926749214863536422910"); /// ``` + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn full_mul(self, rhs: impl Into) -> Uint256 { Uint256::from(self.u128()) .checked_mul(Uint256::from(rhs.into())) @@ -185,46 +199,67 @@ impl Uint128 { .ok_or_else(|| DivideByZeroError::new(self)) } - #[must_use] + pub fn checked_shr(self, other: u32) -> Result { + if other >= 128 { + return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + } + + Ok(Self(self.0.shr(other))) + } + + pub fn checked_shl(self, other: u32) -> Result { + if other >= 128 { + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); + } + + Ok(Self(self.0.shl(other))) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_add(self, other: Self) -> Self { Self(self.0.wrapping_add(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_sub(self, other: Self) -> Self { Self(self.0.wrapping_sub(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_mul(self, other: Self) -> Self { Self(self.0.wrapping_mul(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_pow(self, other: u32) -> Self { Self(self.0.wrapping_pow(other)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_add(self, other: Self) -> Self { Self(self.0.saturating_add(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_sub(self, other: Self) -> Self { Self(self.0.saturating_sub(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_mul(self, other: Self) -> Self { Self(self.0.saturating_mul(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_pow(self, exp: u32) -> Self { Self(self.0.saturating_pow(exp)) } + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn abs_diff(self, other: Self) -> Self { Self(if self.0 < other.0 { other.0 - self.0 @@ -234,6 +269,8 @@ impl Uint128 { } } +impl_mul_fraction!(Uint128); + // `From` is implemented manually instead of // using `impl> From for Uint128` because // of the conflict with `TryFrom<&str>` as described here @@ -299,7 +336,7 @@ impl FromStr for Uint128 { fn from_str(s: &str) -> Result { match s.parse::() { Ok(u) => Ok(Uint128(u)), - Err(e) => Err(StdError::generic_err(format!("Parsing u128: {}", e))), + Err(e) => Err(StdError::generic_err(format!("Parsing u128: {e}"))), } } } @@ -422,6 +459,26 @@ impl<'a> Shr<&'a u32> for Uint128 { } } +impl Shl for Uint128 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + Self( + self.u128() + .checked_shl(rhs) + .expect("attempt to shift left with overflow"), + ) + } +} + +impl<'a> Shl<&'a u32> for Uint128 { + type Output = Self; + + fn shl(self, rhs: &'a u32) -> Self::Output { + self.shl(*rhs) + } +} + impl AddAssign for Uint128 { fn add_assign(&mut self, rhs: Uint128) { *self = *self + rhs; @@ -459,6 +516,14 @@ impl Rem for Uint128 { } forward_ref_binop!(impl Rem, rem for Uint128, Uint128); +impl Not for Uint128 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + impl RemAssign for Uint128 { fn rem_assign(&mut self, rhs: Uint128) { *self = *self % rhs; @@ -478,6 +543,18 @@ impl<'a> ShrAssign<&'a u32> for Uint128 { } } +impl ShlAssign for Uint128 { + fn shl_assign(&mut self, rhs: u32) { + *self = Shl::::shl(*self, rhs); + } +} + +impl<'a> ShlAssign<&'a u32> for Uint128 { + fn shl_assign(&mut self, rhs: &'a u32) { + *self = Shl::::shl(*self, *rhs); + } +} + impl Serialize for Uint128 { /// Serializes as an integer string using base 10 fn serialize(&self, serializer: S) -> Result @@ -513,12 +590,12 @@ impl<'de> de::Visitor<'de> for Uint128Visitor { { match v.parse::() { Ok(u) => Ok(Uint128(u)), - Err(e) => Err(E::custom(format!("invalid Uint128 '{}' - {}", v, e))), + Err(e) => Err(E::custom(format!("invalid Uint128 '{v}' - {e}"))), } } } -impl std::iter::Sum for Uint128 +impl core::iter::Sum for Uint128 where Self: Add, { @@ -527,22 +604,25 @@ where } } -impl PartialEq<&Uint128> for Uint128 { - fn eq(&self, rhs: &&Uint128) -> bool { - self == *rhs - } -} - -impl PartialEq for &Uint128 { - fn eq(&self, rhs: &Uint128) -> bool { - *self == rhs - } -} - #[cfg(test)] mod tests { + use crate::errors::CheckedMultiplyFractionError::{ConversionOverflow, DivideByZero}; + use crate::{from_slice, to_vec, Decimal}; + use super::*; - use crate::{from_slice, to_vec}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 16); + } + + #[test] + fn uint128_not_works() { + assert_eq!(!Uint128::new(1234806), Uint128::new(!1234806)); + + assert_eq!(!Uint128::MAX, Uint128::new(!u128::MAX)); + assert_eq!(!Uint128::MIN, Uint128::new(!u128::MIN)); + } #[test] fn uint128_zero_works() { @@ -600,18 +680,23 @@ mod tests { #[test] fn uint128_implements_display() { let a = Uint128(12345); - assert_eq!(format!("Embedded: {}", a), "Embedded: 12345"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); assert_eq!(a.to_string(), "12345"); let a = Uint128(0); - assert_eq!(format!("Embedded: {}", a), "Embedded: 0"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); assert_eq!(a.to_string(), "0"); } #[test] fn uint128_display_padding_works() { + // width > natural representation let a = Uint128::from(123u64); - assert_eq!(format!("Embedded: {:05}", a), "Embedded: 00123"); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + + // width < natural representation + let a = Uint128::from(123u64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); } #[test] @@ -814,7 +899,7 @@ mod tests { #[test] #[should_panic] fn uint128_pow_overflow_panics() { - Uint128::MAX.pow(2u32); + _ = Uint128::MAX.pow(2u32); } #[test] @@ -860,7 +945,7 @@ mod tests { #[test] #[should_panic(expected = "Denominator must not be zero")] fn uint128_multiply_ratio_panics_for_zero_denominator() { - Uint128(500).multiply_ratio(1u128, 0u128); + _ = Uint128(500).multiply_ratio(1u128, 0u128); } #[test] @@ -875,6 +960,44 @@ mod tests { ); } + #[test] + fn uint128_shr_works() { + let original = Uint128::new(u128::from_be_bytes([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8, + ])); + + let shifted = Uint128::new(u128::from_be_bytes([ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8, + ])); + + assert_eq!(original >> 2u32, shifted); + } + + #[test] + #[should_panic] + fn uint128_shr_overflow_panics() { + let _ = Uint128::from(1u32) >> 128u32; + } + + #[test] + fn uint128_shl_works() { + let original = Uint128::new(u128::from_be_bytes([ + 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ])); + + let shifted = Uint128::new(u128::from_be_bytes([ + 2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ])); + + assert_eq!(original << 2u32, shifted); + } + + #[test] + #[should_panic] + fn uint128_shl_overflow_panics() { + let _ = Uint128::from(1u32) << 128u32; + } + #[test] fn sum_works() { let nums = vec![Uint128(17), Uint128(123), Uint128(540), Uint128(82)]; @@ -1038,4 +1161,312 @@ mod tests { assert_eq!(&lhs == &rhs, expected); } } + + #[test] + fn mul_floor_works_with_zero() { + let fraction = (Uint128::zero(), Uint128::new(21)); + let res = Uint128::new(123456).mul_floor(fraction); + assert_eq!(Uint128::zero(), res) + } + + #[test] + fn mul_floor_does_nothing_with_one() { + let fraction = (Uint128::one(), Uint128::one()); + let res = Uint128::new(123456).mul_floor(fraction); + assert_eq!(Uint128::new(123456), res) + } + + #[test] + fn mul_floor_rounds_down_with_normal_case() { + let fraction = (8u128, 21u128); + let res = Uint128::new(123456).mul_floor(fraction); // 47030.8571 + assert_eq!(Uint128::new(47030), res) + } + + #[test] + fn mul_floor_does_not_round_on_even_divide() { + let fraction = (2u128, 5u128); + let res = Uint128::new(25).mul_floor(fraction); + assert_eq!(Uint128::new(10), res) + } + + #[test] + fn mul_floor_works_when_operation_temporarily_takes_above_max() { + let fraction = (8u128, 21u128); + let res = Uint128::MAX.mul_floor(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.14285 + assert_eq!( + Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_697), + res + ) + } + + #[test] + fn mul_floor_works_with_decimal() { + let decimal = Decimal::from_ratio(8u128, 21u128); + let res = Uint128::new(123456).mul_floor(decimal); // 47030.8571 + assert_eq!(Uint128::new(47030), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn mul_floor_panics_on_overflow() { + let fraction = (21u128, 8u128); + _ = Uint128::MAX.mul_floor(fraction); + } + + #[test] + fn checked_mul_floor_does_not_panic_on_overflow() { + let fraction = (21u128, 8u128); + assert_eq!( + Uint128::MAX.checked_mul_floor(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint256", + target_type: "Uint128", + value: "893241213167463466591358344508391555069".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn mul_floor_panics_on_zero_div() { + let fraction = (21u128, 0u128); + _ = Uint128::new(123456).mul_floor(fraction); + } + + #[test] + fn checked_mul_floor_does_not_panic_on_zero_div() { + let fraction = (21u128, 0u128); + assert_eq!( + Uint128::new(123456).checked_mul_floor(fraction), + Err(DivideByZero(DivideByZeroError { + operand: "2592576".to_string() + })), + ); + } + + #[test] + fn mul_ceil_works_with_zero() { + let fraction = (Uint128::zero(), Uint128::new(21)); + let res = Uint128::new(123456).mul_ceil(fraction); + assert_eq!(Uint128::zero(), res) + } + + #[test] + fn mul_ceil_does_nothing_with_one() { + let fraction = (Uint128::one(), Uint128::one()); + let res = Uint128::new(123456).mul_ceil(fraction); + assert_eq!(Uint128::new(123456), res) + } + + #[test] + fn mul_ceil_rounds_up_with_normal_case() { + let fraction = (8u128, 21u128); + let res = Uint128::new(123456).mul_ceil(fraction); // 47030.8571 + assert_eq!(Uint128::new(47031), res) + } + + #[test] + fn mul_ceil_does_not_round_on_even_divide() { + let fraction = (2u128, 5u128); + let res = Uint128::new(25).mul_ceil(fraction); + assert_eq!(Uint128::new(10), res) + } + + #[test] + fn mul_ceil_works_when_operation_temporarily_takes_above_max() { + let fraction = (8u128, 21u128); + let res = Uint128::MAX.mul_ceil(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.14285 + assert_eq!( + Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_698), + res + ) + } + + #[test] + fn mul_ceil_works_with_decimal() { + let decimal = Decimal::from_ratio(8u128, 21u128); + let res = Uint128::new(123456).mul_ceil(decimal); // 47030.8571 + assert_eq!(Uint128::new(47031), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn mul_ceil_panics_on_overflow() { + let fraction = (21u128, 8u128); + _ = Uint128::MAX.mul_ceil(fraction); + } + + #[test] + fn checked_mul_ceil_does_not_panic_on_overflow() { + let fraction = (21u128, 8u128); + assert_eq!( + Uint128::MAX.checked_mul_ceil(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint256", + target_type: "Uint128", + value: "893241213167463466591358344508391555069".to_string() // raises prior to rounding up + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn mul_ceil_panics_on_zero_div() { + let fraction = (21u128, 0u128); + _ = Uint128::new(123456).mul_ceil(fraction); + } + + #[test] + fn checked_mul_ceil_does_not_panic_on_zero_div() { + let fraction = (21u128, 0u128); + assert_eq!( + Uint128::new(123456).checked_mul_ceil(fraction), + Err(DivideByZero(DivideByZeroError { + operand: "2592576".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn div_floor_raises_with_zero() { + let fraction = (Uint128::zero(), Uint128::new(21)); + _ = Uint128::new(123456).div_floor(fraction); + } + + #[test] + fn div_floor_does_nothing_with_one() { + let fraction = (Uint128::one(), Uint128::one()); + let res = Uint128::new(123456).div_floor(fraction); + assert_eq!(Uint128::new(123456), res) + } + + #[test] + fn div_floor_rounds_down_with_normal_case() { + let fraction = (5u128, 21u128); + let res = Uint128::new(123456).div_floor(fraction); // 518515.2 + assert_eq!(Uint128::new(518515), res) + } + + #[test] + fn div_floor_does_not_round_on_even_divide() { + let fraction = (5u128, 2u128); + let res = Uint128::new(25).div_floor(fraction); + assert_eq!(Uint128::new(10), res) + } + + #[test] + fn div_floor_works_when_operation_temporarily_takes_above_max() { + let fraction = (21u128, 8u128); + let res = Uint128::MAX.div_floor(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.1428 + assert_eq!( + Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_697), + res + ) + } + + #[test] + fn div_floor_works_with_decimal() { + let decimal = Decimal::from_ratio(21u128, 8u128); + let res = Uint128::new(123456).div_floor(decimal); // 47030.8571 + assert_eq!(Uint128::new(47030), res) + } + + #[test] + fn div_floor_works_with_decimal_evenly() { + let res = Uint128::new(60).div_floor(Decimal::from_atomics(6u128, 0).unwrap()); + assert_eq!(res, Uint128::new(10)); + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn div_floor_panics_on_overflow() { + let fraction = (8u128, 21u128); + _ = Uint128::MAX.div_floor(fraction); + } + + #[test] + fn div_floor_does_not_panic_on_overflow() { + let fraction = (8u128, 21u128); + assert_eq!( + Uint128::MAX.checked_div_floor(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint256", + target_type: "Uint128", + value: "893241213167463466591358344508391555069".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn div_ceil_raises_with_zero() { + let fraction = (Uint128::zero(), Uint128::new(21)); + _ = Uint128::new(123456).div_ceil(fraction); + } + + #[test] + fn div_ceil_does_nothing_with_one() { + let fraction = (Uint128::one(), Uint128::one()); + let res = Uint128::new(123456).div_ceil(fraction); + assert_eq!(Uint128::new(123456), res) + } + + #[test] + fn div_ceil_rounds_up_with_normal_case() { + let fraction = (5u128, 21u128); + let res = Uint128::new(123456).div_ceil(fraction); // 518515.2 + assert_eq!(Uint128::new(518516), res) + } + + #[test] + fn div_ceil_does_not_round_on_even_divide() { + let fraction = (5u128, 2u128); + let res = Uint128::new(25).div_ceil(fraction); + assert_eq!(Uint128::new(10), res) + } + + #[test] + fn div_ceil_works_when_operation_temporarily_takes_above_max() { + let fraction = (21u128, 8u128); + let res = Uint128::MAX.div_ceil(fraction); // 129_631_377_874_643_224_176_523_659_974_006_937_697.1428 + assert_eq!( + Uint128::new(129_631_377_874_643_224_176_523_659_974_006_937_698), + res + ) + } + + #[test] + fn div_ceil_works_with_decimal() { + let decimal = Decimal::from_ratio(21u128, 8u128); + let res = Uint128::new(123456).div_ceil(decimal); // 47030.8571 + assert_eq!(Uint128::new(47031), res) + } + + #[test] + fn div_ceil_works_with_decimal_evenly() { + let res = Uint128::new(60).div_ceil(Decimal::from_atomics(6u128, 0).unwrap()); + assert_eq!(res, Uint128::new(10)); + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn div_ceil_panics_on_overflow() { + let fraction = (8u128, 21u128); + _ = Uint128::MAX.div_ceil(fraction); + } + + #[test] + fn div_ceil_does_not_panic_on_overflow() { + let fraction = (8u128, 21u128); + assert_eq!( + Uint128::MAX.checked_div_ceil(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint256", + target_type: "Uint128", + value: "893241213167463466591358344508391555069".to_string() + })), + ); + } } diff --git a/packages/std/src/math/uint256.rs b/packages/std/src/math/uint256.rs index fb83c308b..6422dee76 100644 --- a/packages/std/src/math/uint256.rs +++ b/packages/std/src/math/uint256.rs @@ -1,31 +1,23 @@ +use core::fmt; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, + Sub, SubAssign, +}; +use core::str::FromStr; use forward_ref::{forward_ref_binop, forward_ref_op_assign}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; -use std::fmt; -use std::ops::{ - Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, Shr, ShrAssign, Sub, - SubAssign, -}; -use std::str::FromStr; +use std::ops::Not; use crate::errors::{ - CheckedMultiplyRatioError, ConversionOverflowError, DivideByZeroError, OverflowError, - OverflowOperation, StdError, + CheckedMultiplyFractionError, CheckedMultiplyRatioError, ConversionOverflowError, + DivideByZeroError, OverflowError, OverflowOperation, StdError, }; -use crate::{Uint128, Uint512, Uint64}; - -/// This module is purely a workaround that lets us ignore lints for all the code -/// the `construct_uint!` macro generates. -#[allow(clippy::all)] -mod uints { - uint::construct_uint! { - pub struct U256(4); - } -} +use crate::{forward_ref_partial_eq, impl_mul_fraction, Fraction, Uint128, Uint512, Uint64}; /// Used internally - we don't want to leak this type since we might change /// the implementation in the future. -use uints::U256; +use bnum::types::U256; /// An implementation of u256 that is using strings for JSON encoding/decoding, /// such that the full u256 range can be used for clients that convert JSON numbers to floats, @@ -48,11 +40,13 @@ use uints::U256; /// assert_eq!(a, b); /// ``` #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] -pub struct Uint256(#[schemars(with = "String")] U256); +pub struct Uint256(#[schemars(with = "String")] pub(crate) U256); + +forward_ref_partial_eq!(Uint256, Uint256); impl Uint256 { pub const MAX: Uint256 = Uint256(U256::MAX); - pub const MIN: Uint256 = Uint256(U256::zero()); + pub const MIN: Uint256 = Uint256(U256::ZERO); /// Creates a Uint256(value) from a big endian representation. It's just an alias for /// [`Uint256::from_be_bytes`]. @@ -65,18 +59,16 @@ impl Uint256 { /// Creates a Uint256(0) #[inline] pub const fn zero() -> Self { - Uint256(U256::zero()) + Self(U256::ZERO) } /// Creates a Uint256(1) #[inline] pub const fn one() -> Self { - Self::from_be_bytes([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, - ]) + Self(U256::ONE) } + #[must_use] pub const fn from_be_bytes(data: [u8; 32]) -> Self { let words: [u64; 4] = [ u64::from_le_bytes([ @@ -92,9 +84,10 @@ impl Uint256 { data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0], ]), ]; - Self(U256(words)) + Self(U256::from_digits(words)) } + #[must_use] pub const fn from_le_bytes(data: [u8; 32]) -> Self { let words: [u64; 4] = [ u64::from_le_bytes([ @@ -110,11 +103,12 @@ impl Uint256 { data[24], data[25], data[26], data[27], data[28], data[29], data[30], data[31], ]), ]; - Uint256(U256(words)) + Self(U256::from_digits(words)) } /// A conversion from `u128` that, unlike the one provided by the `From` trait, /// can be used in a `const` context. + #[must_use] pub const fn from_u128(num: u128) -> Self { let bytes = num.to_le_bytes(); @@ -127,46 +121,52 @@ impl Uint256 { /// A conversion from `Uint128` that, unlike the one provided by the `From` trait, /// can be used in a `const` context. + #[must_use] pub const fn from_uint128(num: Uint128) -> Self { Self::from_u128(num.u128()) } /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_be_bytes(self) -> [u8; 32] { + let words = self.0.digits(); let words = [ - (self.0).0[3].to_be_bytes(), - (self.0).0[2].to_be_bytes(), - (self.0).0[1].to_be_bytes(), - (self.0).0[0].to_be_bytes(), + words[3].to_be_bytes(), + words[2].to_be_bytes(), + words[1].to_be_bytes(), + words[0].to_be_bytes(), ]; - unsafe { std::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) } + unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) } } /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_le_bytes(self) -> [u8; 32] { + let words = self.0.digits(); let words = [ - (self.0).0[0].to_le_bytes(), - (self.0).0[1].to_le_bytes(), - (self.0).0[2].to_le_bytes(), - (self.0).0[3].to_le_bytes(), + words[0].to_le_bytes(), + words[1].to_le_bytes(), + words[2].to_le_bytes(), + words[3].to_le_bytes(), ]; - unsafe { std::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) } + unsafe { core::mem::transmute::<[[u8; 8]; 4], [u8; 32]>(words) } } + #[must_use] pub const fn is_zero(&self) -> bool { - let words = (self.0).0; - words[0] == 0 && words[1] == 0 && words[2] == 0 && words[3] == 0 + self.0.is_zero() } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn pow(self, exp: u32) -> Self { - let res = self.0.pow(exp.into()); - Self(res) + Self(self.0.pow(exp)) } /// Returns `self * numerator / denominator`. /// /// Due to the nature of the integer division involved, the result is always floored. /// E.g. 5 * 99/100 = 4. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn multiply_ratio, B: Into>( &self, numerator: A, @@ -216,6 +216,7 @@ impl Uint256 { /// "231584178474632390847141970017375815706539969331281128078915168015826259279870", /// ); /// ``` + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn full_mul(self, rhs: impl Into) -> Uint512 { Uint512::from(self) .checked_mul(Uint512::from(rhs.into())) @@ -245,7 +246,7 @@ impl Uint256 { pub fn checked_pow(self, exp: u32) -> Result { self.0 - .checked_pow(exp.into()) + .checked_pow(exp) .map(Self) .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp)) } @@ -284,61 +285,58 @@ impl Uint256 { Ok(Self(self.0.shl(other))) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_add(self, other: Self) -> Self { - let (value, _did_overflow) = self.0.overflowing_add(other.0); - Self(value) + Self(self.0.wrapping_add(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_sub(self, other: Self) -> Self { - let (value, _did_overflow) = self.0.overflowing_sub(other.0); - Self(value) + Self(self.0.wrapping_sub(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_mul(self, other: Self) -> Self { - let (value, _did_overflow) = self.0.overflowing_mul(other.0); - Self(value) + Self(self.0.wrapping_mul(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_pow(self, other: u32) -> Self { - let (value, _did_overflow) = self.0.overflowing_pow(other.into()); - Self(value) + Self(self.0.wrapping_pow(other)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_add(self, other: Self) -> Self { Self(self.0.saturating_add(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_sub(self, other: Self) -> Self { Self(self.0.saturating_sub(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_mul(self, other: Self) -> Self { Self(self.0.saturating_mul(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_pow(self, exp: u32) -> Self { - match self.checked_pow(exp) { - Ok(value) => value, - Err(_) => Self::MAX, - } + Self(self.0.saturating_pow(exp)) } - pub fn abs_diff(self, other: Self) -> Self { - if self < other { - other - self - } else { - self - other - } + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs_diff(self, other: Self) -> Self { + Self(self.0.abs_diff(other.0)) } } +impl_mul_fraction!(Uint256); + impl From for Uint256 { fn from(val: Uint128) -> Self { val.u128().into() @@ -407,9 +405,9 @@ impl FromStr for Uint256 { return Err(StdError::generic_err("Parsing u256: received empty string")); } - match U256::from_dec_str(s) { + match U256::from_str_radix(s, 10) { Ok(u) => Ok(Uint256(u)), - Err(e) => Err(StdError::generic_err(format!("Parsing u256: {}", e))), + Err(e) => Err(StdError::generic_err(format!("Parsing u256: {e}"))), } } } @@ -422,11 +420,7 @@ impl From for String { impl fmt::Display for Uint256 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // The inner type doesn't work as expected with padding, so we - // work around that. - let unpadded = self.0.to_string(); - - f.pad_integral(true, "", &unpadded) + self.0.fmt(f) } } @@ -503,6 +497,14 @@ impl Rem for Uint256 { } forward_ref_binop!(impl Rem, rem for Uint256, Uint256); +impl Not for Uint256 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + impl RemAssign for Uint256 { fn rem_assign(&mut self, rhs: Uint256) { *self = *self % rhs; @@ -536,8 +538,7 @@ impl Shr for Uint256 { fn shr(self, rhs: u32) -> Self::Output { self.checked_shr(rhs).unwrap_or_else(|_| { panic!( - "right shift error: {} is larger or equal than the number of bits in Uint256", - rhs, + "right shift error: {rhs} is larger or equal than the number of bits in Uint256", ) }) } @@ -555,12 +556,8 @@ impl Shl for Uint256 { type Output = Self; fn shl(self, rhs: u32) -> Self::Output { - self.checked_shl(rhs).unwrap_or_else(|_| { - panic!( - "left shift error: {} is larger or equal than the number of bits in Uint256", - rhs, - ) - }) + self.checked_shl(rhs) + .expect("attempt to shift left with overflow") } } @@ -608,6 +605,18 @@ impl<'a> ShrAssign<&'a u32> for Uint256 { } } +impl ShlAssign for Uint256 { + fn shl_assign(&mut self, rhs: u32) { + *self = self.shl(rhs); + } +} + +impl<'a> ShlAssign<&'a u32> for Uint256 { + fn shl_assign(&mut self, rhs: &'a u32) { + *self = self.shl(*rhs); + } +} + impl Serialize for Uint256 { /// Serializes as an integer string using base 10 fn serialize(&self, serializer: S) -> Result @@ -641,11 +650,11 @@ impl<'de> de::Visitor<'de> for Uint256Visitor { where E: de::Error, { - Uint256::try_from(v).map_err(|e| E::custom(format!("invalid Uint256 '{}' - {}", v, e))) + Uint256::try_from(v).map_err(|e| E::custom(format!("invalid Uint256 '{v}' - {e}"))) } } -impl std::iter::Sum for Uint256 +impl core::iter::Sum for Uint256 where Self: Add, { @@ -654,22 +663,16 @@ where } } -impl PartialEq<&Uint256> for Uint256 { - fn eq(&self, rhs: &&Uint256) -> bool { - self == *rhs - } -} - -impl PartialEq for &Uint256 { - fn eq(&self, rhs: &Uint256) -> bool { - *self == rhs - } -} - #[cfg(test)] mod tests { use super::*; - use crate::{from_slice, to_vec}; + use crate::errors::CheckedMultiplyFractionError::{ConversionOverflow, DivideByZero}; + use crate::{from_slice, to_vec, Decimal, Decimal256}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 32); + } #[test] fn uint256_new_works() { @@ -686,6 +689,16 @@ mod tests { assert_eq!(be_bytes, resulting_bytes); } + #[test] + fn uint256_not_works() { + let num = Uint256::new([1; 32]); + let a = (!num).to_be_bytes(); + assert_eq!(a, [254; 32]); + + assert_eq!(!Uint256::MAX, Uint256::MIN); + assert_eq!(!Uint256::MIN, Uint256::MAX); + } + #[test] fn uint256_zero_works() { let zero = Uint256::zero(); @@ -1025,22 +1038,25 @@ mod tests { #[test] fn uint256_convert_from() { let a = Uint256::from(5u128); - assert_eq!(a.0, U256::from(5)); + assert_eq!(a.0, U256::from(5u32)); let a = Uint256::from(5u64); - assert_eq!(a.0, U256::from(5)); + assert_eq!(a.0, U256::from(5u32)); let a = Uint256::from(5u32); - assert_eq!(a.0, U256::from(5)); + assert_eq!(a.0, U256::from(5u32)); let a = Uint256::from(5u16); - assert_eq!(a.0, U256::from(5)); + assert_eq!(a.0, U256::from(5u32)); let a = Uint256::from(5u8); - assert_eq!(a.0, U256::from(5)); + assert_eq!(a.0, U256::from(5u32)); let result = Uint256::try_from("34567"); - assert_eq!(result.unwrap().0, U256::from_dec_str("34567").unwrap()); + assert_eq!( + result.unwrap().0, + U256::from_str_radix("34567", 10).unwrap() + ); let result = Uint256::try_from("1.23"); assert!(result.is_err()); @@ -1093,18 +1109,23 @@ mod tests { #[test] fn uint256_implements_display() { let a = Uint256::from(12345u32); - assert_eq!(format!("Embedded: {}", a), "Embedded: 12345"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); assert_eq!(a.to_string(), "12345"); let a = Uint256::zero(); - assert_eq!(format!("Embedded: {}", a), "Embedded: 0"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); assert_eq!(a.to_string(), "0"); } #[test] fn uint256_display_padding_works() { + // width > natural representation + let a = Uint256::from(123u64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + + // width < natural representation let a = Uint256::from(123u64); - assert_eq!(format!("Embedded: {:05}", a), "Embedded: 00123"); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); } #[test] @@ -1200,7 +1221,7 @@ mod tests { #[test] fn uint256_is_zero_works() { assert!(Uint256::zero().is_zero()); - assert!(Uint256(U256::from(0)).is_zero()); + assert!(Uint256(U256::from(0u32)).is_zero()); assert!(!Uint256::from(1u32).is_zero()); assert!(!Uint256::from(123u32).is_zero()); @@ -1394,7 +1415,7 @@ mod tests { #[test] #[should_panic] fn uint256_pow_overflow_panics() { - Uint256::MAX.pow(2u32); + _ = Uint256::MAX.pow(2u32); } #[test] @@ -1446,7 +1467,7 @@ mod tests { #[test] #[should_panic(expected = "Denominator must not be zero")] fn uint256_multiply_ratio_panics_for_zero_denominator() { - Uint256::from(500u32).multiply_ratio(1u128, 0u128); + _ = Uint256::from(500u32).multiply_ratio(1u128, 0u128); } #[test] @@ -1482,6 +1503,27 @@ mod tests { let _ = Uint256::from(1u32) >> 256u32; } + #[test] + fn uint256_shl_works() { + let original = Uint256::new([ + 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]); + + let shifted = Uint256::new([ + 2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]); + + assert_eq!(original << 2u32, shifted); + } + + #[test] + #[should_panic] + fn uint256_shl_overflow_panics() { + let _ = Uint256::from(1u32) << 256u32; + } + #[test] fn sum_works() { let nums = vec![ @@ -1600,7 +1642,7 @@ mod tests { } #[test] - #[should_panic(expected = "division by zero")] + #[should_panic(expected = "divisor of zero")] fn uint256_rem_panics_for_zero() { let _ = Uint256::from(10u32) % Uint256::zero(); } @@ -1662,4 +1704,346 @@ mod tests { assert_eq!(&lhs == &rhs, expected); } } + + #[test] + fn mul_floor_works_with_zero() { + let fraction = (Uint256::zero(), Uint256::from(21u32)); + let res = Uint256::from(123456u32).mul_floor(fraction); + assert_eq!(Uint256::zero(), res) + } + + #[test] + fn mul_floor_does_nothing_with_one() { + let fraction = (Uint256::one(), Uint256::one()); + let res = Uint256::from(123456u32).mul_floor(fraction); + assert_eq!(Uint256::from(123456u32), res) + } + + #[test] + fn mul_floor_rounds_down_with_normal_case() { + let fraction = (Uint256::from(8u128), Uint256::from(21u128)); + let res = Uint256::from(123456u32).mul_floor(fraction); // 47030.8571 + assert_eq!(Uint256::from(47030u32), res) + } + + #[test] + fn mul_floor_does_not_round_on_even_divide() { + let fraction = (2u128, 5u128); + let res = Uint256::from(25u32).mul_floor(fraction); + assert_eq!(Uint256::from(10u32), res) + } + + #[test] + fn mul_floor_works_when_operation_temporarily_takes_above_max() { + let fraction = (8u128, 21u128); + let res = Uint256::MAX.mul_floor(fraction); // 44_111_272_090_406_169_685_169_899_050_928_726_801_245_708_444_053_548_205_507_651_050_633_573_196_165.71428571 + assert_eq!( + Uint256::from_str( + "44111272090406169685169899050928726801245708444053548205507651050633573196165" + ) + .unwrap(), + res + ) + } + + #[test] + fn mul_floor_works_with_decimal() { + let decimal = Decimal::from_ratio(8u128, 21u128); + let res = Uint256::from(123456u32).mul_floor(decimal); // 47030.8571 + assert_eq!(Uint256::from(47030u32), res) + } + + #[test] + fn mul_floor_works_with_decimal256() { + let decimal = Decimal256::from_ratio(8u128, 21u128); + let res = Uint256::from(123456u32).mul_floor(decimal); // 47030.8571 + assert_eq!(Uint256::from(47030u32), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn mul_floor_panics_on_overflow() { + let fraction = (21u128, 8u128); + _ = Uint256::MAX.mul_floor(fraction); + } + + #[test] + fn checked_mul_floor_does_not_panic_on_overflow() { + let fraction = (21u128, 8u128); + assert_eq!( + Uint256::MAX.checked_mul_floor(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint512", + target_type: "Uint256", + value: + "303954234247955012986873835647805758114833709747306480603576158020771965304829" + .to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn mul_floor_panics_on_zero_div() { + let fraction = (21u128, 0u128); + _ = Uint256::from(123456u32).mul_floor(fraction); + } + + #[test] + fn checked_mul_floor_does_not_panic_on_zero_div() { + let fraction = (21u128, 0u128); + assert_eq!( + Uint256::from(123456u32).checked_mul_floor(fraction), + Err(DivideByZero(DivideByZeroError { + operand: "2592576".to_string() + })), + ); + } + + #[test] + fn mul_ceil_works_with_zero() { + let fraction = (Uint256::zero(), Uint256::from(21u32)); + let res = Uint256::from(123456u32).mul_ceil(fraction); + assert_eq!(Uint256::zero(), res) + } + + #[test] + fn mul_ceil_does_nothing_with_one() { + let fraction = (Uint256::one(), Uint256::one()); + let res = Uint256::from(123456u32).mul_ceil(fraction); + assert_eq!(Uint256::from(123456u32), res) + } + + #[test] + fn mul_ceil_rounds_up_with_normal_case() { + let fraction = (8u128, 21u128); + let res = Uint256::from(123456u32).mul_ceil(fraction); // 47030.8571 + assert_eq!(Uint256::from(47031u32), res) + } + + #[test] + fn mul_ceil_does_not_round_on_even_divide() { + let fraction = (2u128, 5u128); + let res = Uint256::from(25u32).mul_ceil(fraction); + assert_eq!(Uint256::from(10u32), res) + } + + #[test] + fn mul_ceil_works_when_operation_temporarily_takes_above_max() { + let fraction = (8u128, 21u128); + let res = Uint256::MAX.mul_ceil(fraction); // 44_111_272_090_406_169_685_169_899_050_928_726_801_245_708_444_053_548_205_507_651_050_633_573_196_165.71428571 + assert_eq!( + Uint256::from_str( + "44111272090406169685169899050928726801245708444053548205507651050633573196166" + ) + .unwrap(), + res + ) + } + + #[test] + fn mul_ceil_works_with_decimal() { + let decimal = Decimal::from_ratio(8u128, 21u128); + let res = Uint256::from(123456u32).mul_ceil(decimal); // 47030.8571 + assert_eq!(Uint256::from(47031u32), res) + } + + #[test] + fn mul_ceil_works_with_decimal256() { + let decimal = Decimal256::from_ratio(8u128, 21u128); + let res = Uint256::from(123456u32).mul_ceil(decimal); // 47030.8571 + assert_eq!(Uint256::from(47031u32), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn mul_ceil_panics_on_overflow() { + let fraction = (21u128, 8u128); + _ = Uint256::MAX.mul_ceil(fraction); + } + + #[test] + fn checked_mul_ceil_does_not_panic_on_overflow() { + let fraction = (21u128, 8u128); + assert_eq!( + Uint256::MAX.checked_mul_ceil(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint512", + target_type: "Uint256", + value: + "303954234247955012986873835647805758114833709747306480603576158020771965304829" // raises prior to rounding up + .to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn mul_ceil_panics_on_zero_div() { + let fraction = (21u128, 0u128); + _ = Uint256::from(123456u32).mul_ceil(fraction); + } + + #[test] + fn checked_mul_ceil_does_not_panic_on_zero_div() { + let fraction = (21u128, 0u128); + assert_eq!( + Uint256::from(123456u32).checked_mul_ceil(fraction), + Err(DivideByZero(DivideByZeroError { + operand: "2592576".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn div_floor_raises_with_zero() { + let fraction = (Uint256::zero(), Uint256::from(21u32)); + _ = Uint256::from(123456u128).div_floor(fraction); + } + + #[test] + fn div_floor_does_nothing_with_one() { + let fraction = (Uint256::one(), Uint256::one()); + let res = Uint256::from(123456u128).div_floor(fraction); + assert_eq!(Uint256::from(123456u128), res) + } + + #[test] + fn div_floor_rounds_down_with_normal_case() { + let fraction = (5u128, 21u128); + let res = Uint256::from(123456u128).div_floor(fraction); // 518515.2 + assert_eq!(Uint256::from(518515u128), res) + } + + #[test] + fn div_floor_does_not_round_on_even_divide() { + let fraction = (5u128, 2u128); + let res = Uint256::from(25u128).div_floor(fraction); + assert_eq!(Uint256::from(10u128), res) + } + + #[test] + fn div_floor_works_when_operation_temporarily_takes_above_max() { + let fraction = (21u128, 8u128); + let res = Uint256::MAX.div_floor(fraction); // 44_111_272_090_406_169_685_169_899_050_928_726_801_245_708_444_053_548_205_507_651_050_633_573_196_165.71428571 + assert_eq!( + Uint256::from_str( + "44111272090406169685169899050928726801245708444053548205507651050633573196165" + ) + .unwrap(), + res + ) + } + + #[test] + fn div_floor_works_with_decimal() { + let decimal = Decimal::from_ratio(21u128, 8u128); + let res = Uint256::from(123456u128).div_floor(decimal); // 47030.8571 + assert_eq!(Uint256::from(47030u128), res) + } + + #[test] + fn div_floor_works_with_decimal_evenly() { + let res = Uint256::from(60u128).div_floor(Decimal::from_atomics(6u128, 0).unwrap()); + assert_eq!(res, Uint256::from(10u128)); + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn div_floor_panics_on_overflow() { + let fraction = (8u128, 21u128); + _ = Uint256::MAX.div_floor(fraction); + } + + #[test] + fn div_floor_does_not_panic_on_overflow() { + let fraction = (8u128, 21u128); + assert_eq!( + Uint256::MAX.checked_div_floor(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint512", + target_type: "Uint256", + value: + "303954234247955012986873835647805758114833709747306480603576158020771965304829" + .to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn div_ceil_raises_with_zero() { + let fraction = (Uint256::zero(), Uint256::from(21u128)); + _ = Uint256::from(123456u128).div_ceil(fraction); + } + + #[test] + fn div_ceil_does_nothing_with_one() { + let fraction = (Uint256::one(), Uint256::one()); + let res = Uint256::from(123456u128).div_ceil(fraction); + assert_eq!(Uint256::from(123456u128), res) + } + + #[test] + fn div_ceil_rounds_up_with_normal_case() { + let fraction = (5u128, 21u128); + let res = Uint256::from(123456u128).div_ceil(fraction); // 518515.2 + assert_eq!(Uint256::from(518516u128), res) + } + + #[test] + fn div_ceil_does_not_round_on_even_divide() { + let fraction = (5u128, 2u128); + let res = Uint256::from(25u128).div_ceil(fraction); + assert_eq!(Uint256::from(10u128), res) + } + + #[test] + fn div_ceil_works_when_operation_temporarily_takes_above_max() { + let fraction = (21u128, 8u128); + let res = Uint256::MAX.div_ceil(fraction); // 44_111_272_090_406_169_685_169_899_050_928_726_801_245_708_444_053_548_205_507_651_050_633_573_196_165.71428571 + assert_eq!( + Uint256::from_str( + "44111272090406169685169899050928726801245708444053548205507651050633573196166" + ) + .unwrap(), + res + ) + } + + #[test] + fn div_ceil_works_with_decimal() { + let decimal = Decimal::from_ratio(21u128, 8u128); + let res = Uint256::from(123456u128).div_ceil(decimal); // 47030.8571 + assert_eq!(Uint256::from(47031u128), res) + } + + #[test] + fn div_ceil_works_with_decimal_evenly() { + let res = Uint256::from(60u128).div_ceil(Decimal::from_atomics(6u128, 0).unwrap()); + assert_eq!(res, Uint256::from(10u128)); + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn div_ceil_panics_on_overflow() { + let fraction = (8u128, 21u128); + _ = Uint256::MAX.div_ceil(fraction); + } + + #[test] + fn div_ceil_does_not_panic_on_overflow() { + let fraction = (8u128, 21u128); + assert_eq!( + Uint256::MAX.checked_div_ceil(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint512", + target_type: "Uint256", + value: + "303954234247955012986873835647805758114833709747306480603576158020771965304829" + .to_string() // raises prior to rounding up + })), + ); + } } diff --git a/packages/std/src/math/uint512.rs b/packages/std/src/math/uint512.rs index 515029c5d..c4dd9e3f5 100644 --- a/packages/std/src/math/uint512.rs +++ b/packages/std/src/math/uint512.rs @@ -1,29 +1,21 @@ +use core::fmt; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Not, Rem, RemAssign, Shl, ShlAssign, Shr, + ShrAssign, Sub, SubAssign, +}; +use core::str::FromStr; use forward_ref::{forward_ref_binop, forward_ref_op_assign}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; -use std::fmt; -use std::ops::{ - Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shr, ShrAssign, Sub, SubAssign, -}; -use std::str::FromStr; use crate::errors::{ ConversionOverflowError, DivideByZeroError, OverflowError, OverflowOperation, StdError, }; -use crate::{Uint128, Uint256, Uint64}; - -/// This module is purely a workaround that lets us ignore lints for all the code -/// the `construct_uint!` macro generates. -#[allow(clippy::all)] -mod uints { - uint::construct_uint! { - pub struct U512(8); - } -} +use crate::{forward_ref_partial_eq, Uint128, Uint256, Uint64}; /// Used internally - we don't want to leak this type since we might change /// the implementation in the future. -use uints::U512; +use bnum::types::U512; /// An implementation of u512 that is using strings for JSON encoding/decoding, /// such that the full u512 range can be used for clients that convert JSON numbers to floats, @@ -50,14 +42,16 @@ use uints::U512; /// assert_eq!(a, b); /// ``` #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] -pub struct Uint512(#[schemars(with = "String")] U512); +pub struct Uint512(#[schemars(with = "String")] pub(crate) U512); + +forward_ref_partial_eq!(Uint512, Uint512); impl Uint512 { pub const MAX: Uint512 = Uint512(U512::MAX); - pub const MIN: Uint512 = Uint512(U512::zero()); + pub const MIN: Uint512 = Uint512(U512::ZERO); /// Creates a Uint512(value) from a big endian representation. It's just an alias for - /// `from_big_endian`. + /// `from_be_bytes`. pub const fn new(value: [u8; 64]) -> Self { Self::from_be_bytes(value) } @@ -65,19 +59,16 @@ impl Uint512 { /// Creates a Uint512(0) #[inline] pub const fn zero() -> Self { - Uint512(U512::zero()) + Uint512(U512::ZERO) } /// Creates a Uint512(1) #[inline] pub const fn one() -> Self { - Self::from_be_bytes([ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, - ]) + Self(U512::ONE) } + #[must_use] pub const fn from_be_bytes(data: [u8; 64]) -> Self { let words: [u64; 8] = [ u64::from_le_bytes([ @@ -105,9 +96,10 @@ impl Uint512 { data[7], data[6], data[5], data[4], data[3], data[2], data[1], data[0], ]), ]; - Self(U512(words)) + Self(U512::from_digits(words)) } + #[must_use] pub const fn from_le_bytes(data: [u8; 64]) -> Self { let words: [u64; 8] = [ u64::from_le_bytes([ @@ -135,11 +127,12 @@ impl Uint512 { data[56], data[57], data[58], data[59], data[60], data[61], data[62], data[63], ]), ]; - Self(U512(words)) + Self(U512::from_digits(words)) } /// A conversion from `Uint256` that, unlike the one provided by the `From` trait, /// can be used in a `const` context. + #[must_use] pub const fn from_uint256(num: Uint256) -> Self { let bytes = num.to_le_bytes(); Self::from_le_bytes([ @@ -153,50 +146,47 @@ impl Uint512 { } /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_be_bytes(self) -> [u8; 64] { + let words = self.0.digits(); let words = [ - (self.0).0[7].to_be_bytes(), - (self.0).0[6].to_be_bytes(), - (self.0).0[5].to_be_bytes(), - (self.0).0[4].to_be_bytes(), - (self.0).0[3].to_be_bytes(), - (self.0).0[2].to_be_bytes(), - (self.0).0[1].to_be_bytes(), - (self.0).0[0].to_be_bytes(), + words[7].to_be_bytes(), + words[6].to_be_bytes(), + words[5].to_be_bytes(), + words[4].to_be_bytes(), + words[3].to_be_bytes(), + words[2].to_be_bytes(), + words[1].to_be_bytes(), + words[0].to_be_bytes(), ]; - unsafe { std::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) } + unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) } } /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_le_bytes(self) -> [u8; 64] { + let words = self.0.digits(); let words = [ - (self.0).0[0].to_le_bytes(), - (self.0).0[1].to_le_bytes(), - (self.0).0[2].to_le_bytes(), - (self.0).0[3].to_le_bytes(), - (self.0).0[4].to_le_bytes(), - (self.0).0[5].to_le_bytes(), - (self.0).0[6].to_le_bytes(), - (self.0).0[7].to_le_bytes(), + words[0].to_le_bytes(), + words[1].to_le_bytes(), + words[2].to_le_bytes(), + words[3].to_le_bytes(), + words[4].to_le_bytes(), + words[5].to_le_bytes(), + words[6].to_le_bytes(), + words[7].to_le_bytes(), ]; - unsafe { std::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) } + unsafe { core::mem::transmute::<[[u8; 8]; 8], [u8; 64]>(words) } } + #[must_use] pub const fn is_zero(&self) -> bool { - let words = (self.0).0; - words[0] == 0 - && words[1] == 0 - && words[2] == 0 - && words[3] == 0 - && words[4] == 0 - && words[5] == 0 - && words[6] == 0 - && words[7] == 0 + self.0.is_zero() } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn pow(self, exp: u32) -> Self { - let res = self.0.pow(exp.into()); - Self(res) + Self(self.0.pow(exp)) } pub fn checked_add(self, other: Self) -> Result { @@ -222,7 +212,7 @@ impl Uint512 { pub fn checked_pow(self, exp: u32) -> Result { self.0 - .checked_pow(exp.into()) + .checked_pow(exp) .map(Self) .ok_or_else(|| OverflowError::new(OverflowOperation::Pow, self, exp)) } @@ -246,73 +236,76 @@ impl Uint512 { } pub fn checked_shr(self, other: u32) -> Result { + self.0 + .checked_shr(other) + .map(Self) + .ok_or_else(|| OverflowError::new(OverflowOperation::Shr, self, other)) + } + + pub fn checked_shl(self, other: u32) -> Result { if other >= 512 { - return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); } - Ok(Self(self.0.shr(other))) + Ok(Self(self.0.shl(other))) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_add(self, other: Self) -> Self { - let (value, _did_overflow) = self.0.overflowing_add(other.0); - Self(value) + Self(self.0.wrapping_add(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_sub(self, other: Self) -> Self { - let (value, _did_overflow) = self.0.overflowing_sub(other.0); - Self(value) + Self(self.0.wrapping_sub(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_mul(self, other: Self) -> Self { - let (value, _did_overflow) = self.0.overflowing_mul(other.0); - Self(value) + Self(self.0.wrapping_mul(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] #[inline] pub fn wrapping_pow(self, other: u32) -> Self { - let (value, _did_overflow) = self.0.overflowing_pow(other.into()); - Self(value) + Self(self.0.wrapping_pow(other)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_add(self, other: Self) -> Self { Self(self.0.saturating_add(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_sub(self, other: Self) -> Self { Self(self.0.saturating_sub(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_mul(self, other: Self) -> Self { Self(self.0.saturating_mul(other.0)) } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_pow(self, exp: u32) -> Self { - match self.checked_pow(exp) { - Ok(value) => value, - Err(_) => Self::MAX, - } + Self(self.0.saturating_pow(exp)) } - pub fn abs_diff(self, other: Self) -> Self { - if self < other { - other - self - } else { - self - other - } + #[must_use = "this returns the result of the operation, without modifying the original"] + pub const fn abs_diff(self, other: Self) -> Self { + Self(self.0.abs_diff(other.0)) } } impl From for Uint512 { fn from(val: Uint256) -> Self { - let bytes = [[0u8; 32], val.to_be_bytes()].concat(); + let mut bytes = [0u8; 64]; + bytes[32..].copy_from_slice(&val.to_be_bytes()); - Self::from_be_bytes(bytes.try_into().unwrap()) + Self::from_be_bytes(bytes) } } @@ -399,9 +392,9 @@ impl FromStr for Uint512 { type Err = StdError; fn from_str(s: &str) -> Result { - match U512::from_dec_str(s) { + match U512::from_str_radix(s, 10) { Ok(u) => Ok(Self(u)), - Err(e) => Err(StdError::generic_err(format!("Parsing u512: {}", e))), + Err(e) => Err(StdError::generic_err(format!("Parsing u512: {e}"))), } } } @@ -414,11 +407,7 @@ impl From for String { impl fmt::Display for Uint512 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // The inner type doesn't work as expected with padding, so we - // work around that. - let unpadded = self.0.to_string(); - - f.pad_integral(true, "", &unpadded) + self.0.fmt(f) } } @@ -483,6 +472,14 @@ impl Rem for Uint512 { } forward_ref_binop!(impl Rem, rem for Uint512, Uint512); +impl Not for Uint512 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + impl RemAssign for Uint512 { fn rem_assign(&mut self, rhs: Uint512) { *self = *self % rhs; @@ -512,8 +509,7 @@ impl Shr for Uint512 { fn shr(self, rhs: u32) -> Self::Output { self.checked_shr(rhs).unwrap_or_else(|_| { panic!( - "right shift error: {} is larger or equal than the number of bits in Uint512", - rhs, + "right shift error: {rhs} is larger or equal than the number of bits in Uint512", ) }) } @@ -527,6 +523,23 @@ impl<'a> Shr<&'a u32> for Uint512 { } } +impl Shl for Uint512 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + self.checked_shl(rhs) + .expect("attempt to shift left with overflow") + } +} + +impl<'a> Shl<&'a u32> for Uint512 { + type Output = Self; + + fn shl(self, rhs: &'a u32) -> Self::Output { + self.shl(*rhs) + } +} + impl AddAssign for Uint512 { fn add_assign(&mut self, rhs: Uint512) { self.0 = self.0.checked_add(rhs.0).unwrap(); @@ -563,6 +576,18 @@ impl<'a> ShrAssign<&'a u32> for Uint512 { } } +impl ShlAssign for Uint512 { + fn shl_assign(&mut self, rhs: u32) { + *self = self.shl(rhs); + } +} + +impl<'a> ShlAssign<&'a u32> for Uint512 { + fn shl_assign(&mut self, rhs: &'a u32) { + *self = self.shl(*rhs); + } +} + impl Serialize for Uint512 { /// Serializes as an integer string using base 10 fn serialize(&self, serializer: S) -> Result @@ -596,11 +621,11 @@ impl<'de> de::Visitor<'de> for Uint512Visitor { where E: de::Error, { - Uint512::try_from(v).map_err(|e| E::custom(format!("invalid Uint512 '{}' - {}", v, e))) + Uint512::try_from(v).map_err(|e| E::custom(format!("invalid Uint512 '{v}' - {e}"))) } } -impl std::iter::Sum for Uint512 +impl core::iter::Sum for Uint512 where Self: Add, { @@ -609,23 +634,16 @@ where } } -impl PartialEq<&Uint512> for Uint512 { - fn eq(&self, rhs: &&Uint512) -> bool { - self == *rhs - } -} - -impl PartialEq for &Uint512 { - fn eq(&self, rhs: &Uint512) -> bool { - *self == rhs - } -} - #[cfg(test)] mod tests { use super::*; use crate::{from_slice, to_vec}; + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 64); + } + #[test] fn uint512_new_works() { let num = Uint512::new([1; 64]); @@ -643,6 +661,16 @@ mod tests { assert_eq!(be_bytes, resulting_bytes); } + #[test] + fn uint512_not_works() { + let num = Uint512::new([1; 64]); + let a = (!num).to_be_bytes(); + assert_eq!(a, [254; 64]); + + assert_eq!(!Uint512::MAX, Uint512::MIN); + assert_eq!(!Uint512::MIN, Uint512::MAX); + } + #[test] fn uint512_zero_works() { let zero = Uint512::zero(); @@ -696,22 +724,25 @@ mod tests { #[test] fn uint512_convert_from() { let a = Uint512::from(5u128); - assert_eq!(a.0, U512::from(5)); + assert_eq!(a.0, U512::from(5u32)); let a = Uint512::from(5u64); - assert_eq!(a.0, U512::from(5)); + assert_eq!(a.0, U512::from(5u32)); let a = Uint512::from(5u32); - assert_eq!(a.0, U512::from(5)); + assert_eq!(a.0, U512::from(5u32)); let a = Uint512::from(5u16); - assert_eq!(a.0, U512::from(5)); + assert_eq!(a.0, U512::from(5u32)); let a = Uint512::from(5u8); - assert_eq!(a.0, U512::from(5)); + assert_eq!(a.0, U512::from(5u32)); let result = Uint512::try_from("34567"); - assert_eq!(result.unwrap().0, U512::from_dec_str("34567").unwrap()); + assert_eq!( + result.unwrap().0, + U512::from_str_radix("34567", 10).unwrap() + ); let result = Uint512::try_from("1.23"); assert!(result.is_err()); @@ -764,18 +795,23 @@ mod tests { #[test] fn uint512_implements_display() { let a = Uint512::from(12345u32); - assert_eq!(format!("Embedded: {}", a), "Embedded: 12345"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); assert_eq!(a.to_string(), "12345"); let a = Uint512::zero(); - assert_eq!(format!("Embedded: {}", a), "Embedded: 0"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); assert_eq!(a.to_string(), "0"); } #[test] fn uint512_display_padding_works() { + // width > natural representation + let a = Uint512::from(123u64); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + + // width < natural representation let a = Uint512::from(123u64); - assert_eq!(format!("Embedded: {:05}", a), "Embedded: 00123"); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); } #[test] @@ -889,7 +925,7 @@ mod tests { #[test] fn uint512_is_zero_works() { assert!(Uint512::zero().is_zero()); - assert!(Uint512(U512::from(0)).is_zero()); + assert!(Uint512(U512::from(0u32)).is_zero()); assert!(!Uint512::from(1u32).is_zero()); assert!(!Uint512::from(123u32).is_zero()); @@ -1083,7 +1119,7 @@ mod tests { #[test] #[should_panic] fn uint512_pow_overflow_panics() { - Uint512::MAX.pow(2u32); + _ = Uint512::MAX.pow(2u32); } #[test] @@ -1111,6 +1147,31 @@ mod tests { let _ = Uint512::from(1u32) >> 512u32; } + #[test] + fn uint512_shl_works() { + let original = Uint512::new([ + 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]); + + let shifted = Uint512::new([ + 2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ]); + + assert_eq!(original << 2u32, shifted); + } + + #[test] + #[should_panic] + fn uint512_shl_overflow_panics() { + let _ = Uint512::from(1u32) << 512u32; + } + #[test] fn sum_works() { let nums = vec![ @@ -1229,7 +1290,7 @@ mod tests { } #[test] - #[should_panic(expected = "division by zero")] + #[should_panic(expected = "divisor of zero")] fn uint512_rem_panics_for_zero() { let _ = Uint512::from(10u32) % Uint512::zero(); } diff --git a/packages/std/src/math/uint64.rs b/packages/std/src/math/uint64.rs index 17d765fc0..f405b2364 100644 --- a/packages/std/src/math/uint64.rs +++ b/packages/std/src/math/uint64.rs @@ -1,15 +1,18 @@ +use core::fmt::{self}; +use core::ops::{ + Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, + Sub, SubAssign, +}; use forward_ref::{forward_ref_binop, forward_ref_op_assign}; use schemars::JsonSchema; use serde::{de, ser, Deserialize, Deserializer, Serialize}; -use std::fmt::{self}; -use std::ops::{ - Add, AddAssign, Div, DivAssign, Mul, MulAssign, Rem, RemAssign, Shr, ShrAssign, Sub, SubAssign, -}; +use std::ops::Not; use crate::errors::{ - CheckedMultiplyRatioError, DivideByZeroError, OverflowError, OverflowOperation, StdError, + CheckedMultiplyFractionError, CheckedMultiplyRatioError, DivideByZeroError, OverflowError, + OverflowOperation, StdError, }; -use crate::Uint128; +use crate::{forward_ref_partial_eq, impl_mul_fraction, Fraction, Uint128}; /// A thin wrapper around u64 that is using strings for JSON encoding/decoding, /// such that the full u64 range can be used for clients that convert JSON numbers to floats, @@ -28,7 +31,9 @@ use crate::Uint128; /// assert_eq!(b.u64(), 70); /// ``` #[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] -pub struct Uint64(#[schemars(with = "String")] u64); +pub struct Uint64(#[schemars(with = "String")] pub(crate) u64); + +forward_ref_partial_eq!(Uint64, Uint64); impl Uint64 { pub const MAX: Self = Self(u64::MAX); @@ -59,19 +64,23 @@ impl Uint64 { } /// Returns a copy of the number as big endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_be_bytes(self) -> [u8; 8] { self.0.to_be_bytes() } /// Returns a copy of the number as little endian bytes. + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn to_le_bytes(self) -> [u8; 8] { self.0.to_le_bytes() } + #[must_use] pub const fn is_zero(&self) -> bool { self.0 == 0 } + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn pow(self, exp: u32) -> Self { self.0.pow(exp).into() } @@ -80,6 +89,7 @@ impl Uint64 { /// /// Due to the nature of the integer division involved, the result is always floored. /// E.g. 5 * 99/100 = 4. + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn multiply_ratio, B: Into>( &self, numerator: A, @@ -126,6 +136,7 @@ impl Uint64 { /// let result = a.full_mul(2u32); /// assert_eq!(result.to_string(), "36893488147419103230"); /// ``` + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn full_mul(self, rhs: impl Into) -> Uint128 { Uint128::from(self.u64()) .checked_mul(Uint128::from(rhs.into())) @@ -181,47 +192,67 @@ impl Uint64 { .ok_or_else(|| DivideByZeroError::new(self)) } - #[must_use] + pub fn checked_shr(self, other: u32) -> Result { + if other >= 64 { + return Err(OverflowError::new(OverflowOperation::Shr, self, other)); + } + + Ok(Self(self.0.shr(other))) + } + + pub fn checked_shl(self, other: u32) -> Result { + if other >= 64 { + return Err(OverflowError::new(OverflowOperation::Shl, self, other)); + } + + Ok(Self(self.0.shl(other))) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_add(self, other: Self) -> Self { Self(self.0.wrapping_add(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_sub(self, other: Self) -> Self { Self(self.0.wrapping_sub(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_mul(self, other: Self) -> Self { Self(self.0.wrapping_mul(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] pub fn wrapping_pow(self, other: u32) -> Self { Self(self.0.wrapping_pow(other)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_add(self, other: Self) -> Self { Self(self.0.saturating_add(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_sub(self, other: Self) -> Self { Self(self.0.saturating_sub(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_mul(self, other: Self) -> Self { Self(self.0.saturating_mul(other.0)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub fn saturating_pow(self, exp: u32) -> Self { Self(self.0.saturating_pow(exp)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn abs_diff(self, other: Self) -> Self { Self(if self.0 < other.0 { other.0 - self.0 @@ -231,6 +262,8 @@ impl Uint64 { } } +impl_mul_fraction!(Uint64); + // `From` is implemented manually instead of // using `impl> From for Uint64` because // of the conflict with `TryFrom<&str>` as described here @@ -266,7 +299,7 @@ impl TryFrom<&str> for Uint64 { fn try_from(val: &str) -> Result { match val.parse::() { Ok(u) => Ok(Uint64(u)), - Err(e) => Err(StdError::generic_err(format!("Parsing u64: {}", e))), + Err(e) => Err(StdError::generic_err(format!("Parsing u64: {e}"))), } } } @@ -374,6 +407,14 @@ impl Rem for Uint64 { } forward_ref_binop!(impl Rem, rem for Uint64, Uint64); +impl Not for Uint64 { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + impl RemAssign for Uint64 { fn rem_assign(&mut self, rhs: Uint64) { *self = *self % rhs; @@ -397,6 +438,26 @@ impl<'a> Shr<&'a u32> for Uint64 { } } +impl Shl for Uint64 { + type Output = Self; + + fn shl(self, rhs: u32) -> Self::Output { + Self( + self.u64() + .checked_shl(rhs) + .expect("attempt to shift left with overflow"), + ) + } +} + +impl<'a> Shl<&'a u32> for Uint64 { + type Output = Self; + + fn shl(self, rhs: &'a u32) -> Self::Output { + self.shl(*rhs) + } +} + impl AddAssign for Uint64 { fn add_assign(&mut self, rhs: Uint64) { self.0 = self.0.checked_add(rhs.u64()).unwrap(); @@ -433,6 +494,18 @@ impl<'a> ShrAssign<&'a u32> for Uint64 { } } +impl ShlAssign for Uint64 { + fn shl_assign(&mut self, rhs: u32) { + *self = self.shl(rhs); + } +} + +impl<'a> ShlAssign<&'a u32> for Uint64 { + fn shl_assign(&mut self, rhs: &'a u32) { + *self = self.shl(*rhs); + } +} + impl Serialize for Uint64 { /// Serializes as an integer string using base 10 fn serialize(&self, serializer: S) -> Result @@ -468,12 +541,12 @@ impl<'de> de::Visitor<'de> for Uint64Visitor { { match v.parse::() { Ok(u) => Ok(Uint64(u)), - Err(e) => Err(E::custom(format!("invalid Uint64 '{}' - {}", v, e))), + Err(e) => Err(E::custom(format!("invalid Uint64 '{v}' - {e}"))), } } } -impl std::iter::Sum for Uint64 +impl core::iter::Sum for Uint64 where Self: Add, { @@ -482,22 +555,24 @@ where } } -impl PartialEq<&Uint64> for Uint64 { - fn eq(&self, rhs: &&Uint64) -> bool { - self == *rhs - } -} - -impl PartialEq for &Uint64 { - fn eq(&self, rhs: &Uint64) -> bool { - *self == rhs - } -} - #[cfg(test)] mod tests { use super::*; - use crate::{from_slice, to_vec}; + use crate::errors::CheckedMultiplyFractionError::{ConversionOverflow, DivideByZero}; + use crate::{from_slice, to_vec, ConversionOverflowError}; + + #[test] + fn size_of_works() { + assert_eq!(core::mem::size_of::(), 8); + } + + #[test] + fn uint64_not_works() { + assert_eq!(!Uint64::new(1234806), Uint64::new(!1234806)); + + assert_eq!(!Uint64::MAX, Uint64::new(!u64::MAX)); + assert_eq!(!Uint64::MIN, Uint64::new(!u64::MIN)); + } #[test] fn uint64_zero_works() { @@ -546,18 +621,23 @@ mod tests { #[test] fn uint64_implements_display() { let a = Uint64(12345); - assert_eq!(format!("Embedded: {}", a), "Embedded: 12345"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 12345"); assert_eq!(a.to_string(), "12345"); let a = Uint64(0); - assert_eq!(format!("Embedded: {}", a), "Embedded: 0"); + assert_eq!(format!("Embedded: {a}"), "Embedded: 0"); assert_eq!(a.to_string(), "0"); } #[test] fn uint64_display_padding_works() { + // width > natural representation let a = Uint64::from(123u64); - assert_eq!(format!("Embedded: {:05}", a), "Embedded: 00123"); + assert_eq!(format!("Embedded: {a:05}"), "Embedded: 00123"); + + // width < natural representation + let a = Uint64::from(123u64); + assert_eq!(format!("Embedded: {a:02}"), "Embedded: 123"); } #[test] @@ -722,7 +802,7 @@ mod tests { #[test] #[should_panic] fn uint64_pow_overflow_panics() { - Uint64::MAX.pow(2u32); + _ = Uint64::MAX.pow(2u32); } #[test] @@ -776,7 +856,7 @@ mod tests { #[test] #[should_panic(expected = "Denominator must not be zero")] fn uint64_multiply_ratio_panics_for_zero_denominator() { - Uint64(500).multiply_ratio(1u64, 0u64); + _ = Uint64(500).multiply_ratio(1u64, 0u64); } #[test] @@ -791,6 +871,40 @@ mod tests { ); } + #[test] + fn uint64_shr_works() { + let original = Uint64::new(u64::from_be_bytes([0u8, 0u8, 0u8, 0u8, 2u8, 0u8, 4u8, 2u8])); + + let shifted = Uint64::new(u64::from_be_bytes([ + 0u8, 0u8, 0u8, 0u8, 0u8, 128u8, 1u8, 0u8, + ])); + + assert_eq!(original >> 2u32, shifted); + } + + #[test] + #[should_panic] + fn uint64_shr_overflow_panics() { + let _ = Uint64::from(1u32) >> 64u32; + } + + #[test] + fn uint64_shl_works() { + let original = Uint64::new(u64::from_be_bytes([ + 64u8, 128u8, 1u8, 0u8, 0u8, 0u8, 0u8, 0u8, + ])); + + let shifted = Uint64::new(u64::from_be_bytes([2u8, 0u8, 4u8, 0u8, 0u8, 0u8, 0u8, 0u8])); + + assert_eq!(original << 2u32, shifted); + } + + #[test] + #[should_panic] + fn uint64_shl_overflow_panics() { + let _ = Uint64::from(1u32) << 64u32; + } + #[test] fn sum_works() { let nums = vec![Uint64(17), Uint64(123), Uint64(540), Uint64(82)]; @@ -955,4 +1069,260 @@ mod tests { assert_eq!(&lhs == &rhs, expected); } } + + #[test] + fn mul_floor_works_with_zero() { + let fraction = (0u32, 21u32); + let res = Uint64::new(123456).mul_floor(fraction); + assert_eq!(Uint64::zero(), res) + } + + #[test] + fn mul_floor_does_nothing_with_one() { + let fraction = (Uint64::one(), Uint64::one()); + let res = Uint64::new(123456).mul_floor(fraction); + assert_eq!(Uint64::new(123456), res) + } + + #[test] + fn mul_floor_rounds_down_with_normal_case() { + let fraction = (8u64, 21u64); + let res = Uint64::new(123456).mul_floor(fraction); // 47030.8571 + assert_eq!(Uint64::new(47030), res) + } + + #[test] + fn mul_floor_does_not_round_on_even_divide() { + let fraction = (2u64, 5u64); + let res = Uint64::new(25).mul_floor(fraction); + assert_eq!(Uint64::new(10), res) + } + + #[test] + fn mul_floor_works_when_operation_temporarily_takes_above_max() { + let fraction = (8u64, 21u64); + let res = Uint64::MAX.mul_floor(fraction); // 7_027_331_075_698_876_805.71428571 + assert_eq!(Uint64::new(7_027_331_075_698_876_805), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn mul_floor_panics_on_overflow() { + let fraction = (21u64, 8u64); + _ = Uint64::MAX.mul_floor(fraction); + } + + #[test] + fn checked_mul_floor_does_not_panic_on_overflow() { + let fraction = (21u64, 8u64); + assert_eq!( + Uint64::MAX.checked_mul_floor(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint128", + target_type: "Uint64", + value: "48422703193487572989".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn mul_floor_panics_on_zero_div() { + let fraction = (21u64, 0u64); + _ = Uint64::new(123456).mul_floor(fraction); + } + + #[test] + fn checked_mul_floor_does_not_panic_on_zero_div() { + let fraction = (21u64, 0u64); + assert_eq!( + Uint64::new(123456).checked_mul_floor(fraction), + Err(DivideByZero(DivideByZeroError { + operand: "2592576".to_string() + })), + ); + } + + #[test] + fn mul_ceil_works_with_zero() { + let fraction = (Uint64::zero(), Uint64::new(21)); + let res = Uint64::new(123456).mul_ceil(fraction); + assert_eq!(Uint64::zero(), res) + } + + #[test] + fn mul_ceil_does_nothing_with_one() { + let fraction = (Uint64::one(), Uint64::one()); + let res = Uint64::new(123456).mul_ceil(fraction); + assert_eq!(Uint64::new(123456), res) + } + + #[test] + fn mul_ceil_rounds_up_with_normal_case() { + let fraction = (8u64, 21u64); + let res = Uint64::new(123456).mul_ceil(fraction); // 47030.8571 + assert_eq!(Uint64::new(47031), res) + } + + #[test] + fn mul_ceil_does_not_round_on_even_divide() { + let fraction = (2u64, 5u64); + let res = Uint64::new(25).mul_ceil(fraction); + assert_eq!(Uint64::new(10), res) + } + + #[test] + fn mul_ceil_works_when_operation_temporarily_takes_above_max() { + let fraction = (8u64, 21u64); + let res = Uint64::MAX.mul_ceil(fraction); // 7_027_331_075_698_876_805.71428571 + assert_eq!(Uint64::new(7_027_331_075_698_876_806), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn mul_ceil_panics_on_overflow() { + let fraction = (21u64, 8u64); + _ = Uint64::MAX.mul_ceil(fraction); + } + + #[test] + fn checked_mul_ceil_does_not_panic_on_overflow() { + let fraction = (21u64, 8u64); + assert_eq!( + Uint64::MAX.checked_mul_ceil(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint128", + target_type: "Uint64", + value: "48422703193487572989".to_string() // raises prior to rounding up + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn mul_ceil_panics_on_zero_div() { + let fraction = (21u64, 0u64); + _ = Uint64::new(123456).mul_ceil(fraction); + } + + #[test] + fn checked_mul_ceil_does_not_panic_on_zero_div() { + let fraction = (21u64, 0u64); + assert_eq!( + Uint64::new(123456).checked_mul_ceil(fraction), + Err(DivideByZero(DivideByZeroError { + operand: "2592576".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn div_floor_raises_with_zero() { + let fraction = (Uint64::zero(), Uint64::new(21)); + _ = Uint64::new(123456).div_floor(fraction); + } + + #[test] + fn div_floor_does_nothing_with_one() { + let fraction = (Uint64::one(), Uint64::one()); + let res = Uint64::new(123456).div_floor(fraction); + assert_eq!(Uint64::new(123456), res) + } + + #[test] + fn div_floor_rounds_down_with_normal_case() { + let fraction = (5u64, 21u64); + let res = Uint64::new(123456).div_floor(fraction); // 518515.2 + assert_eq!(Uint64::new(518515), res) + } + + #[test] + fn div_floor_does_not_round_on_even_divide() { + let fraction = (5u64, 2u64); + let res = Uint64::new(25).div_floor(fraction); + assert_eq!(Uint64::new(10), res) + } + + #[test] + fn div_floor_works_when_operation_temporarily_takes_above_max() { + let fraction = (21u64, 8u64); + let res = Uint64::MAX.div_floor(fraction); // 7_027_331_075_698_876_805.71428 + assert_eq!(Uint64::new(7_027_331_075_698_876_805), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn div_floor_panics_on_overflow() { + let fraction = (8u64, 21u64); + _ = Uint64::MAX.div_floor(fraction); + } + + #[test] + fn div_floor_does_not_panic_on_overflow() { + let fraction = (8u64, 21u64); + assert_eq!( + Uint64::MAX.checked_div_floor(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint128", + target_type: "Uint64", + value: "48422703193487572989".to_string() + })), + ); + } + + #[test] + #[should_panic(expected = "DivideByZeroError")] + fn div_ceil_raises_with_zero() { + let fraction = (Uint64::zero(), Uint64::new(21)); + _ = Uint64::new(123456).div_ceil(fraction); + } + + #[test] + fn div_ceil_does_nothing_with_one() { + let fraction = (Uint64::one(), Uint64::one()); + let res = Uint64::new(123456).div_ceil(fraction); + assert_eq!(Uint64::new(123456), res) + } + + #[test] + fn div_ceil_rounds_up_with_normal_case() { + let fraction = (5u64, 21u64); + let res = Uint64::new(123456).div_ceil(fraction); // 518515.2 + assert_eq!(Uint64::new(518516), res) + } + + #[test] + fn div_ceil_does_not_round_on_even_divide() { + let fraction = (5u64, 2u64); + let res = Uint64::new(25).div_ceil(fraction); + assert_eq!(Uint64::new(10), res) + } + + #[test] + fn div_ceil_works_when_operation_temporarily_takes_above_max() { + let fraction = (21u64, 8u64); + let res = Uint64::MAX.div_ceil(fraction); // 7_027_331_075_698_876_805.71428 + assert_eq!(Uint64::new(7_027_331_075_698_876_806), res) + } + + #[test] + #[should_panic(expected = "ConversionOverflowError")] + fn div_ceil_panics_on_overflow() { + let fraction = (8u64, 21u64); + _ = Uint64::MAX.div_ceil(fraction); + } + + #[test] + fn div_ceil_does_not_panic_on_overflow() { + let fraction = (8u64, 21u64); + assert_eq!( + Uint64::MAX.checked_div_ceil(fraction), + Err(ConversionOverflow(ConversionOverflowError { + source_type: "Uint128", + target_type: "Uint64", + value: "48422703193487572989".to_string() + })), + ); + } } diff --git a/packages/std/src/memory.rs b/packages/std/src/memory.rs index c331a53c4..7fa3098a1 100644 --- a/packages/std/src/memory.rs +++ b/packages/std/src/memory.rs @@ -1,5 +1,5 @@ -use std::mem; -use std::vec::Vec; +use alloc::vec::Vec; +use core::mem; /// Describes some data allocated in Wasm's linear memory. /// A pointer to an instance of this can be returned over FFI boundaries. diff --git a/packages/std/src/metadata.rs b/packages/std/src/metadata.rs new file mode 100644 index 000000000..c0827ce72 --- /dev/null +++ b/packages/std/src/metadata.rs @@ -0,0 +1,23 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +/// Replicates the cosmos-sdk bank module Metadata type +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] +pub struct DenomMetadata { + pub description: String, + pub denom_units: Vec, + pub base: String, + pub display: String, + pub name: String, + pub symbol: String, + pub uri: String, + pub uri_hash: String, +} + +/// Replicates the cosmos-sdk bank module DenomUnit type +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] +pub struct DenomUnit { + pub denom: String, + pub exponent: u32, + pub aliases: Vec, +} diff --git a/packages/std/src/never.rs b/packages/std/src/never.rs new file mode 100644 index 000000000..51173892f --- /dev/null +++ b/packages/std/src/never.rs @@ -0,0 +1,45 @@ +/// Never can never be instantiated. This can be used in places +/// where we want to ensure that no error is returned, such as +/// the `ibc_packet_receive` entry point. +/// +/// In contrast to `Empty`, this does not have a JSON schema +/// and cannot be used for message and query types. +/// +/// Once the ! type is stable, this is not needed anymore. +/// See . +/// +/// ## Examples +/// +/// When using `Never` in a `Result`, we can unwrap in a type-safe way: +/// +/// ``` +/// use cosmwasm_std::Never; +/// +/// pub fn safe_unwrap(res: Result) -> T { +/// match res { +/// Ok(value) => value, +/// Err(err) => match err {}, +/// } +/// } +/// +/// let res: Result = Ok(5); +/// assert_eq!(safe_unwrap(res), 5); +/// ``` +pub enum Never {} + +// The Debug implementation is needed to allow the use of `Result::unwrap`. +impl core::fmt::Debug for Never { + fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + // Unreachable because no instance of Never can exist + match *self {} + } +} + +// The Display implementation is needed to fulfill the ToString requirement of +// entry point errors: `Result, E>` with `E: ToString`. +impl core::fmt::Display for Never { + fn fmt(&self, _f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + // Unreachable because no instance of Never can exist + match *self {} + } +} diff --git a/packages/std/src/pagination.rs b/packages/std/src/pagination.rs new file mode 100644 index 000000000..d9d1d8ef9 --- /dev/null +++ b/packages/std/src/pagination.rs @@ -0,0 +1,12 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::Binary; + +/// Simplified version of the PageRequest type for pagination from the cosmos-sdk +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] +pub struct PageRequest { + pub key: Option, + pub limit: u32, + pub reverse: bool, +} diff --git a/packages/std/src/query/bank.rs b/packages/std/src/query/bank.rs index 9656ea613..95cf616e2 100644 --- a/packages/std/src/query/bank.rs +++ b/packages/std/src/query/bank.rs @@ -3,6 +3,12 @@ use serde::{Deserialize, Serialize}; use crate::Coin; +#[cfg(feature = "cosmwasm_1_3")] +use crate::PageRequest; +use crate::{Binary, DenomMetadata}; + +use super::query_response::QueryResponseType; + #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -19,10 +25,17 @@ pub enum BankQuery { /// Note that this may be much more expensive than Balance and should be avoided if possible. /// Return value is AllBalanceResponse. AllBalances { address: String }, + /// This calls into the native bank module for querying metadata for a specific bank token. + /// Return value is DenomMetadataResponse + #[cfg(feature = "cosmwasm_1_3")] + DenomMetadata { denom: String }, + /// This calls into the native bank module for querying metadata for all bank tokens that have a metadata entry. + /// Return value is AllDenomMetadataResponse + #[cfg(feature = "cosmwasm_1_3")] + AllDenomMetadata { pagination: Option }, } -#[cfg(feature = "cosmwasm_1_1")] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] #[non_exhaustive] pub struct SupplyResponse { @@ -31,7 +44,11 @@ pub struct SupplyResponse { pub amount: Coin, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +impl_response_constructor!(SupplyResponse, amount: Coin); + +impl QueryResponseType for SupplyResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct BalanceResponse { /// Always returns a Coin with the requested denom. @@ -39,9 +56,62 @@ pub struct BalanceResponse { pub amount: Coin, } -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +impl_response_constructor!(BalanceResponse, amount: Coin); + +impl QueryResponseType for BalanceResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct AllBalanceResponse { /// Returns all non-zero coins held by this account. pub amount: Vec, } + +impl_response_constructor!(AllBalanceResponse, amount: Vec); + +impl QueryResponseType for AllBalanceResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub struct DenomMetadataResponse { + /// The metadata for the queried denom. + pub metadata: DenomMetadata, +} + +impl_response_constructor!(DenomMetadataResponse, metadata: DenomMetadata); + +impl QueryResponseType for DenomMetadataResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub struct AllDenomMetadataResponse { + /// Always returns metadata for all token denoms on the base chain. + pub metadata: Vec, + pub next_key: Option, +} + +impl_response_constructor!( + AllDenomMetadataResponse, + metadata: Vec, + next_key: Option +); + +impl QueryResponseType for AllDenomMetadataResponse {} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn private_constructor_works() { + let response = AllBalanceResponse::new(vec![Coin::new(1234, "uatom")]); + assert_eq!( + response, + AllBalanceResponse { + amount: vec![Coin::new(1234, "uatom")] + } + ); + } +} diff --git a/packages/std/src/query/distribution.rs b/packages/std/src/query/distribution.rs new file mode 100644 index 000000000..0414ef792 --- /dev/null +++ b/packages/std/src/query/distribution.rs @@ -0,0 +1,106 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::Addr; + +use super::query_response::QueryResponseType; + +#[non_exhaustive] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum DistributionQuery { + /// See + DelegatorWithdrawAddress { delegator_address: String }, + /// See + #[cfg(feature = "cosmwasm_1_4")] + DelegationRewards { + delegator_address: String, + validator_address: String, + }, + /// See + #[cfg(feature = "cosmwasm_1_4")] + DelegationTotalRewards { delegator_address: String }, + /// See + #[cfg(feature = "cosmwasm_1_4")] + DelegatorValidators { delegator_address: String }, +} + +/// See +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +#[non_exhaustive] +pub struct DelegatorWithdrawAddressResponse { + pub withdraw_address: Addr, +} + +impl_response_constructor!(DelegatorWithdrawAddressResponse, withdraw_address: Addr); +impl QueryResponseType for DelegatorWithdrawAddressResponse {} + +/// See +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct DelegationRewardsResponse { + pub rewards: Vec, +} + +impl_response_constructor!(DelegationRewardsResponse, rewards: Vec); +impl QueryResponseType for DelegationRewardsResponse {} + +/// A coin type with decimal amount. +/// Modeled after the Cosmos SDK's [DecCoin] type. +/// However, in contrast to the Cosmos SDK the `amount` string MUST always have a dot at JSON level, +/// see . +/// Also if Cosmos SDK choses to migrate away from fixed point decimals +/// (as shown [here](https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/x/group/internal/math/dec.go#L13-L21 and discussed [here](https://github.com/cosmos/cosmos-sdk/issues/11783)), +/// wasmd needs to truncate the decimal places to 18. +/// +/// [DecCoin]: (https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/proto/cosmos/base/v1beta1/coin.proto#L28-L38) +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub struct DecCoin { + pub denom: String, + /// An amount in the base denom of the distributed token. + /// + /// Some chains have choosen atto (10^-18) for their token's base denomination. If we used `Decimal` here, we could only store + /// 340282366920938463463.374607431768211455atoken which is 340.28 TOKEN. + pub amount: crate::Decimal256, +} + +impl DecCoin { + pub fn new(amount: crate::Decimal256, denom: impl Into) -> Self { + Self { + denom: denom.into(), + amount, + } + } +} + +/// See +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[non_exhaustive] +pub struct DelegationTotalRewardsResponse { + pub rewards: Vec, + pub total: Vec, +} + +impl_response_constructor!( + DelegationTotalRewardsResponse, + rewards: Vec, + total: Vec +); +impl QueryResponseType for DelegationTotalRewardsResponse {} + +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct DelegatorReward { + pub validator_address: String, + pub reward: Vec, +} + +/// See +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct DelegatorValidatorsResponse { + pub validators: Vec, +} + +impl_response_constructor!(DelegatorValidatorsResponse, validators: Vec); +impl QueryResponseType for DelegatorValidatorsResponse {} diff --git a/packages/std/src/query/ibc.rs b/packages/std/src/query/ibc.rs index 0164de330..e8d6ff81e 100644 --- a/packages/std/src/query/ibc.rs +++ b/packages/std/src/query/ibc.rs @@ -1,5 +1,3 @@ -#![cfg(feature = "stargate")] - use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -37,12 +35,18 @@ pub struct PortIdResponse { pub port_id: String, } +impl_response_constructor!(PortIdResponse, port_id: String); + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ListChannelsResponse { pub channels: Vec, } +impl_response_constructor!(ListChannelsResponse, channels: Vec); + #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ChannelResponse { pub channel: Option, } + +impl_response_constructor!(ChannelResponse, channel: Option); diff --git a/packages/std/src/query/mod.rs b/packages/std/src/query/mod.rs index 67a2fcdb0..a957574a8 100644 --- a/packages/std/src/query/mod.rs +++ b/packages/std/src/query/mod.rs @@ -5,22 +5,37 @@ use serde::{Deserialize, Serialize}; use crate::Binary; use crate::Empty; +/// Implements a hidden constructor for query responses. +macro_rules! impl_response_constructor { + ( $response:ty, $( $field: ident : $t: ty),* ) => { + impl $response { + /// Constructor for testing frameworks such as cw-multi-test. + /// This is required because query response types should be #[non_exhaustive]. + /// As a contract developer you should not need this constructor since + /// query responses are constructed for you via deserialization. + /// + /// Warning: This can change in breaking ways in minor versions. + #[doc(hidden)] + #[allow(dead_code)] + pub fn new($( $field: $t),*) -> Self { + Self { $( $field ),* } + } + } + }; +} + mod bank; +mod distribution; mod ibc; +mod query_response; mod staking; mod wasm; -#[cfg(feature = "cosmwasm_1_1")] -pub use bank::SupplyResponse; -pub use bank::{AllBalanceResponse, BalanceResponse, BankQuery}; -#[cfg(feature = "stargate")] -pub use ibc::{ChannelResponse, IbcQuery, ListChannelsResponse, PortIdResponse}; -#[cfg(feature = "staking")] -pub use staking::{ - AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation, - DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse, -}; -pub use wasm::{ContractInfoResponse, WasmQuery}; +pub use bank::*; +pub use distribution::*; +pub use ibc::*; +pub use staking::*; +pub use wasm::*; #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] @@ -30,6 +45,8 @@ pub enum QueryRequest { Custom(C), #[cfg(feature = "staking")] Staking(StakingQuery), + #[cfg(feature = "cosmwasm_1_3")] + Distribution(DistributionQuery), /// A Stargate query is encoded the same way as abci_query, with path and protobuf encoded request data. /// The format is defined in [ADR-21](https://github.com/cosmos/cosmos-sdk/blob/master/docs/architecture/adr-021-protobuf-query-encoding.md). /// The response is protobuf encoded data directly without a JSON response wrapper. @@ -103,3 +120,10 @@ impl From for QueryRequest { QueryRequest::Ibc(msg) } } + +#[cfg(feature = "cosmwasm_1_3")] +impl From for QueryRequest { + fn from(msg: DistributionQuery) -> Self { + QueryRequest::Distribution(msg) + } +} diff --git a/packages/std/src/query/query_response.rs b/packages/std/src/query/query_response.rs new file mode 100644 index 000000000..4aa4559e4 --- /dev/null +++ b/packages/std/src/query/query_response.rs @@ -0,0 +1,18 @@ +use std::fmt::Debug; + +use serde::de::DeserializeOwned; + +/// A marker trait for query response types. +/// +/// Those types have in common that they should be `#[non_exhaustive]` in order +/// to allow adding fields in a backwards compatible way. In contracts they are +/// only constructed through deserialization. We want to make it hard for +/// contract developers to construct those types themselves as this is most likely +/// not what they should do. +/// +/// In hosts they are constructed as follows: +/// - wasmvm: Go types with the same JSON layout +/// - multi-test/cw-sdk: create a default instance and mutate the fields +/// +/// This trait is crate-internal and can change any time. +pub(crate) trait QueryResponseType: DeserializeOwned + Debug + PartialEq + Clone {} diff --git a/packages/std/src/query/staking.rs b/packages/std/src/query/staking.rs index fa513ac52..08222f3cb 100644 --- a/packages/std/src/query/staking.rs +++ b/packages/std/src/query/staking.rs @@ -1,10 +1,10 @@ -#![cfg(feature = "staking")] - use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use crate::{Addr, Coin, Decimal}; +use super::query_response::QueryResponseType; + #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -40,6 +40,10 @@ pub struct BondedDenomResponse { pub denom: String, } +impl QueryResponseType for BondedDenomResponse {} + +impl_response_constructor!(BondedDenomResponse, denom: String); + /// DelegationsResponse is data format returned from StakingRequest::AllDelegations query #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] @@ -47,6 +51,10 @@ pub struct AllDelegationsResponse { pub delegations: Vec, } +impl QueryResponseType for AllDelegationsResponse {} + +impl_response_constructor!(AllDelegationsResponse, delegations: Vec); + /// Delegation is basic (cheap to query) data about a delegation. /// /// Instances are created in the querier. @@ -76,6 +84,10 @@ pub struct DelegationResponse { pub delegation: Option, } +impl QueryResponseType for DelegationResponse {} + +impl_response_constructor!(DelegationResponse, delegation: Option); + /// FullDelegation is all the info on the delegation, some (like accumulated_reward and can_redelegate) /// is expensive to query. /// @@ -101,19 +113,32 @@ pub struct AllValidatorsResponse { pub validators: Vec, } +impl QueryResponseType for AllValidatorsResponse {} + +impl_response_constructor!(AllValidatorsResponse, validators: Vec); + /// The data format returned from StakingRequest::Validator query #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct ValidatorResponse { pub validator: Option, } +impl QueryResponseType for ValidatorResponse {} + +impl_response_constructor!(ValidatorResponse, validator: Option); + /// Instances are created in the querier. #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] pub struct Validator { - /// A validator address (e.g. cosmosvaloper1...) + /// The operator address of the validator (e.g. cosmosvaloper1...). + /// See https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/proto/cosmos/staking/v1beta1/staking.proto#L95-L96 + /// for more information. + /// + /// This uses `String` instead of `Addr` since the bech32 address prefix is different from + /// the ones that regular user accounts use. pub address: String, pub commission: Decimal, pub max_commission: Decimal, - /// TODO: what units are these (in terms of time)? + /// The maximum daily increase of the commission pub max_change_rate: Decimal, } diff --git a/packages/std/src/query/wasm.rs b/packages/std/src/query/wasm.rs index cbac89983..9487ff592 100644 --- a/packages/std/src/query/wasm.rs +++ b/packages/std/src/query/wasm.rs @@ -1,7 +1,9 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use crate::Binary; +use crate::{Binary, HexBinary}; + +use super::query_response::QueryResponseType; #[non_exhaustive] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] @@ -22,12 +24,15 @@ pub enum WasmQuery { /// Key is the raw key used in the contracts Storage key: Binary, }, - /// returns a ContractInfoResponse with metadata on the contract from the runtime + /// Returns a [`ContractInfoResponse`] with metadata on the contract from the runtime ContractInfo { contract_addr: String }, + /// Returns a [`CodeInfoResponse`] with metadata of the code + #[cfg(feature = "cosmwasm_1_2")] + CodeInfo { code_id: u64 }, } #[non_exhaustive] -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] pub struct ContractInfoResponse { pub code_id: u64, /// address that instantiated this contract @@ -40,16 +45,113 @@ pub struct ContractInfoResponse { pub ibc_port: Option, } +impl QueryResponseType for ContractInfoResponse {} + impl ContractInfoResponse { - /// Convenience constructor for tests / mocks + /// Constructor for testing frameworks such as cw-multi-test. + /// This is required because query response types should be #[non_exhaustive]. + /// As a contract developer you should not need this constructor since + /// query responses are constructed for you via deserialization. #[doc(hidden)] + #[deprecated( + note = "Use ContractInfoResponse::default() and mutate the fields you want to set." + )] pub fn new(code_id: u64, creator: impl Into) -> Self { - Self { + ContractInfoResponse { code_id, creator: creator.into(), - admin: None, - pinned: false, - ibc_port: None, + ..Default::default() } } } + +/// The essential data from wasmd's [CodeInfo]/[CodeInfoResponse]. +/// +/// `code_hash`/`data_hash` was renamed to `checksum` to follow the CosmWasm +/// convention and naming in `instantiate2_address`. +/// +/// [CodeInfo]: https://github.com/CosmWasm/wasmd/blob/v0.30.0/proto/cosmwasm/wasm/v1/types.proto#L62-L72 +/// [CodeInfoResponse]: https://github.com/CosmWasm/wasmd/blob/v0.30.0/proto/cosmwasm/wasm/v1/query.proto#L184-L199 +#[non_exhaustive] +#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, Eq, JsonSchema)] +pub struct CodeInfoResponse { + pub code_id: u64, + /// The address that initially stored the code + pub creator: String, + /// The hash of the Wasm blob + pub checksum: HexBinary, +} + +impl_response_constructor!( + CodeInfoResponse, + code_id: u64, + creator: String, + checksum: HexBinary +); + +impl QueryResponseType for CodeInfoResponse {} + +#[cfg(test)] +mod tests { + use super::*; + use crate::to_binary; + + #[test] + fn wasm_query_contract_info_serialization() { + let query = WasmQuery::ContractInfo { + contract_addr: "aabbccdd456".into(), + }; + let json = to_binary(&query).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"contract_info":{"contract_addr":"aabbccdd456"}}"#, + ); + } + + #[test] + #[cfg(feature = "cosmwasm_1_2")] + fn wasm_query_code_info_serialization() { + let query = WasmQuery::CodeInfo { code_id: 70 }; + let json = to_binary(&query).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"code_info":{"code_id":70}}"#, + ); + } + + #[test] + fn contract_info_response_serialization() { + let response = ContractInfoResponse { + code_id: 67, + creator: "jane".to_string(), + admin: Some("king".to_string()), + pinned: true, + ibc_port: Some("wasm.123".to_string()), + }; + let json = to_binary(&response).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"code_id":67,"creator":"jane","admin":"king","pinned":true,"ibc_port":"wasm.123"}"#, + ); + } + + #[test] + #[cfg(feature = "cosmwasm_1_2")] + fn code_info_response_serialization() { + use crate::HexBinary; + + let response = CodeInfoResponse { + code_id: 67, + creator: "jane".to_string(), + checksum: HexBinary::from_hex( + "f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00", + ) + .unwrap(), + }; + let json = to_binary(&response).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"code_id":67,"creator":"jane","checksum":"f7bb7b18fb01bbf425cf4ed2cd4b7fb26a019a7fc75a4dc87e8a0b768c501f00"}"#, + ); + } +} diff --git a/packages/std/src/results/contract_result.rs b/packages/std/src/results/contract_result.rs index 380ecaecc..343da57c8 100644 --- a/packages/std/src/results/contract_result.rs +++ b/packages/std/src/results/contract_result.rs @@ -1,6 +1,6 @@ +use core::fmt; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::fmt; /// This is the final result type that is created and serialized in a contract for /// every init/execute/migrate call. The VM then deserializes this type to distinguish @@ -132,18 +132,18 @@ mod tests { let parse: StdResult> = from_slice(br#"{"unrelated":321,"ok":4554}"#); match parse.unwrap_err() { StdError::ParseErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } let parse: StdResult> = from_slice(br#"{"ok":4554,"unrelated":321}"#); match parse.unwrap_err() { StdError::ParseErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } let parse: StdResult> = from_slice(br#"{"ok":4554,"error":"What's up now?"}"#); match parse.unwrap_err() { StdError::ParseErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/packages/std/src/results/cosmos_msg.rs b/packages/std/src/results/cosmos_msg.rs index 8c15e135e..1a8bd0eb6 100644 --- a/packages/std/src/results/cosmos_msg.rs +++ b/packages/std/src/results/cosmos_msg.rs @@ -1,7 +1,7 @@ +use core::fmt; use derivative::Derivative; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::fmt; use crate::binary::Binary; use crate::coin::Coin; @@ -9,6 +9,8 @@ use crate::errors::StdResult; #[cfg(feature = "stargate")] use crate::ibc::IbcMsg; use crate::serde::to_binary; +#[cfg(all(feature = "stargate", feature = "cosmwasm_1_2"))] +use crate::Decimal; use super::Empty; @@ -109,12 +111,19 @@ pub enum DistributionMsg { /// The `validator_address` validator: String, }, + /// This is translated to a [[MsgFundCommunityPool](https://github.com/cosmos/cosmos-sdk/blob/v0.42.4/proto/cosmos/distribution/v1beta1/tx.proto#LL69C1-L76C2). + /// `depositor` is automatically filled with the current contract's address. + #[cfg(feature = "cosmwasm_1_3")] + FundCommunityPool { + /// The amount to spend + amount: Vec, + }, } -fn binary_to_string(data: &Binary, fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - match std::str::from_utf8(data.as_slice()) { +fn binary_to_string(data: &Binary, fmt: &mut core::fmt::Formatter) -> core::fmt::Result { + match core::str::from_utf8(data.as_slice()) { Ok(s) => fmt.write_str(s), - Err(_) => write!(fmt, "{:?}", data), + Err(_) => fmt::Debug::fmt(data, fmt), } } @@ -139,6 +148,11 @@ pub enum WasmMsg { }, /// Instantiates a new contracts from previously uploaded Wasm code. /// + /// The contract address is non-predictable. But it is guaranteed that + /// when emitting the same Instantiate message multiple times, + /// multiple instances on different addresses will be generated. See also + /// Instantiate2. + /// /// This is translated to a [MsgInstantiateContract](https://github.com/Finschia/finschia-sdk/blob/v0.46.0/proto/cosmwasm/wasm/v1/tx.proto#L45-L62). /// `sender` is automatically filled with the current contract's address. Instantiate { @@ -148,9 +162,38 @@ pub enum WasmMsg { #[derivative(Debug(format_with = "binary_to_string"))] msg: Binary, funds: Vec, - /// A human-readbale label for the contract + /// A human-readable label for the contract. + /// + /// Valid values should: + /// - not be empty + /// - not be bigger than 128 bytes (or some chain-specific limit) + /// - not start / end with whitespace label: String, }, + /// Instantiates a new contracts from previously uploaded Wasm code + /// using a predictable address derivation algorithm implemented in + /// [`cosmwasm_std::instantiate2_address`]. + /// + /// This is translated to a [MsgInstantiateContract2](https://github.com/CosmWasm/wasmd/blob/v0.29.2/proto/cosmwasm/wasm/v1/tx.proto#L73-L96). + /// `sender` is automatically filled with the current contract's address. + /// `fix_msg` is automatically set to false. + #[cfg(feature = "cosmwasm_1_2")] + Instantiate2 { + admin: Option, + code_id: u64, + /// A human-readable label for the contract. + /// + /// Valid values should: + /// - not be empty + /// - not be bigger than 128 bytes (or some chain-specific limit) + /// - not start / end with whitespace + label: String, + /// msg is the JSON-encoded InstantiateMsg struct (as raw Binary) + #[derivative(Debug(format_with = "binary_to_string"))] + msg: Binary, + funds: Vec, + salt: Binary, + }, /// Migrates a given contracts to use new wasm code. Passes a MigrateMsg to allow us to /// customize behavior. /// @@ -177,12 +220,94 @@ pub enum WasmMsg { ClearAdmin { contract_addr: String }, } +/// This message type allows the contract interact with the [x/gov] module in order +/// to cast votes. +/// +/// [x/gov]: https://github.com/cosmos/cosmos-sdk/tree/v0.45.12/x/gov +/// +/// ## Examples +/// +/// Cast a simple vote: +/// +/// ``` +/// # use cosmwasm_std::{ +/// # HexBinary, +/// # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, +/// # Response, QueryResponse, +/// # }; +/// # type ExecuteMsg = (); +/// use cosmwasm_std::{GovMsg, VoteOption}; +/// +/// #[entry_point] +/// pub fn execute( +/// deps: DepsMut, +/// env: Env, +/// info: MessageInfo, +/// msg: ExecuteMsg, +/// ) -> Result { +/// // ... +/// Ok(Response::new().add_message(GovMsg::Vote { +/// proposal_id: 4, +/// vote: VoteOption::Yes, +/// })) +/// } +/// ``` +/// +/// Cast a weighted vote: +/// +/// ``` +/// # use cosmwasm_std::{ +/// # HexBinary, +/// # Storage, Api, Querier, DepsMut, Deps, entry_point, Env, StdError, MessageInfo, +/// # Response, QueryResponse, +/// # }; +/// # type ExecuteMsg = (); +/// # #[cfg(feature = "cosmwasm_1_2")] +/// use cosmwasm_std::{Decimal, GovMsg, VoteOption, WeightedVoteOption}; +/// +/// # #[cfg(feature = "cosmwasm_1_2")] +/// #[entry_point] +/// pub fn execute( +/// deps: DepsMut, +/// env: Env, +/// info: MessageInfo, +/// msg: ExecuteMsg, +/// ) -> Result { +/// // ... +/// Ok(Response::new().add_message(GovMsg::VoteWeighted { +/// proposal_id: 4, +/// options: vec![ +/// WeightedVoteOption { +/// option: VoteOption::Yes, +/// weight: Decimal::percent(65), +/// }, +/// WeightedVoteOption { +/// option: VoteOption::Abstain, +/// weight: Decimal::percent(35), +/// }, +/// ], +/// })) +/// } +/// ``` #[cfg(feature = "stargate")] #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum GovMsg { /// This maps directly to [MsgVote](https://github.com/cosmos/cosmos-sdk/blob/v0.42.5/proto/cosmos/gov/v1beta1/tx.proto#L46-L56) in the Cosmos SDK with voter set to the contract address. - Vote { proposal_id: u64, vote: VoteOption }, + Vote { + proposal_id: u64, + /// The vote option. + /// + /// This should be called "option" for consistency with Cosmos SDK. Sorry for that. + /// See . + vote: VoteOption, + }, + /// This maps directly to [MsgVoteWeighted](https://github.com/cosmos/cosmos-sdk/blob/v0.45.8/proto/cosmos/gov/v1beta1/tx.proto#L66-L78) in the Cosmos SDK with voter set to the contract address. + #[cfg(feature = "cosmwasm_1_2")] + VoteWeighted { + proposal_id: u64, + options: Vec, + }, } #[cfg(feature = "stargate")] @@ -195,6 +320,13 @@ pub enum VoteOption { NoWithVeto, } +#[cfg(all(feature = "stargate", feature = "cosmwasm_1_2"))] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +pub struct WeightedVoteOption { + pub option: VoteOption, + pub weight: Decimal, +} + /// Shortcut helper as the construction of WasmMsg::Instantiate can be quite verbose in contract code. /// /// When using this, `admin` is always unset. If you need more flexibility, create the message directly. @@ -214,7 +346,7 @@ pub fn wasm_instantiate( }) } -/// Shortcut helper as the construction of WasmMsg::Instantiate can be quite verbose in contract code +/// Shortcut helper as the construction of WasmMsg::Execute can be quite verbose in contract code pub fn wasm_execute( contract_addr: impl Into, msg: &impl Serialize, @@ -285,13 +417,109 @@ mod tests { } } - #[cosmwasm_schema::cw_serde] - enum ExecuteMsg { - Mint { coin: Coin }, + #[test] + fn wasm_msg_serializes_to_correct_json() { + // Instantiate with admin + let msg = WasmMsg::Instantiate { + admin: Some("king".to_string()), + code_id: 7897, + msg: br#"{"claim":{}}"#.into(), + funds: vec![], + label: "my instance".to_string(), + }; + let json = to_binary(&msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"instantiate":{"admin":"king","code_id":7897,"msg":"eyJjbGFpbSI6e319","funds":[],"label":"my instance"}}"#, + ); + + // Instantiate without admin + let msg = WasmMsg::Instantiate { + admin: None, + code_id: 7897, + msg: br#"{"claim":{}}"#.into(), + funds: vec![], + label: "my instance".to_string(), + }; + let json = to_binary(&msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"instantiate":{"admin":null,"code_id":7897,"msg":"eyJjbGFpbSI6e319","funds":[],"label":"my instance"}}"#, + ); + + // Instantiate with funds + let msg = WasmMsg::Instantiate { + admin: None, + code_id: 7897, + msg: br#"{"claim":{}}"#.into(), + funds: vec![coin(321, "stones")], + label: "my instance".to_string(), + }; + let json = to_binary(&msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"instantiate":{"admin":null,"code_id":7897,"msg":"eyJjbGFpbSI6e319","funds":[{"denom":"stones","amount":"321"}],"label":"my instance"}}"#, + ); + + // Instantiate2 + #[cfg(feature = "cosmwasm_1_2")] + { + let msg = WasmMsg::Instantiate2 { + admin: None, + code_id: 7897, + label: "my instance".to_string(), + msg: br#"{"claim":{}}"#.into(), + funds: vec![coin(321, "stones")], + salt: Binary::from_base64("UkOVazhiwoo=").unwrap(), + }; + let json = to_binary(&msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"instantiate2":{"admin":null,"code_id":7897,"label":"my instance","msg":"eyJjbGFpbSI6e319","funds":[{"denom":"stones","amount":"321"}],"salt":"UkOVazhiwoo="}}"#, + ); + } + } + + #[test] + #[cfg(feature = "cosmwasm_1_3")] + fn msg_distribution_serializes_to_correct_json() { + // FundCommunityPool + let fund_coins = vec![coin(200, "feathers"), coin(200, "stones")]; + let fund_msg = DistributionMsg::FundCommunityPool { amount: fund_coins }; + let fund_json = to_binary(&fund_msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&fund_json), + r#"{"fund_community_pool":{"amount":[{"denom":"feathers","amount":"200"},{"denom":"stones","amount":"200"}]}}"#, + ); + + // SetWithdrawAddress + let set_msg = DistributionMsg::SetWithdrawAddress { + address: String::from("withdrawer"), + }; + let set_json = to_binary(&set_msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&set_json), + r#"{"set_withdraw_address":{"address":"withdrawer"}}"#, + ); + + // WithdrawDelegatorRewards + let withdraw_msg = DistributionMsg::WithdrawDelegatorReward { + validator: String::from("fancyoperator"), + }; + let withdraw_json = to_binary(&withdraw_msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&withdraw_json), + r#"{"withdraw_delegator_reward":{"validator":"fancyoperator"}}"# + ); } #[test] fn wasm_msg_debug_decodes_binary_string_when_possible() { + #[cosmwasm_schema::cw_serde] + enum ExecuteMsg { + Mint { coin: Coin }, + } + let msg = WasmMsg::Execute { contract_addr: "joe".to_string(), msg: to_binary(&ExecuteMsg::Mint { @@ -302,7 +530,7 @@ mod tests { }; assert_eq!( - format!("{:?}", msg), + format!("{msg:?}"), "Execute { contract_addr: \"joe\", msg: {\"mint\":{\"coin\":{\"denom\":\"BTC\",\"amount\":\"10\"}}}, funds: [] }" ); } @@ -316,8 +544,51 @@ mod tests { }; assert_eq!( - format!("{:?}", msg), + format!("{msg:?}"), "Execute { contract_addr: \"joe\", msg: Binary(009f9296), funds: [] }" ); } + + #[test] + #[cfg(feature = "stargate")] + fn gov_msg_serializes_to_correct_json() { + // Vote + let msg = GovMsg::Vote { + proposal_id: 4, + vote: VoteOption::NoWithVeto, + }; + let json = to_binary(&msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"vote":{"proposal_id":4,"vote":"no_with_veto"}}"#, + ); + + // VoteWeighted + #[cfg(feature = "cosmwasm_1_2")] + { + let msg = GovMsg::VoteWeighted { + proposal_id: 25, + options: vec![ + WeightedVoteOption { + weight: Decimal::percent(25), + option: VoteOption::Yes, + }, + WeightedVoteOption { + weight: Decimal::percent(25), + option: VoteOption::No, + }, + WeightedVoteOption { + weight: Decimal::percent(50), + option: VoteOption::Abstain, + }, + ], + }; + + let json = to_binary(&msg).unwrap(); + assert_eq!( + String::from_utf8_lossy(&json), + r#"{"vote_weighted":{"proposal_id":25,"options":[{"option":"yes","weight":"0.25"},{"option":"no","weight":"0.25"},{"option":"abstain","weight":"0.5"}]}}"#, + ); + } + } } diff --git a/packages/std/src/results/events.rs b/packages/std/src/results/events.rs index 068f26323..195cd9161 100644 --- a/packages/std/src/results/events.rs +++ b/packages/std/src/results/events.rs @@ -1,6 +1,8 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use crate::forward_ref_partial_eq; + /// A full [*Cosmos SDK* event]. /// /// This version uses string attributes (similar to [*Cosmos SDK* StringEvent]), @@ -23,6 +25,8 @@ pub struct Event { pub attributes: Vec, } +forward_ref_partial_eq!(Event, Event); + impl Event { /// Create a new event with the given type and an empty list of attributes. #[must_use] @@ -64,6 +68,8 @@ pub struct Attribute { pub value: String, } +forward_ref_partial_eq!(Attribute, Attribute); + impl Attribute { /// Creates a new Attribute. `attr` is just an alias for this. pub fn new(key: impl Into, value: impl Into) -> Self { @@ -72,8 +78,7 @@ impl Attribute { #[cfg(debug_assertions)] if key.starts_with('_') { panic!( - "attribute key `{}` is invalid - keys starting with an underscore are reserved", - key + "attribute key `{key}` is invalid - keys starting with an underscore are reserved" ); } @@ -114,18 +119,6 @@ impl, V: AsRef> PartialEq<&Attribute> for (K, V) { } } -impl PartialEq for &Attribute { - fn eq(&self, rhs: &Attribute) -> bool { - *self == rhs - } -} - -impl PartialEq<&Attribute> for Attribute { - fn eq(&self, rhs: &&Attribute) -> bool { - self == *rhs - } -} - /// Creates a new Attribute. `Attribute::new` is an alias for this. #[inline] pub fn attr(key: impl Into, value: impl Into) -> Attribute { diff --git a/packages/std/src/results/mod.rs b/packages/std/src/results/mod.rs index 95dd1dd8e..90b887974 100644 --- a/packages/std/src/results/mod.rs +++ b/packages/std/src/results/mod.rs @@ -10,6 +10,8 @@ mod submessages; mod system_result; pub use contract_result::ContractResult; +#[cfg(all(feature = "stargate", feature = "cosmwasm_1_2"))] +pub use cosmos_msg::WeightedVoteOption; pub use cosmos_msg::{wasm_execute, wasm_instantiate, BankMsg, CosmosMsg, CustomMsg, WasmMsg}; #[cfg(feature = "staking")] pub use cosmos_msg::{DistributionMsg, StakingMsg}; diff --git a/packages/std/src/results/response.rs b/packages/std/src/results/response.rs index 60aa6513d..88f04e5c8 100644 --- a/packages/std/src/results/response.rs +++ b/packages/std/src/results/response.rs @@ -215,7 +215,7 @@ impl Response { /// ``` #[must_use] pub fn add_submessages(mut self, msgs: impl IntoIterator>) -> Self { - self.messages.extend(msgs.into_iter()); + self.messages.extend(msgs); self } @@ -224,12 +224,8 @@ impl Response { /// /// The `wasm-` prefix will be appended by the runtime to the provided types /// of events. - #[must_use] - pub fn add_events(mut self, events: impl IntoIterator) -> Self - where - S: Into, - { - self.events.extend(events.into_iter().map(|e| e.into())); + pub fn add_events(mut self, events: impl IntoIterator) -> Self { + self.events.extend(events); self } @@ -250,7 +246,7 @@ mod tests { #[test] fn response_add_attributes_works() { - let res = Response::::new().add_attributes(std::iter::empty::()); + let res = Response::::new().add_attributes(core::iter::empty::()); assert_eq!(res.attributes.len(), 0); let res = Response::::new().add_attributes([Attribute::new("test", "ing")]); @@ -272,11 +268,11 @@ mod tests { assert_eq!(res.attributes, attrs); let optional = Option::::None; - let res: Response = Response::new().add_attributes(optional.into_iter()); + let res: Response = Response::new().add_attributes(optional); assert_eq!(res.attributes.len(), 0); let optional = Option::::Some(Attribute::new("test", "ing")); - let res: Response = Response::new().add_attributes(optional.into_iter()); + let res: Response = Response::new().add_attributes(optional); assert_eq!(res.attributes.len(), 1); assert_eq!( res.attributes[0], @@ -391,7 +387,7 @@ mod tests { let event2 = Event::new("act").add_attributes(vec![attr("name", "burn"), attr("amount", "21")]); let expected = Response::::new().add_events(vec![event1, event2]); - let actual = Response::::new().add_events(vec![act1, act2]); + let actual: Response = Response::::new().add_event(act1).add_event(act2); assert_eq!(actual, expected); } diff --git a/packages/std/src/results/submessages.rs b/packages/std/src/results/submessages.rs index 792ea4eba..f854e7832 100644 --- a/packages/std/src/results/submessages.rs +++ b/packages/std/src/results/submessages.rs @@ -260,12 +260,12 @@ mod tests { let parse: StdResult = from_slice(br#"{"unrelated":321,"error":"broken"}"#); match parse.unwrap_err() { StdError::ParseErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } let parse: StdResult = from_slice(br#"{"error":"broken","unrelated":321}"#); match parse.unwrap_err() { StdError::ParseErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/packages/std/src/results/system_result.rs b/packages/std/src/results/system_result.rs index 9cc7a4858..6ad224d94 100644 --- a/packages/std/src/results/system_result.rs +++ b/packages/std/src/results/system_result.rs @@ -1,6 +1,6 @@ +use core::fmt; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::fmt; use super::super::errors::SystemError; diff --git a/packages/std/src/serde.rs b/packages/std/src/serde.rs index e58a51e6d..5b258fd1f 100644 --- a/packages/std/src/serde.rs +++ b/packages/std/src/serde.rs @@ -2,8 +2,8 @@ // The reason is two fold: // 1. To easily ensure that all calling libraries use the same version (minimize code size) // 2. To allow us to switch out to eg. serde-json-core more easily +use core::any::type_name; use serde::{de::DeserializeOwned, Serialize}; -use std::any::type_name; use crate::binary::Binary; use crate::errors::{StdError, StdResult}; diff --git a/packages/std/src/stdack.rs b/packages/std/src/stdack.rs new file mode 100644 index 000000000..e933257a0 --- /dev/null +++ b/packages/std/src/stdack.rs @@ -0,0 +1,163 @@ +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::binary::Binary; +use crate::to_binary; + +/// This is a standard IBC acknowledgement type. IBC application are free +/// to use any acknowledgement format they want. However, for compatibility +/// purposes it is recommended to use this. +/// +/// The original proto definition can be found at +/// and . +/// +/// In contrast to the original idea, [ICS-20](https://github.com/cosmos/ibc/tree/ed849c7bacf16204e9509f0f0df325391f3ce25c/spec/app/ics-020-fungible-token-transfer#technical-specification) and CosmWasm IBC protocols +/// use JSON instead of a protobuf serialization. +/// +/// For compatibility, we use the field name "result" for the success case in JSON. +/// However, all Rust APIs use the term "success" for clarity and discriminability from [Result]. +/// +/// If ibc_receive_packet returns Err(), then x/wasm runtime will rollback the state and +/// return an error message in this format. +/// +/// ## Examples +/// +/// For your convenience, there are success and error constructors. +/// +/// ``` +/// use cosmwasm_std::StdAck; +/// +/// let ack1 = StdAck::success(b"\x01"); // 0x01 is a FungibleTokenPacketSuccess from ICS-20. +/// assert!(ack1.is_success()); +/// +/// let ack2 = StdAck::error("kaputt"); // Some free text error message +/// assert!(ack2.is_error()); +/// ``` +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum StdAck { + #[serde(rename = "result")] + Success(Binary), + Error(String), +} + +impl StdAck { + /// Creates a success ack with the given data + pub fn success(data: impl Into) -> Self { + StdAck::Success(data.into()) + } + + /// Creates an error ack + pub fn error(err: impl Into) -> Self { + StdAck::Error(err.into()) + } + + #[must_use = "if you intended to assert that this is a success, consider `.unwrap()` instead"] + #[inline] + pub const fn is_success(&self) -> bool { + matches!(*self, StdAck::Success(_)) + } + + #[must_use = "if you intended to assert that this is an error, consider `.unwrap_err()` instead"] + #[inline] + pub const fn is_error(&self) -> bool { + !self.is_success() + } + + /// Serialized the ack to binary using JSON. This used for setting the acknowledgement + /// field in IbcReceiveResponse. + /// + /// ## Examples + /// + /// Show how the acknowledgement looks on the write: + /// + /// ``` + /// # use cosmwasm_std::StdAck; + /// let ack1 = StdAck::success(b"\x01"); // 0x01 is a FungibleTokenPacketSuccess from ICS-20. + /// assert_eq!(ack1.to_binary(), br#"{"result":"AQ=="}"#); + /// + /// let ack2 = StdAck::error("kaputt"); // Some free text error message + /// assert_eq!(ack2.to_binary(), br#"{"error":"kaputt"}"#); + /// ``` + /// + /// Set acknowledgement field in `IbcReceiveResponse`: + /// + /// ``` + /// use cosmwasm_std::{StdAck, IbcReceiveResponse}; + /// + /// let ack = StdAck::success(b"\x01"); // 0x01 is a FungibleTokenPacketSuccess from ICS-20. + /// + /// let res: IbcReceiveResponse = IbcReceiveResponse::new().set_ack(ack.to_binary()); + /// let res: IbcReceiveResponse = IbcReceiveResponse::new().set_ack(ack); // Does the same but consumes the instance + /// ``` + pub fn to_binary(&self) -> Binary { + // We need a non-failing StdAck -> Binary conversion to allow using StdAck in + // `impl Into` arguments. + // Pretty sure this cannot fail. If that changes we can create a non-failing implementation here. + to_binary(&self).unwrap() + } + + pub fn unwrap(self) -> Binary { + match self { + StdAck::Success(data) => data, + StdAck::Error(err) => panic!("{}", err), + } + } + + pub fn unwrap_err(self) -> String { + match self { + StdAck::Success(_) => panic!("not an error"), + StdAck::Error(err) => err, + } + } +} + +impl From for Binary { + fn from(original: StdAck) -> Binary { + original.to_binary() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn stdack_success_works() { + let success = StdAck::success(b"foo"); + match success { + StdAck::Success(data) => assert_eq!(data, b"foo"), + StdAck::Error(_err) => panic!("must not be an error"), + } + } + + #[test] + fn stdack_error_works() { + let err = StdAck::error("bar"); + match err { + StdAck::Success(_data) => panic!("must not be a success"), + StdAck::Error(err) => assert_eq!(err, "bar"), + } + } + + #[test] + fn stdack_is_success_is_error_work() { + let success = StdAck::success(b"foo"); + let err = StdAck::error("bar"); + // is_success + assert!(success.is_success()); + assert!(!err.is_success()); + // is_eror + assert!(!success.is_error()); + assert!(err.is_error()); + } + + #[test] + fn stdack_to_binary_works() { + let ack1 = StdAck::success(b"\x01"); + assert_eq!(ack1.to_binary(), br#"{"result":"AQ=="}"#); + + let ack2 = StdAck::error("kaputt"); + assert_eq!(ack2.to_binary(), br#"{"error":"kaputt"}"#); + } +} diff --git a/packages/std/src/storage.rs b/packages/std/src/storage.rs index 8615afdda..e3156dcd1 100644 --- a/packages/std/src/storage.rs +++ b/packages/std/src/storage.rs @@ -1,9 +1,9 @@ -use std::collections::BTreeMap; -use std::fmt; +use alloc::collections::BTreeMap; +use core::fmt; #[cfg(feature = "iterator")] -use std::iter; +use core::iter; #[cfg(feature = "iterator")] -use std::ops::{Bound, RangeBounds}; +use core::ops::{Bound, RangeBounds}; #[cfg(feature = "iterator")] use crate::iterator::{Order, Record}; @@ -74,11 +74,11 @@ impl fmt::Debug for MemoryStorage { for (key, value) in &self.data { f.write_str(" 0x")?; for byte in key { - write!(f, "{:02x}", byte)?; + write!(f, "{byte:02x}")?; } f.write_str(": 0x")?; for byte in value { - write!(f, "{:02x}", byte)?; + write!(f, "{byte:02x}")?; } f.write_str("\n")?; } @@ -284,7 +284,7 @@ mod tests { fn memory_storage_implements_debug() { let store = MemoryStorage::new(); assert_eq!( - format!("{:?}", store), + format!("{store:?}"), "MemoryStorage (0 entries) {\n\ }" ); @@ -293,7 +293,7 @@ mod tests { let mut store = MemoryStorage::new(); store.set(&[0x00, 0xAB, 0xDD], &[0xFF, 0xD5]); assert_eq!( - format!("{:?}", store), + format!("{store:?}"), "MemoryStorage (1 entries) {\n\ \x20\x200x00abdd: 0xffd5\n\ }" @@ -305,7 +305,7 @@ mod tests { store.set(&[0x00, 0xAB, 0xEE], &[0xFF, 0xD5]); store.set(&[0x00, 0xAB, 0xCC], &[0xFF, 0xD5]); assert_eq!( - format!("{:?}", store), + format!("{store:?}"), "MemoryStorage (3 entries) {\n\ \x20\x200x00abcc: 0xffd5\n\ \x20\x200x00abdd: 0xffd5\n\ @@ -320,7 +320,7 @@ mod tests { store.set(&[0xAA, 0xBB, 0xCC], &[0x11, 0x22, 0x33]); store.set(&[0xAA, 0xBB, 0xCC, 0xDD], &[0x11, 0x22, 0x33, 0x44]); assert_eq!( - format!("{:?}", store), + format!("{store:?}"), "MemoryStorage (4 entries) {\n\ \x20\x200xaa: 0x11\n\ \x20\x200xaabb: 0x1122\n\ diff --git a/packages/storage/src/length_prefixed.rs b/packages/std/src/storage_keys/length_prefixed.rs similarity index 65% rename from packages/storage/src/length_prefixed.rs rename to packages/std/src/storage_keys/length_prefixed.rs index 5d97b3b41..9e95f17f0 100644 --- a/packages/storage/src/length_prefixed.rs +++ b/packages/std/src/storage_keys/length_prefixed.rs @@ -6,38 +6,61 @@ /// Calculates the raw key prefix for a given namespace as documented /// in https://github.com/webmaster128/key-namespacing#length-prefixed-keys -pub fn to_length_prefixed(namespace: &[u8]) -> Vec { - let mut out = Vec::with_capacity(namespace.len() + 2); - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); +pub fn to_length_prefixed(namespace_component: &[u8]) -> Vec { + let mut out = Vec::with_capacity(namespace_component.len() + 2); + out.extend_from_slice(&encode_length(namespace_component)); + out.extend_from_slice(namespace_component); out } /// Calculates the raw key prefix for a given nested namespace /// as documented in https://github.com/webmaster128/key-namespacing#nesting -pub fn to_length_prefixed_nested(namespaces: &[&[u8]]) -> Vec { +pub fn to_length_prefixed_nested(namespace: &[&[u8]]) -> Vec { let mut size = 0; - for &namespace in namespaces { - size += namespace.len() + 2; + for component in namespace { + size += component.len() + 2; } let mut out = Vec::with_capacity(size); - for &namespace in namespaces { - out.extend_from_slice(&encode_length(namespace)); - out.extend_from_slice(namespace); + for component in namespace { + out.extend_from_slice(&encode_length(component)); + out.extend_from_slice(component); } out } -/// Encodes the length of a given namespace as a 2 byte big endian encoded integer -fn encode_length(namespace: &[u8]) -> [u8; 2] { - if namespace.len() > 0xFFFF { - panic!("only supports namespaces up to length 0xFFFF") +/// Encodes the length of a given namespace component +/// as a 2 byte big endian encoded integer +fn encode_length(namespace_component: &[u8]) -> [u8; 2] { + if namespace_component.len() > 0xFFFF { + panic!("only supports namespace components up to length 0xFFFF") } - let length_bytes = (namespace.len() as u32).to_be_bytes(); + let length_bytes = (namespace_component.len() as u32).to_be_bytes(); [length_bytes[2], length_bytes[3]] } +/// Encodes a namespace + key to a raw storage key. +/// +/// This is equivalent concat(to_length_prefixed_nested(namespace), key) +/// but more efficient when the namespace serialization is not persisted because +/// here we only need one vector allocation. +pub fn namespace_with_key(namespace: &[&[u8]], key: &[u8]) -> Vec { + // As documented in docs/STORAGE_KEYS.md, we know the final size of the key, + // which allows us to avoid reallocations of vectors. + let mut size = key.len(); + for component in namespace { + size += 2 /* encoded component length */ + component.len() /* the actual component data */; + } + + let mut out = Vec::with_capacity(size); + for component in namespace { + out.extend_from_slice(&encode_length(component)); + out.extend_from_slice(component); + } + out.extend_from_slice(key); + out +} + #[cfg(test)] mod tests { use super::*; @@ -69,7 +92,7 @@ mod tests { } #[test] - #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] + #[should_panic(expected = "only supports namespace components up to length 0xFFFF")] fn to_length_prefixed_panics_for_too_long_prefix() { let limit = 0xFFFF; let long_namespace = vec![0; limit + 1]; @@ -108,6 +131,15 @@ mod tests { ); } + #[test] + fn to_length_prefixed_nested_returns_the_same_as_to_length_prefixed_for_one_element() { + let tests = [b"" as &[u8], b"x" as &[u8], b"abababab" as &[u8]]; + + for test in tests { + assert_eq!(to_length_prefixed_nested(&[test]), to_length_prefixed(test)); + } + } + #[test] fn to_length_prefixed_nested_allows_many_long_namespaces() { // The 0xFFFF limit is for each namespace, not for the combination of them @@ -169,8 +201,29 @@ mod tests { } #[test] - #[should_panic(expected = "only supports namespaces up to length 0xFFFF")] + #[should_panic(expected = "only supports namespace components up to length 0xFFFF")] fn encode_length_panics_for_large_values() { encode_length(&vec![1; 65536]); } + + #[test] + fn namespace_with_key_works() { + // Empty namespace + let enc = namespace_with_key(&[], b"foo"); + assert_eq!(enc, b"foo"); + let enc = namespace_with_key(&[], b""); + assert_eq!(enc, b""); + + // One component namespace + let enc = namespace_with_key(&[b"bar"], b"foo"); + assert_eq!(enc, b"\x00\x03barfoo"); + let enc = namespace_with_key(&[b"bar"], b""); + assert_eq!(enc, b"\x00\x03bar"); + + // Multi component namespace + let enc = namespace_with_key(&[b"bar", b"cool"], b"foo"); + assert_eq!(enc, b"\x00\x03bar\x00\x04coolfoo"); + let enc = namespace_with_key(&[b"bar", b"cool"], b""); + assert_eq!(enc, b"\x00\x03bar\x00\x04cool"); + } } diff --git a/packages/std/src/storage_keys/mod.rs b/packages/std/src/storage_keys/mod.rs new file mode 100644 index 000000000..630feaa18 --- /dev/null +++ b/packages/std/src/storage_keys/mod.rs @@ -0,0 +1,5 @@ +mod length_prefixed; + +// Please note that the entire storage_keys module is public. So be careful +// when adding elements here. +pub use length_prefixed::{namespace_with_key, to_length_prefixed, to_length_prefixed_nested}; diff --git a/packages/std/src/testing/assertions.rs b/packages/std/src/testing/assertions.rs index 3d5cf0a2d..d74736007 100644 --- a/packages/std/src/testing/assertions.rs +++ b/packages/std/src/testing/assertions.rs @@ -1,5 +1,7 @@ use crate::{Decimal, Uint128}; -use std::str::FromStr as _; +#[cfg(test)] +use core::hash::{Hash, Hasher}; +use core::str::FromStr as _; /// Asserts that two expressions are approximately equal to each other. /// @@ -21,6 +23,25 @@ macro_rules! assert_approx_eq { }}; } +/// Tests that type `T` implements `Eq` and `Hash` traits correctly. +/// +/// `left` and `right` must be unequal objects. +/// +/// Some object pairs may produce the same hash causing test failure. +/// In those cases try different objects. The test uses stable hasher +/// so once working pair is identified, the test’s going to continue +/// passing. +#[macro_export] +#[cfg(test)] +macro_rules! assert_hash_works { + ($left:expr, $right:expr $(,)?) => {{ + $crate::testing::assert_hash_works_impl($left, $right, None); + }}; + ($left:expr, $right:expr, $($args:tt)+) => {{ + $crate::testing::assert_hash_works_impl($left, $right, Some(format!($($args)*))); + }}; +} + /// Implementation for the [`cosmwasm_std::assert_approx_eq`] macro. This does not provide any /// stability guarantees and may change any time. #[track_caller] @@ -35,20 +56,61 @@ pub fn assert_approx_eq_impl>( let right = right.into(); let max_rel_diff = Decimal::from_str(max_rel_diff).unwrap(); - let largest = std::cmp::max(left, right); + let largest = core::cmp::max(left, right); let rel_diff = Decimal::from_ratio(left.abs_diff(right), largest); if rel_diff > max_rel_diff { - match panic_msg { - Some(panic_msg) => panic!( - "assertion failed: `(left ≈ right)`\nleft: {}\nright: {}\nrelative difference: {}\nmax allowed relative difference: {}\n: {}", - left, right, rel_diff, max_rel_diff, panic_msg - ), - None => panic!( - "assertion failed: `(left ≈ right)`\nleft: {}\nright: {}\nrelative difference: {}\nmax allowed relative difference: {}\n", - left, right, rel_diff, max_rel_diff - ), - } + do_panic(format_args!("assertion failed: `(left ≈ right)`\nleft: {left}\nright: {right}\nrelative difference: {rel_diff}\nmax allowed relative difference: {max_rel_diff}"), panic_msg); + } +} + +/// Tests that type `T` implements `Eq` and `Hash` traits correctly. +/// +/// `left` and `right` must be unequal objects. +/// +/// Some object pairs may produce the same hash causing test failure. In those +/// cases try different objects. The test uses stable hasher so once working +/// pair is identified, the test’s going to continue passing. +#[track_caller] +#[doc(hidden)] +#[cfg(test)] +pub fn assert_hash_works_impl(left: T, right: T, panic_msg: Option) { + fn hash(value: &impl Hash) -> u64 { + let mut hasher = crc32fast::Hasher::default(); + value.hash(&mut hasher); + hasher.finish() + } + + // Check clone + let clone = left.clone(); + if left != clone { + do_panic("assertion failed: `left == left.clone()`", panic_msg); + } + if hash(&left) != hash(&clone) { + do_panic( + "assertion failed: `hash(left) == hash(left.clone())`", + panic_msg, + ); + } + + // Check different object + if left == right { + do_panic("assertion failed: `left != right`", panic_msg); + } + if hash(&left) == hash(&right) { + do_panic("assertion failed: `hash(left) != hash(right)`", panic_msg); + } +} + +/// Panics concatenating both arguments. +/// +/// If second argument is `None` panics with just the first argument as message. +/// Otherwise, formats the panic message as `{reason}:\n{panic_msg}`. +#[track_caller] +fn do_panic(reason: impl core::fmt::Display, panic_msg: Option) -> ! { + match panic_msg { + Some(panic_msg) => panic!("{reason}:\n{panic_msg}"), + None => panic!("{reason}"), } } @@ -82,7 +144,7 @@ mod tests { #[test] #[should_panic( - expected = "assertion failed: `(left ≈ right)`\nleft: 8\nright: 10\nrelative difference: 0.2\nmax allowed relative difference: 0.12\n" + expected = "assertion failed: `(left ≈ right)`\nleft: 8\nright: 10\nrelative difference: 0.2\nmax allowed relative difference: 0.12" )] fn assert_approx_fail() { assert_approx_eq!(8_u32, 10_u32, "0.12"); @@ -90,7 +152,7 @@ mod tests { #[test] #[should_panic( - expected = "assertion failed: `(left ≈ right)`\nleft: 17\nright: 20\nrelative difference: 0.15\nmax allowed relative difference: 0.12\n: some extra info about the error: Foo(8)" + expected = "assertion failed: `(left ≈ right)`\nleft: 17\nright: 20\nrelative difference: 0.15\nmax allowed relative difference: 0.12:\nsome extra info about the error: Foo(8)" )] fn assert_approx_with_custom_panic_msg() { let adjective = "extra"; diff --git a/packages/std/src/testing/mock.rs b/packages/std/src/testing/mock.rs index 350c16927..f7cec5430 100644 --- a/packages/std/src/testing/mock.rs +++ b/packages/std/src/testing/mock.rs @@ -1,8 +1,13 @@ +use alloc::collections::BTreeMap; +use core::marker::PhantomData; +#[cfg(feature = "cosmwasm_1_3")] +use core::ops::Bound; use serde::de::DeserializeOwned; #[cfg(feature = "stargate")] use serde::Serialize; +#[cfg(feature = "cosmwasm_1_3")] +use std::collections::BTreeSet; use std::collections::HashMap; -use std::marker::PhantomData; use crate::addresses::{Addr, CanonicalAddr}; use crate::binary::Binary; @@ -28,13 +33,26 @@ use crate::query::{ AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse, }; +#[cfg(feature = "cosmwasm_1_3")] +use crate::query::{DelegatorWithdrawAddressResponse, DistributionQuery}; use crate::results::{ContractResult, Empty, SystemResult}; use crate::serde::{from_slice, to_binary}; use crate::storage::MemoryStorage; use crate::timestamp::Timestamp; use crate::traits::{Api, Querier, QuerierResult}; use crate::types::{BlockInfo, ContractInfo, Env, MessageInfo, TransactionInfo}; -use crate::Attribute; +#[cfg(feature = "cosmwasm_1_3")] +use crate::{ + query::{AllDenomMetadataResponse, DecCoin, DenomMetadataResponse}, + PageRequest, +}; +use crate::{Attribute, DenomMetadata}; +#[cfg(feature = "stargate")] +use crate::{ChannelResponse, IbcQuery, ListChannelsResponse, PortIdResponse}; +#[cfg(feature = "cosmwasm_1_4")] +use crate::{Decimal256, DelegationRewardsResponse, DelegatorValidatorsResponse}; + +use super::riffle_shuffle; pub const MOCK_CONTRACT_ADDR: &str = "cosmos2contract"; @@ -77,12 +95,17 @@ pub fn mock_dependencies_with_balances( // We can later make simplifications here if needed pub type MockStorage = MemoryStorage; -/// Length of canonical addresses created with this API. Contracts should not make any assumtions +/// Length of canonical addresses created with this API. Contracts should not make any assumptions /// what this value is. +/// +/// The mock API can only canonicalize and humanize addresses up to this length. So it must be +/// long enough to store common bech32 addresses. +/// /// The value here must be restorable with `SHUFFLES_ENCODE` + `SHUFFLES_DECODE` in-shuffles. -const CANONICAL_LENGTH: usize = 54; +/// See for a table of those values. +const CANONICAL_LENGTH: usize = 90; // n = 45 -const SHUFFLES_ENCODE: usize = 18; +const SHUFFLES_ENCODE: usize = 10; const SHUFFLES_DECODE: usize = 2; // MockPrecompiles zero pads all human addresses to make them fit the canonical_length @@ -90,7 +113,7 @@ const SHUFFLES_DECODE: usize = 2; // not really smart, but allows us to see a difference (and consistent length for canonical adddresses) #[derive(Copy, Clone)] pub struct MockApi { - /// Length of canonical addresses created with this API. Contracts should not make any assumtions + /// Length of canonical addresses created with this API. Contracts should not make any assumptions /// what this value is. canonical_length: usize, } @@ -118,14 +141,16 @@ impl Api for MockApi { fn addr_canonicalize(&self, input: &str) -> StdResult { // Dummy input validation. This is more sophisticated for formats like bech32, where format and checksum are validated. - if input.len() < 3 { + let min_length = 3; + let max_length = self.canonical_length; + if input.len() < min_length { return Err(StdError::generic_err( - "Invalid input: human address too short", + format!("Invalid input: human address too short for this mock implementation (must be >= {min_length})."), )); } - if input.len() > self.canonical_length { + if input.len() > max_length { return Err(StdError::generic_err( - "Invalid input: human address too long", + format!("Invalid input: human address too long for this mock implementation (must be <= {max_length})."), )); } @@ -221,7 +246,7 @@ impl Api for MockApi { } fn debug(&self, message: &str) { - println!("{}", message); + println!("{message}"); } } @@ -431,7 +456,11 @@ pub struct MockQuerier { bank: BankQuerier, #[cfg(feature = "staking")] staking: StakingQuerier, + #[cfg(feature = "cosmwasm_1_3")] + distribution: DistributionQuerier, wasm: WasmQuerier, + #[cfg(feature = "stargate")] + ibc: IbcQuerier, /// A handler to handle custom queries. This is set to a dummy handler that /// always errors by default. Update it via `with_custom_handler`. /// @@ -443,9 +472,13 @@ impl MockQuerier { pub fn new(balances: &[(&str, &[Coin])]) -> Self { MockQuerier { bank: BankQuerier::new(balances), + #[cfg(feature = "cosmwasm_1_3")] + distribution: DistributionQuerier::default(), #[cfg(feature = "staking")] staking: StakingQuerier::default(), wasm: WasmQuerier::default(), + #[cfg(feature = "stargate")] + ibc: IbcQuerier::default(), // strange argument notation suggested as a workaround here: https://github.com/rust-lang/rust/issues/41078#issuecomment-294296365 custom_handler: Box::from(|_: &_| -> MockQuerierCustomHandlerResult { SystemResult::Err(SystemError::UnsupportedRequest { @@ -464,6 +497,37 @@ impl MockQuerier { self.bank.update_balance(addr, balance) } + pub fn set_denom_metadata(&mut self, denom_metadata: &[DenomMetadata]) { + self.bank.set_denom_metadata(denom_metadata); + } + + #[cfg(feature = "cosmwasm_1_3")] + pub fn set_withdraw_address( + &mut self, + delegator_address: impl Into, + withdraw_address: impl Into, + ) { + self.distribution + .set_withdraw_address(delegator_address, withdraw_address); + } + + /// Sets multiple withdraw addresses. + /// + /// This allows passing multiple tuples of `(delegator_address, withdraw_address)`. + /// It does not overwrite existing entries. + #[cfg(feature = "cosmwasm_1_3")] + pub fn set_withdraw_addresses( + &mut self, + withdraw_addresses: impl IntoIterator, impl Into)>, + ) { + self.distribution.set_withdraw_addresses(withdraw_addresses); + } + + #[cfg(feature = "cosmwasm_1_3")] + pub fn clear_withdraw_addresses(&mut self) { + self.distribution.clear_withdraw_addresses(); + } + #[cfg(feature = "staking")] pub fn update_staking( &mut self, @@ -474,6 +538,11 @@ impl MockQuerier { self.staking = StakingQuerier::new(denom, validators, delegations); } + #[cfg(feature = "stargate")] + pub fn update_ibc(&mut self, port_id: &str, channels: &[IbcChannel]) { + self.ibc = IbcQuerier::new(port_id, channels); + } + pub fn update_wasm(&mut self, handler: WH) where WH: Fn(&WasmQuery) -> QuerierResult, @@ -503,7 +572,7 @@ impl Querier for MockQuerier { Ok(v) => v, Err(e) => { return SystemResult::Err(SystemError::InvalidRequest { - error: format!("Parsing query request: {}", e), + error: format!("Parsing query request: {e}"), request: bin_request.into(), }) } @@ -519,15 +588,17 @@ impl MockQuerier { QueryRequest::Custom(custom_query) => (*self.custom_handler)(custom_query), #[cfg(feature = "staking")] QueryRequest::Staking(staking_query) => self.staking.query(staking_query), + #[cfg(feature = "cosmwasm_1_3")] + QueryRequest::Distribution(distribution_query) => { + self.distribution.query(distribution_query) + } QueryRequest::Wasm(msg) => self.wasm.query(msg), #[cfg(feature = "stargate")] QueryRequest::Stargate { .. } => SystemResult::Err(SystemError::UnsupportedRequest { kind: "Stargate".to_string(), }), #[cfg(feature = "stargate")] - QueryRequest::Ibc(_) => SystemResult::Err(SystemError::UnsupportedRequest { - kind: "Ibc".to_string(), - }), + QueryRequest::Ibc(msg) => self.ibc.query(msg), } } } @@ -560,13 +631,22 @@ impl WasmQuerier { impl Default for WasmQuerier { fn default() -> Self { let handler = Box::from(|request: &WasmQuery| -> QuerierResult { - let addr = match request { - WasmQuery::Smart { contract_addr, .. } => contract_addr, - WasmQuery::Raw { contract_addr, .. } => contract_addr, - WasmQuery::ContractInfo { contract_addr, .. } => contract_addr, - } - .clone(); - SystemResult::Err(SystemError::NoSuchContract { addr }) + let err = match request { + WasmQuery::Smart { contract_addr, .. } => SystemError::NoSuchContract { + addr: contract_addr.clone(), + }, + WasmQuery::Raw { contract_addr, .. } => SystemError::NoSuchContract { + addr: contract_addr.clone(), + }, + WasmQuery::ContractInfo { contract_addr, .. } => SystemError::NoSuchContract { + addr: contract_addr.clone(), + }, + #[cfg(feature = "cosmwasm_1_2")] + WasmQuery::CodeInfo { code_id, .. } => { + SystemError::NoSuchCode { code_id: *code_id } + } + }; + SystemResult::Err(err) }); Self::new(handler) } @@ -579,6 +659,8 @@ pub struct BankQuerier { supplies: HashMap, /// HashMap balances: HashMap>, + /// Vec + denom_metadata: BTreeMap, DenomMetadata>, } impl BankQuerier { @@ -591,6 +673,7 @@ impl BankQuerier { BankQuerier { supplies: Self::calculate_supplies(&balances), balances, + denom_metadata: BTreeMap::new(), } } @@ -605,6 +688,13 @@ impl BankQuerier { result } + pub fn set_denom_metadata(&mut self, denom_metadata: &[DenomMetadata]) { + self.denom_metadata = denom_metadata + .iter() + .map(|d| (d.base.as_bytes().to_vec(), d.clone())) + .collect(); + } + fn calculate_supplies(balances: &HashMap>) -> HashMap { let mut supplies = HashMap::new(); @@ -658,6 +748,123 @@ impl BankQuerier { }; to_binary(&bank_res).into() } + #[cfg(feature = "cosmwasm_1_3")] + BankQuery::DenomMetadata { denom } => { + let denom_metadata = self.denom_metadata.get(denom.as_bytes()); + match denom_metadata { + Some(m) => { + let metadata_res = DenomMetadataResponse { + metadata: m.clone(), + }; + to_binary(&metadata_res).into() + } + None => return SystemResult::Err(SystemError::Unknown {}), + } + } + #[cfg(feature = "cosmwasm_1_3")] + BankQuery::AllDenomMetadata { pagination } => { + let default_pagination = PageRequest { + key: None, + limit: 100, + reverse: false, + }; + let pagination = pagination.as_ref().unwrap_or(&default_pagination); + + // range of all denoms after the given key (or until the key for reverse) + let range = match (pagination.reverse, &pagination.key) { + (_, None) => (Bound::Unbounded, Bound::Unbounded), + (true, Some(key)) => (Bound::Unbounded, Bound::Included(key.as_slice())), + (false, Some(key)) => (Bound::Included(key.as_slice()), Bound::Unbounded), + }; + let iter = self.denom_metadata.range::<[u8], _>(range); + // using dynamic dispatch here to reduce code duplication and since this is only testing code + let iter: Box> = if pagination.reverse { + Box::new(iter.rev()) + } else { + Box::new(iter) + }; + + let mut metadata: Vec<_> = iter + // take the requested amount + 1 to get the next key + .take((pagination.limit.saturating_add(1)) as usize) + .map(|(_, m)| m.clone()) + .collect(); + + // if we took more than requested, remove the last element (the next key), + // otherwise this is the last batch + let next_key = if metadata.len() > pagination.limit as usize { + metadata.pop().map(|m| Binary::from(m.base.as_bytes())) + } else { + None + }; + + let metadata_res = AllDenomMetadataResponse { metadata, next_key }; + to_binary(&metadata_res).into() + } + }; + // system result is always ok in the mock implementation + SystemResult::Ok(contract_result) + } +} + +#[cfg(feature = "stargate")] +#[derive(Clone, Default)] +pub struct IbcQuerier { + port_id: String, + channels: Vec, +} + +#[cfg(feature = "stargate")] +impl IbcQuerier { + /// Create a mock querier where: + /// - port_id is the port the "contract" is bound to + /// - channels are a list of ibc channels + pub fn new(port_id: &str, channels: &[IbcChannel]) -> Self { + IbcQuerier { + port_id: port_id.to_string(), + channels: channels.to_vec(), + } + } + + pub fn query(&self, request: &IbcQuery) -> QuerierResult { + let contract_result: ContractResult = match request { + IbcQuery::Channel { + channel_id, + port_id, + } => { + let channel = self + .channels + .iter() + .find(|c| match port_id { + Some(p) => c.endpoint.channel_id.eq(channel_id) && c.endpoint.port_id.eq(p), + None => { + c.endpoint.channel_id.eq(channel_id) + && c.endpoint.port_id == self.port_id + } + }) + .cloned(); + let res = ChannelResponse { channel }; + to_binary(&res).into() + } + IbcQuery::ListChannels { port_id } => { + let channels = self + .channels + .iter() + .filter(|c| match port_id { + Some(p) => c.endpoint.port_id.eq(p), + None => c.endpoint.port_id == self.port_id, + }) + .cloned() + .collect(); + let res = ListChannelsResponse { channels }; + to_binary(&res).into() + } + IbcQuery::PortId {} => { + let res = PortIdResponse { + port_id: self.port_id.clone(), + }; + to_binary(&res).into() + } }; // system result is always ok in the mock implementation SystemResult::Ok(contract_result) @@ -735,66 +942,160 @@ impl StakingQuerier { } } -/// Performs a perfect shuffle (in shuffle) -/// -/// https://en.wikipedia.org/wiki/Riffle_shuffle_permutation#Perfect_shuffles -/// https://en.wikipedia.org/wiki/In_shuffle -/// -/// The number of shuffles required to restore the original order are listed in -/// https://oeis.org/A002326, e.g.: -/// -/// ```ignore -/// 2: 2 -/// 4: 4 -/// 6: 3 -/// 8: 6 -/// 10: 10 -/// 12: 12 -/// 14: 4 -/// 16: 8 -/// 18: 18 -/// 20: 6 -/// 22: 11 -/// 24: 20 -/// 26: 18 -/// 28: 28 -/// 30: 5 -/// 32: 10 -/// 34: 12 -/// 36: 36 -/// 38: 12 -/// 40: 20 -/// 42: 14 -/// 44: 12 -/// 46: 23 -/// 48: 21 -/// 50: 8 -/// 52: 52 -/// 54: 20 -/// 56: 18 -/// 58: 58 -/// 60: 60 -/// 62: 6 -/// 64: 12 -/// 66: 66 -/// 68: 22 -/// 70: 35 -/// 72: 9 -/// 74: 20 -/// ``` -pub fn riffle_shuffle(input: &[T]) -> Vec { - assert!( - input.len() % 2 == 0, - "Method only defined for even number of elements" - ); - let mid = input.len() / 2; - let (left, right) = input.split_at(mid); - let mut out = Vec::::with_capacity(input.len()); - for i in 0..mid { - out.push(right[i].clone()); - out.push(left[i].clone()); - } - out +#[cfg(feature = "cosmwasm_1_3")] +#[derive(Clone, Default)] +pub struct DistributionQuerier { + withdraw_addresses: HashMap, + /// Mock of accumulated rewards, indexed first by delegator and then validator address. + rewards: BTreeMap>>, + /// Mock of validators that a delegator has bonded to. + validators: BTreeMap>, +} + +#[cfg(feature = "cosmwasm_1_3")] +impl DistributionQuerier { + pub fn new(withdraw_addresses: HashMap) -> Self { + DistributionQuerier { + withdraw_addresses, + ..Default::default() + } + } + + pub fn set_withdraw_address( + &mut self, + delegator_address: impl Into, + withdraw_address: impl Into, + ) { + self.withdraw_addresses + .insert(delegator_address.into(), withdraw_address.into()); + } + + /// Sets multiple withdraw addresses. + /// + /// This allows passing multiple tuples of `(delegator_address, withdraw_address)`. + /// It does not overwrite existing entries. + pub fn set_withdraw_addresses( + &mut self, + withdraw_addresses: impl IntoIterator, impl Into)>, + ) { + for (d, w) in withdraw_addresses { + self.set_withdraw_address(d, w); + } + } + + pub fn clear_withdraw_addresses(&mut self) { + self.withdraw_addresses.clear(); + } + + /// Sets accumulated rewards for a given validator and delegator pair. + pub fn set_rewards( + &mut self, + validator: impl Into, + delegator: impl Into, + rewards: Vec, + ) { + self.rewards + .entry(delegator.into()) + .or_default() + .insert(validator.into(), rewards); + } + + /// Sets the validators a given delegator has bonded to. + pub fn set_validators( + &mut self, + delegator: impl Into, + validators: impl IntoIterator>, + ) { + self.validators.insert( + delegator.into(), + validators.into_iter().map(Into::into).collect(), + ); + } + + pub fn query(&self, request: &DistributionQuery) -> QuerierResult { + let contract_result: ContractResult = match request { + DistributionQuery::DelegatorWithdrawAddress { delegator_address } => { + let res = DelegatorWithdrawAddressResponse { + withdraw_address: Addr::unchecked( + self.withdraw_addresses + .get(delegator_address) + .unwrap_or(delegator_address), + ), + }; + to_binary(&res).into() + } + #[cfg(feature = "cosmwasm_1_4")] + DistributionQuery::DelegationRewards { + delegator_address, + validator_address, + } => { + let res = DelegationRewardsResponse { + rewards: self + .rewards + .get(delegator_address) + .and_then(|v| v.get(validator_address)) + .cloned() + .unwrap_or_default(), + }; + to_binary(&res).into() + } + #[cfg(feature = "cosmwasm_1_4")] + DistributionQuery::DelegationTotalRewards { delegator_address } => { + let validator_rewards = self + .validator_rewards(delegator_address) + .unwrap_or_default(); + let res = crate::DelegationTotalRewardsResponse { + total: validator_rewards + .iter() + .fold(BTreeMap::<&str, DecCoin>::new(), |mut acc, rewards| { + for coin in &rewards.reward { + acc.entry(&coin.denom) + .or_insert_with(|| DecCoin { + denom: coin.denom.clone(), + amount: Decimal256::zero(), + }) + .amount += coin.amount; + } + + acc + }) + .into_values() + .collect(), + rewards: validator_rewards, + }; + to_binary(&res).into() + } + #[cfg(feature = "cosmwasm_1_4")] + DistributionQuery::DelegatorValidators { delegator_address } => { + let res = DelegatorValidatorsResponse { + validators: self + .validators + .get(delegator_address) + .map(|set| set.iter().cloned().collect()) + .unwrap_or_default(), + }; + to_binary(&res).into() + } + }; + // system result is always ok in the mock implementation + SystemResult::Ok(contract_result) + } + + /// Helper method to get all rewards for a given delegator. + #[cfg(feature = "cosmwasm_1_4")] + fn validator_rewards(&self, delegator_address: &str) -> Option> { + let validator_rewards = self.rewards.get(delegator_address)?; + + Some( + validator_rewards + .iter() + .map(|(validator, rewards)| crate::DelegatorReward { + validator_address: validator.clone(), + reward: rewards.clone(), + }) + .collect(), + ) + } } pub fn digit_sum(input: &[u8]) -> usize { @@ -813,6 +1114,8 @@ pub fn mock_wasmd_attr(key: impl Into, value: impl Into) -> Attr #[cfg(test)] mod tests { use super::*; + #[cfg(feature = "cosmwasm_1_3")] + use crate::DenomUnit; use crate::{coin, coins, from_binary, to_binary, ContractInfoResponse, Response}; #[cfg(feature = "staking")] use crate::{Decimal, Delegation}; @@ -886,23 +1189,34 @@ mod tests { let canonical = api.addr_canonicalize(&original).unwrap(); let recovered = api.addr_humanize(&canonical).unwrap(); assert_eq!(recovered, "cosmwasmchef"); + + // Long input (Juno contract address) + let original = + String::from("juno1v82su97skv6ucfqvuvswe0t5fph7pfsrtraxf0x33d8ylj5qnrysdvkc95"); + let canonical = api.addr_canonicalize(&original).unwrap(); + let recovered = api.addr_humanize(&canonical).unwrap(); + assert_eq!(recovered, original); } #[test] - #[should_panic(expected = "address too short")] fn addr_canonicalize_min_input_length() { let api = MockApi::default(); let human = String::from("1"); - let _ = api.addr_canonicalize(&human).unwrap(); + let err = api.addr_canonicalize(&human).unwrap_err(); + assert!(err + .to_string() + .contains("human address too short for this mock implementation (must be >= 3)")); } #[test] - #[should_panic(expected = "address too long")] fn addr_canonicalize_max_input_length() { let api = MockApi::default(); let human = - String::from("some-extremely-long-address-not-supported-by-this-api-longer-than-54"); - let _ = api.addr_canonicalize(&human).unwrap(); + String::from("some-extremely-long-address-not-supported-by-this-api-longer-than-supported------------------------"); + let err = api.addr_canonicalize(&human).unwrap_err(); + assert!(err + .to_string() + .contains("human address too long for this mock implementation (must be <= 90)")); } #[test] @@ -991,7 +1305,7 @@ mod tests { let result = api.secp256k1_recover_pubkey(&hash, &signature, 42); match result.unwrap_err() { RecoverPubkeyError::InvalidRecoveryParam => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -1020,7 +1334,7 @@ mod tests { let result = api.secp256k1_recover_pubkey(&malformed_hash, &signature, recovery_param); match result.unwrap_err() { RecoverPubkeyError::InvalidHashFormat => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -1229,6 +1543,329 @@ mod tests { assert_eq!(res.amount, coin(0, "ELF")); } + #[cfg(feature = "cosmwasm_1_3")] + #[test] + fn bank_querier_metadata_works() { + let mut bank = BankQuerier::new(&[]); + bank.set_denom_metadata( + &(0..100) + .map(|i| DenomMetadata { + symbol: format!("FOO{i}"), + name: "Foo".to_string(), + description: "Foo coin".to_string(), + denom_units: vec![DenomUnit { + denom: "ufoo".to_string(), + exponent: 8, + aliases: vec!["microfoo".to_string(), "foobar".to_string()], + }], + display: "FOO".to_string(), + base: format!("ufoo{i}"), + uri: "https://foo.bar".to_string(), + uri_hash: "foo".to_string(), + }) + .collect::>(), + ); + + // querying first 10 should work + let res = bank + .query(&BankQuery::AllDenomMetadata { + pagination: Some(PageRequest { + key: None, + limit: 10, + reverse: false, + }), + }) + .unwrap() + .unwrap(); + let res: AllDenomMetadataResponse = from_binary(&res).unwrap(); + assert_eq!(res.metadata.len(), 10); + assert!(res.next_key.is_some()); + + // querying next 10 should also work + let res2 = bank + .query(&BankQuery::AllDenomMetadata { + pagination: Some(PageRequest { + key: res.next_key, + limit: 10, + reverse: false, + }), + }) + .unwrap() + .unwrap(); + let res2: AllDenomMetadataResponse = from_binary(&res2).unwrap(); + assert_eq!(res2.metadata.len(), 10); + assert_ne!(res.metadata.last(), res2.metadata.first()); + // should have no overlap + for m in res.metadata { + assert!(!res2.metadata.contains(&m)); + } + + // querying all 100 should work + let res = bank + .query(&BankQuery::AllDenomMetadata { + pagination: Some(PageRequest { + key: None, + limit: 100, + reverse: true, + }), + }) + .unwrap() + .unwrap(); + let res: AllDenomMetadataResponse = from_binary(&res).unwrap(); + assert_eq!(res.metadata.len(), 100); + assert!(res.next_key.is_none(), "no more data should be available"); + assert_eq!(res.metadata[0].symbol, "FOO99", "should have been reversed"); + + let more_res = bank + .query(&BankQuery::AllDenomMetadata { + pagination: Some(PageRequest { + key: res.next_key, + limit: u32::MAX, + reverse: true, + }), + }) + .unwrap() + .unwrap(); + let more_res: AllDenomMetadataResponse = from_binary(&more_res).unwrap(); + assert_eq!( + more_res.metadata, res.metadata, + "should be same as previous query" + ); + } + + #[cfg(feature = "cosmwasm_1_3")] + #[test] + fn distribution_querier_delegator_withdraw_address() { + let mut distribution = DistributionQuerier::default(); + distribution.set_withdraw_address("addr0", "withdraw0"); + + let query = DistributionQuery::DelegatorWithdrawAddress { + delegator_address: "addr0".to_string(), + }; + + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegatorWithdrawAddressResponse = from_binary(&res).unwrap(); + assert_eq!(res.withdraw_address, "withdraw0"); + + let query = DistributionQuery::DelegatorWithdrawAddress { + delegator_address: "addr1".to_string(), + }; + + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegatorWithdrawAddressResponse = from_binary(&res).unwrap(); + assert_eq!(res.withdraw_address, "addr1"); + } + + #[cfg(feature = "cosmwasm_1_4")] + #[test] + fn distribution_querier_delegator_validators() { + let mut distribution = DistributionQuerier::default(); + distribution.set_validators("addr0", ["valoper1", "valoper2"]); + + let query = DistributionQuery::DelegatorValidators { + delegator_address: "addr0".to_string(), + }; + + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegatorValidatorsResponse = from_binary(&res).unwrap(); + assert_eq!(res.validators, ["valoper1", "valoper2"]); + + let query = DistributionQuery::DelegatorValidators { + delegator_address: "addr1".to_string(), + }; + + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegatorValidatorsResponse = from_binary(&res).unwrap(); + assert_eq!(res.validators, ([] as [String; 0])); + } + + #[cfg(feature = "cosmwasm_1_4")] + #[test] + fn distribution_querier_delegation_rewards() { + use crate::{Decimal256, DelegationTotalRewardsResponse, DelegatorReward}; + + let mut distribution = DistributionQuerier::default(); + let valoper0_rewards = vec![ + DecCoin::new(Decimal256::from_atomics(1234u128, 0).unwrap(), "uatom"), + DecCoin::new(Decimal256::from_atomics(56781234u128, 4).unwrap(), "utest"), + ]; + distribution.set_rewards("valoper0", "addr0", valoper0_rewards.clone()); + + // both exist / are set + let query = DistributionQuery::DelegationRewards { + delegator_address: "addr0".to_string(), + validator_address: "valoper0".to_string(), + }; + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegationRewardsResponse = from_binary(&res).unwrap(); + assert_eq!(res.rewards, valoper0_rewards); + + // delegator does not exist + let query = DistributionQuery::DelegationRewards { + delegator_address: "nonexistent".to_string(), + validator_address: "valoper0".to_string(), + }; + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegationRewardsResponse = from_binary(&res).unwrap(); + assert_eq!(res.rewards.len(), 0); + + // validator does not exist + let query = DistributionQuery::DelegationRewards { + delegator_address: "addr0".to_string(), + validator_address: "valopernonexistent".to_string(), + }; + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegationRewardsResponse = from_binary(&res).unwrap(); + assert_eq!(res.rewards.len(), 0); + + // add one more validator + let valoper1_rewards = vec![DecCoin::new(Decimal256::one(), "uatom")]; + distribution.set_rewards("valoper1", "addr0", valoper1_rewards.clone()); + + // total rewards + let query = DistributionQuery::DelegationTotalRewards { + delegator_address: "addr0".to_string(), + }; + let res = distribution.query(&query).unwrap().unwrap(); + let res: DelegationTotalRewardsResponse = from_binary(&res).unwrap(); + assert_eq!( + res.rewards, + vec![ + DelegatorReward { + validator_address: "valoper0".into(), + reward: valoper0_rewards + }, + DelegatorReward { + validator_address: "valoper1".into(), + reward: valoper1_rewards + }, + ] + ); + assert_eq!( + res.total, + [ + DecCoin::new( + Decimal256::from_atomics(1234u128, 0).unwrap() + Decimal256::one(), + "uatom" + ), + // total for utest should still be the same + DecCoin::new(Decimal256::from_atomics(56781234u128, 4).unwrap(), "utest") + ] + ); + } + + #[cfg(feature = "stargate")] + #[test] + fn ibc_querier_channel_existing() { + let chan1 = mock_ibc_channel("channel-0", IbcOrder::Ordered, "ibc"); + let chan2 = mock_ibc_channel("channel-1", IbcOrder::Ordered, "ibc"); + + let ibc = IbcQuerier::new("myport", &[chan1.clone(), chan2]); + + // query existing + let query = &IbcQuery::Channel { + channel_id: "channel-0".to_string(), + port_id: Some("my_port".to_string()), + }; + let raw = ibc.query(query).unwrap().unwrap(); + let chan: ChannelResponse = from_binary(&raw).unwrap(); + assert_eq!(chan.channel, Some(chan1)); + } + + #[cfg(feature = "stargate")] + #[test] + fn ibc_querier_channel_existing_no_port() { + let chan1 = IbcChannel { + endpoint: IbcEndpoint { + port_id: "myport".to_string(), + channel_id: "channel-0".to_string(), + }, + counterparty_endpoint: IbcEndpoint { + port_id: "their_port".to_string(), + channel_id: "channel-7".to_string(), + }, + order: IbcOrder::Ordered, + version: "ibc".to_string(), + connection_id: "connection-2".to_string(), + }; + let chan2 = mock_ibc_channel("channel-1", IbcOrder::Ordered, "ibc"); + + let ibc = IbcQuerier::new("myport", &[chan1.clone(), chan2]); + + // query existing + let query = &IbcQuery::Channel { + channel_id: "channel-0".to_string(), + port_id: Some("myport".to_string()), + }; + let raw = ibc.query(query).unwrap().unwrap(); + let chan: ChannelResponse = from_binary(&raw).unwrap(); + assert_eq!(chan.channel, Some(chan1)); + } + + #[cfg(feature = "stargate")] + #[test] + fn ibc_querier_channel_none() { + let chan1 = mock_ibc_channel("channel-0", IbcOrder::Ordered, "ibc"); + let chan2 = mock_ibc_channel("channel-1", IbcOrder::Ordered, "ibc"); + + let ibc = IbcQuerier::new("myport", &[chan1, chan2]); + + // query non-existing + let query = &IbcQuery::Channel { + channel_id: "channel-0".to_string(), + port_id: None, + }; + let raw = ibc.query(query).unwrap().unwrap(); + let chan: ChannelResponse = from_binary(&raw).unwrap(); + assert_eq!(chan.channel, None); + } + + #[cfg(feature = "stargate")] + #[test] + fn ibc_querier_channels_matching() { + let chan1 = mock_ibc_channel("channel-0", IbcOrder::Ordered, "ibc"); + let chan2 = mock_ibc_channel("channel-1", IbcOrder::Ordered, "ibc"); + + let ibc = IbcQuerier::new("myport", &[chan1.clone(), chan2.clone()]); + + // query channels matching "my_port" (should match both above) + let query = &IbcQuery::ListChannels { + port_id: Some("my_port".to_string()), + }; + let raw = ibc.query(query).unwrap().unwrap(); + let res: ListChannelsResponse = from_binary(&raw).unwrap(); + assert_eq!(res.channels, vec![chan1, chan2]); + } + + #[cfg(feature = "stargate")] + #[test] + fn ibc_querier_channels_no_matching() { + let chan1 = mock_ibc_channel("channel-0", IbcOrder::Ordered, "ibc"); + let chan2 = mock_ibc_channel("channel-1", IbcOrder::Ordered, "ibc"); + + let ibc = IbcQuerier::new("myport", &[chan1, chan2]); + + // query channels matching "myport" (should be none) + let query = &IbcQuery::ListChannels { port_id: None }; + let raw = ibc.query(query).unwrap().unwrap(); + let res: ListChannelsResponse = from_binary(&raw).unwrap(); + assert_eq!(res.channels, vec![]); + } + + #[cfg(feature = "stargate")] + #[test] + fn ibc_querier_port() { + let chan1 = mock_ibc_channel("channel-0", IbcOrder::Ordered, "ibc"); + + let ibc = IbcQuerier::new("myport", &[chan1]); + + // query channels matching "myport" (should be none) + let query = &IbcQuery::PortId {}; + let raw = ibc.query(query).unwrap().unwrap(); + let res: PortIdResponse = from_binary(&raw).unwrap(); + assert_eq!(res.port_id, "myport"); + } + #[cfg(feature = "staking")] #[test] fn staking_querier_all_validators() { @@ -1430,7 +2067,7 @@ mod tests { let any_addr = "foo".to_string(); - // Query WasmQuery::Raw + // By default, querier errors for WasmQuery::Raw let system_err = querier .query(&WasmQuery::Raw { contract_addr: any_addr.clone(), @@ -1439,10 +2076,10 @@ mod tests { .unwrap_err(); match system_err { SystemError::NoSuchContract { addr } => assert_eq!(addr, any_addr), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } - // Query WasmQuery::Smart + // By default, querier errors for WasmQuery::Smart let system_err = querier .query(&WasmQuery::Smart { contract_addr: any_addr.clone(), @@ -1451,10 +2088,10 @@ mod tests { .unwrap_err(); match system_err { SystemError::NoSuchContract { addr } => assert_eq!(addr, any_addr), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } - // Query WasmQuery::ContractInfo + // By default, querier errors for WasmQuery::ContractInfo let system_err = querier .query(&WasmQuery::ContractInfo { contract_addr: any_addr.clone(), @@ -1462,7 +2099,19 @@ mod tests { .unwrap_err(); match system_err { SystemError::NoSuchContract { addr } => assert_eq!(addr, any_addr), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), + } + + #[cfg(feature = "cosmwasm_1_2")] + { + // By default, querier errors for WasmQuery::CodeInfo + let system_err = querier + .query(&WasmQuery::CodeInfo { code_id: 4 }) + .unwrap_err(); + match system_err { + SystemError::NoSuchCode { code_id } => assert_eq!(code_id, 4), + err => panic!("Unexpected error: {err:?}"), + } } querier.update_handler(|request| { @@ -1518,6 +2167,24 @@ mod tests { }) } } + #[cfg(feature = "cosmwasm_1_2")] + WasmQuery::CodeInfo { code_id } => { + use crate::{CodeInfoResponse, HexBinary}; + let code_id = *code_id; + if code_id == 4 { + let response = CodeInfoResponse { + code_id, + creator: "lalala".into(), + checksum: HexBinary::from_hex( + "84cf20810fd429caf58898c3210fcb71759a27becddae08dbde8668ea2f4725d", + ) + .unwrap(), + }; + SystemResult::Ok(ContractResult::Ok(to_binary(&response).unwrap())) + } else { + SystemResult::Err(SystemError::NoSuchCode { code_id }) + } + } } }); @@ -1528,7 +2195,7 @@ mod tests { }); match result { SystemResult::Ok(ContractResult::Ok(value)) => assert_eq!(value, b"the value" as &[u8]), - res => panic!("Unexpected result: {:?}", res), + res => panic!("Unexpected result: {res:?}"), } let result = querier.query(&WasmQuery::Raw { contract_addr: "contract1".into(), @@ -1536,7 +2203,7 @@ mod tests { }); match result { SystemResult::Ok(ContractResult::Ok(value)) => assert_eq!(value, b"" as &[u8]), - res => panic!("Unexpected result: {:?}", res), + res => panic!("Unexpected result: {res:?}"), } // WasmQuery::Smart @@ -1549,7 +2216,7 @@ mod tests { value, br#"{"messages":[],"attributes":[],"events":[],"data":"Z29vZA=="}"# as &[u8] ), - res => panic!("Unexpected result: {:?}", res), + res => panic!("Unexpected result: {res:?}"), } let result = querier.query(&WasmQuery::Smart { contract_addr: "contract1".into(), @@ -1559,7 +2226,7 @@ mod tests { SystemResult::Ok(ContractResult::Err(err)) => { assert_eq!(err, "Error parsing into type cosmwasm_std::testing::mock::tests::wasm_querier_works::{{closure}}::MyMsg: Invalid type") } - res => panic!("Unexpected result: {:?}", res), + res => panic!("Unexpected result: {res:?}"), } // WasmQuery::ContractInfo @@ -1572,40 +2239,21 @@ mod tests { br#"{"code_id":4,"creator":"lalala","admin":null,"pinned":false,"ibc_port":null}"# as &[u8] ), - res => panic!("Unexpected result: {:?}", res), + res => panic!("Unexpected result: {res:?}"), } - } - - #[test] - fn riffle_shuffle_works() { - // Example from https://en.wikipedia.org/wiki/In_shuffle - let start = [0xA, 0x2, 0x3, 0x4, 0x5, 0x6]; - let round1 = riffle_shuffle(&start); - assert_eq!(round1, [0x4, 0xA, 0x5, 0x2, 0x6, 0x3]); - let round2 = riffle_shuffle(&round1); - assert_eq!(round2, [0x2, 0x4, 0x6, 0xA, 0x3, 0x5]); - let round3 = riffle_shuffle(&round2); - assert_eq!(round3, start); - - // For 14 elements, the original order is restored after 4 executions - // See https://en.wikipedia.org/wiki/In_shuffle#Mathematics and https://oeis.org/A002326 - let original = [12, 33, 76, 576, 0, 44, 1, 14, 78, 99, 871212, -7, 2, -1]; - let mut result = Vec::from(original); - for _ in 0..4 { - result = riffle_shuffle(&result); - } - assert_eq!(result, original); - // For 24 elements, the original order is restored after 20 executions - let original = [ - 7, 4, 2, 4656, 23, 45, 23, 1, 12, 76, 576, 0, 12, 1, 14, 78, 99, 12, 1212, 444, 31, - 111, 424, 34, - ]; - let mut result = Vec::from(original); - for _ in 0..20 { - result = riffle_shuffle(&result); + // WasmQuery::ContractInfo + #[cfg(feature = "cosmwasm_1_2")] + { + let result = querier.query(&WasmQuery::CodeInfo { code_id: 4 }); + match result { + SystemResult::Ok(ContractResult::Ok(value)) => assert_eq!( + value, + br#"{"code_id":4,"creator":"lalala","checksum":"84cf20810fd429caf58898c3210fcb71759a27becddae08dbde8668ea2f4725d"}"# + ), + res => panic!("Unexpected result: {res:?}"), + } } - assert_eq!(result, original); } #[test] diff --git a/packages/std/src/testing/mod.rs b/packages/std/src/testing/mod.rs index b317d61c4..14b362ce4 100644 --- a/packages/std/src/testing/mod.rs +++ b/packages/std/src/testing/mod.rs @@ -5,14 +5,19 @@ mod assertions; mod mock; +mod shuffle; pub use assertions::assert_approx_eq_impl; +#[cfg(test)] +pub use assertions::assert_hash_works_impl; +#[cfg(feature = "cosmwasm_1_3")] +pub use mock::DistributionQuerier; #[cfg(feature = "staking")] pub use mock::StakingQuerier; pub use mock::{ digit_sum, mock_dependencies, mock_dependencies_with_balance, mock_dependencies_with_balances, - mock_env, mock_info, mock_wasmd_attr, riffle_shuffle, BankQuerier, MockApi, MockQuerier, + mock_env, mock_info, mock_wasmd_attr, BankQuerier, MockApi, MockQuerier, MockQuerierCustomHandlerResult, MockStorage, MOCK_CONTRACT_ADDR, }; #[cfg(feature = "stargate")] @@ -21,3 +26,4 @@ pub use mock::{ mock_ibc_channel_connect_ack, mock_ibc_channel_connect_confirm, mock_ibc_channel_open_init, mock_ibc_channel_open_try, mock_ibc_packet_ack, mock_ibc_packet_recv, mock_ibc_packet_timeout, }; +pub use shuffle::riffle_shuffle; diff --git a/packages/std/src/testing/shuffle.rs b/packages/std/src/testing/shuffle.rs new file mode 100644 index 000000000..aa04c17ff --- /dev/null +++ b/packages/std/src/testing/shuffle.rs @@ -0,0 +1,69 @@ +/// Performs a perfect shuffle (in shuffle) +/// +/// https://en.wikipedia.org/wiki/Riffle_shuffle_permutation#Perfect_shuffles +/// https://en.wikipedia.org/wiki/In_shuffle +/// +/// The number of shuffles required to restore the original order are listed in +/// and , e.g.: +/// +/// ```text +/// 2 (n=1): 2 +/// 4 (n=2): 4 +/// 6 (n=3): 3 +/// 8 (n=4): 6 +/// 10 (n=5): 10 +/// 12 (n=6): 12 +/// 14 (n=7): 4 +/// 16 (n=8): 8 +/// ``` +pub fn riffle_shuffle(input: &[T]) -> Vec { + assert!( + input.len() % 2 == 0, + "Method only defined for even number of elements" + ); + let mid = input.len() / 2; + let (left, right) = input.split_at(mid); + let mut out = Vec::::with_capacity(input.len()); + for i in 0..mid { + out.push(right[i].clone()); + out.push(left[i].clone()); + } + out +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn riffle_shuffle_works() { + // Example from https://en.wikipedia.org/wiki/In_shuffle + let start = [0xA, 0x2, 0x3, 0x4, 0x5, 0x6]; + let round1 = riffle_shuffle(&start); + assert_eq!(round1, [0x4, 0xA, 0x5, 0x2, 0x6, 0x3]); + let round2 = riffle_shuffle(&round1); + assert_eq!(round2, [0x2, 0x4, 0x6, 0xA, 0x3, 0x5]); + let round3 = riffle_shuffle(&round2); + assert_eq!(round3, start); + + // For 14 elements, the original order is restored after 4 executions + // See https://en.wikipedia.org/wiki/In_shuffle#Mathematics and https://oeis.org/A002326 + let original = [12, 33, 76, 576, 0, 44, 1, 14, 78, 99, 871212, -7, 2, -1]; + let mut result = Vec::from(original); + for _ in 0..4 { + result = riffle_shuffle(&result); + } + assert_eq!(result, original); + + // For 24 elements, the original order is restored after 20 executions + let original = [ + 7, 4, 2, 4656, 23, 45, 23, 1, 12, 76, 576, 0, 12, 1, 14, 78, 99, 12, 1212, 444, 31, + 111, 424, 34, + ]; + let mut result = Vec::from(original); + for _ in 0..20 { + result = riffle_shuffle(&result); + } + assert_eq!(result, original); + } +} diff --git a/packages/std/src/timestamp.rs b/packages/std/src/timestamp.rs index 12d504aea..984ad1ac3 100644 --- a/packages/std/src/timestamp.rs +++ b/packages/std/src/timestamp.rs @@ -1,6 +1,6 @@ +use core::fmt; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::fmt; use crate::math::Uint64; @@ -40,23 +40,59 @@ impl Timestamp { Timestamp(Uint64::new(seconds_since_epoch * 1_000_000_000)) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub const fn plus_days(&self, addition: u64) -> Timestamp { + self.plus_hours(addition * 24) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub const fn plus_hours(&self, addition: u64) -> Timestamp { + self.plus_minutes(addition * 60) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub const fn plus_minutes(&self, addition: u64) -> Timestamp { + self.plus_seconds(addition * 60) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn plus_seconds(&self, addition: u64) -> Timestamp { self.plus_nanos(addition * 1_000_000_000) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn plus_nanos(&self, addition: u64) -> Timestamp { let nanos = Uint64::new(self.0.u64() + addition); Timestamp(nanos) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub const fn minus_days(&self, subtrahend: u64) -> Timestamp { + self.minus_hours(subtrahend * 24) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub const fn minus_hours(&self, subtrahend: u64) -> Timestamp { + self.minus_minutes(subtrahend * 60) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] + #[inline] + pub const fn minus_minutes(&self, subtrahend: u64) -> Timestamp { + self.minus_seconds(subtrahend * 60) + } + + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn minus_seconds(&self, subtrahend: u64) -> Timestamp { self.minus_nanos(subtrahend * 1_000_000_000) } - #[must_use] + #[must_use = "this returns the result of the operation, without modifying the original"] pub const fn minus_nanos(&self, subtrahend: u64) -> Timestamp { let nanos = Uint64::new(self.0.u64() - subtrahend); Timestamp(nanos) @@ -86,7 +122,7 @@ impl fmt::Display for Timestamp { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let whole = self.seconds(); let fractional = self.subsec_nanos(); - write!(f, "{}.{:09}", whole, fractional) + write!(f, "{whole}.{fractional:09}") } } @@ -158,6 +194,56 @@ mod tests { let _earlier = Timestamp::from_nanos(100).minus_nanos(101); } + #[test] + fn timestamp_plus_days() { + let ts = Timestamp::from_seconds(123).plus_days(0); + assert_eq!(ts.0.u64(), 123_000_000_000); + let ts = Timestamp::from_seconds(123).plus_days(10); + assert_eq!(ts.0.u64(), 864_123_000_000_000); + } + + #[test] + fn timestamp_minus_days() { + let ts = Timestamp::from_seconds(123).minus_days(0); + assert_eq!(ts.0.u64(), 123_000_000_000); + let ts = Timestamp::from_seconds(2 * 86400 + 123).minus_days(1); + assert_eq!(ts.0.u64(), 86_523_000_000_000); + let ts = Timestamp::from_seconds(86400).minus_days(1); + assert_eq!(ts.0.u64(), 0); + } + + #[test] + fn timestamp_plus_hours() { + let ts = Timestamp::from_seconds(123).plus_hours(0); + assert_eq!(ts.0.u64(), 123_000_000_000); + let ts = Timestamp::from_seconds(123).plus_hours(2); + assert_eq!(ts.0.u64(), 123_000_000_000 + 60 * 60 * 2 * 1_000_000_000); + } + + #[test] + fn timestamp_minus_hours() { + let ts = Timestamp::from_seconds(2 * 60 * 60).minus_hours(0); + assert_eq!(ts.0.u64(), 2 * 60 * 60 * 1_000_000_000); + let ts = Timestamp::from_seconds(2 * 60 * 60 + 123).minus_hours(1); + assert_eq!(ts.0.u64(), 60 * 60 * 1_000_000_000 + 123_000_000_000); + } + + #[test] + fn timestamp_plus_minutes() { + let ts = Timestamp::from_seconds(123).plus_minutes(0); + assert_eq!(ts.0.u64(), 123_000_000_000); + let ts = Timestamp::from_seconds(123).plus_minutes(2); + assert_eq!(ts.0.u64(), 123_000_000_000 + 60 * 2 * 1_000_000_000); + } + + #[test] + fn timestamp_minus_minutes() { + let ts = Timestamp::from_seconds(5 * 60).minus_minutes(0); + assert_eq!(ts.0.u64(), 5 * 60 * 1_000_000_000); + let ts = Timestamp::from_seconds(5 * 60 + 123).minus_minutes(1); + assert_eq!(ts.0.u64(), 4 * 60 * 1_000_000_000 + 123_000_000_000); + } + #[test] fn timestamp_nanos() { let sum = Timestamp::from_nanos(123); diff --git a/packages/std/src/traits.rs b/packages/std/src/traits.rs index 8097db0b5..618c57f64 100644 --- a/packages/std/src/traits.rs +++ b/packages/std/src/traits.rs @@ -1,6 +1,6 @@ +use core::marker::PhantomData; +use core::ops::Deref; use serde::{de::DeserializeOwned, Serialize}; -use std::marker::PhantomData; -use std::ops::Deref; use crate::addresses::{Addr, CanonicalAddr}; use crate::binary::Binary; @@ -10,6 +10,8 @@ use crate::errors::{ }; #[cfg(feature = "iterator")] use crate::iterator::{Order, Record}; +#[cfg(feature = "cosmwasm_1_2")] +use crate::query::CodeInfoResponse; #[cfg(feature = "cosmwasm_1_1")] use crate::query::SupplyResponse; use crate::query::{ @@ -20,9 +22,16 @@ use crate::query::{ AllDelegationsResponse, AllValidatorsResponse, BondedDenomResponse, Delegation, DelegationResponse, FullDelegation, StakingQuery, Validator, ValidatorResponse, }; +#[cfg(feature = "cosmwasm_1_3")] +use crate::query::{ + AllDenomMetadataResponse, DelegatorWithdrawAddressResponse, DenomMetadataResponse, + DistributionQuery, +}; use crate::results::{ContractResult, Empty, SystemResult}; use crate::serde::{from_binary, to_binary, to_vec}; use crate::ContractInfoResponse; +#[cfg(feature = "cosmwasm_1_3")] +use crate::{DenomMetadata, PageRequest}; /// Storage provides read and write access to a persistent storage. /// If you only want to provide read access, provide `&Storage` @@ -34,12 +43,11 @@ pub trait Storage { /// is not great yet and might not be possible in all backends. But we're trying to get there. fn get(&self, key: &[u8]) -> Option>; - #[cfg(feature = "iterator")] /// Allows iteration over a set of key/value pairs, either forwards or backwards. /// /// The bound `start` is inclusive and `end` is exclusive. - /// /// If `start` is lexicographically greater than or equal to `end`, an empty range is described, mo matter of the order. + #[cfg(feature = "iterator")] fn range<'a>( &'a self, start: Option<&[u8]>, @@ -47,6 +55,40 @@ pub trait Storage { order: Order, ) -> Box + 'a>; + /// Allows iteration over a set of keys, either forwards or backwards. + /// + /// The bound `start` is inclusive and `end` is exclusive. + /// If `start` is lexicographically greater than or equal to `end`, an empty range is described, mo matter of the order. + /// + /// The default implementation uses [`Storage::range`] and discards the values. More efficient + /// implementations might be possible depending on the storage. + #[cfg(feature = "iterator")] + fn range_keys<'a>( + &'a self, + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, + ) -> Box> + 'a> { + Box::new(self.range(start, end, order).map(|(k, _v)| k)) + } + + /// Allows iteration over a set of values, either forwards or backwards. + /// + /// The bound `start` is inclusive and `end` is exclusive. + /// If `start` is lexicographically greater than or equal to `end`, an empty range is described, mo matter of the order. + /// + /// The default implementation uses [`Storage::range`] and discards the keys. More efficient implementations + /// might be possible depending on the storage. + #[cfg(feature = "iterator")] + fn range_values<'a>( + &'a self, + start: Option<&[u8]>, + end: Option<&[u8]>, + order: Order, + ) -> Box> + 'a> { + Box::new(self.range(start, end, order).map(|(_k, v)| v)) + } + fn set(&mut self, key: &[u8], value: &[u8]); /// Removes a database entry at `key`. @@ -187,6 +229,15 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { } } + /// This allows to convert any `QuerierWrapper` into a `QuerierWrapper` generic + /// over `Empty` custom query type. + pub fn into_empty(self) -> QuerierWrapper<'a, Empty> { + QuerierWrapper { + querier: self.querier, + custom_query_type: PhantomData, + } + } + /// Makes the query and parses the response. /// /// Any error (System Error, Error or called contract, or Parse Error) are flattened into @@ -194,15 +245,14 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { /// eg. If you don't differentiate between contract missing and contract returned error pub fn query(&self, request: &QueryRequest) -> StdResult { let raw = to_vec(request).map_err(|serialize_err| { - StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err)) + StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}")) })?; match self.raw_query(&raw) { SystemResult::Err(system_err) => Err(StdError::generic_err(format!( - "Querier system error: {}", - system_err + "Querier system error: {system_err}" ))), SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err( - format!("Querier contract error: {}", contract_err), + format!("Querier contract error: {contract_err}"), )), SystemResult::Ok(ContractResult::Ok(value)) => from_binary(&value), } @@ -241,8 +291,88 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { Ok(res.amount) } - // this queries another wasm contract. You should know a priori the proper types for T and U - // (response and request) based on the contract API + #[cfg(feature = "cosmwasm_1_3")] + pub fn query_delegator_withdraw_address( + &self, + delegator: impl Into, + ) -> StdResult { + let request = DistributionQuery::DelegatorWithdrawAddress { + delegator_address: delegator.into(), + } + .into(); + let res: DelegatorWithdrawAddressResponse = self.query(&request)?; + Ok(res.withdraw_address) + } + + #[cfg(feature = "cosmwasm_1_3")] + pub fn query_denom_metadata(&self, denom: impl Into) -> StdResult { + let request = BankQuery::DenomMetadata { + denom: denom.into(), + } + .into(); + let res: DenomMetadataResponse = self.query(&request)?; + Ok(res.metadata) + } + + #[cfg(feature = "cosmwasm_1_3")] + pub fn query_all_denom_metadata( + &self, + pagination: PageRequest, + ) -> StdResult { + let request = BankQuery::AllDenomMetadata { + pagination: Some(pagination), + } + .into(); + self.query(&request) + } + + #[cfg(feature = "cosmwasm_1_4")] + pub fn query_delegation_rewards( + &self, + delegator: impl Into, + validator: impl Into, + ) -> StdResult> { + use crate::DelegationRewardsResponse; + + let request = DistributionQuery::DelegationRewards { + delegator_address: delegator.into(), + validator_address: validator.into(), + } + .into(); + let DelegationRewardsResponse { rewards } = self.query(&request)?; + + Ok(rewards) + } + + #[cfg(feature = "cosmwasm_1_4")] + pub fn query_delegation_total_rewards( + &self, + delegator: impl Into, + ) -> StdResult { + let request = DistributionQuery::DelegationTotalRewards { + delegator_address: delegator.into(), + } + .into(); + self.query(&request) + } + + #[cfg(feature = "cosmwasm_1_4")] + pub fn query_delegator_validators( + &self, + delegator: impl Into, + ) -> StdResult> { + use crate::DelegatorValidatorsResponse; + + let request = DistributionQuery::DelegatorValidators { + delegator_address: delegator.into(), + } + .into(); + let res: DelegatorValidatorsResponse = self.query(&request)?; + Ok(res.validators) + } + + /// Queries another wasm contract. You should know a priori the proper types for T and U + /// (response and request) based on the contract API pub fn query_wasm_smart( &self, contract_addr: impl Into, @@ -256,13 +386,14 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { self.query(&request) } - // this queries the raw storage from another wasm contract. - // you must know the exact layout and are implementation dependent - // (not tied to an interface like query_wasm_smart) - // that said, if you are building a few contracts together, this is a much cheaper approach - // - // Similar return value to Storage.get(). Returns Some(val) or None if the data is there. - // It only returns error on some runtime issue, not on any data cases. + /// Queries the raw storage from another wasm contract. + /// + /// You must know the exact layout and are implementation dependent + /// (not tied to an interface like query_wasm_smart). + /// That said, if you are building a few contracts together, this is a much cheaper approach + /// + /// Similar return value to [`Storage::get`]. Returns `Some(val)` or `None` if the data is there. + /// It only returns error on some runtime issue, not on any data cases. pub fn query_wasm_raw( &self, contract_addr: impl Into, @@ -276,15 +407,14 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { // we cannot use query, as it will try to parse the binary data, when we just want to return it, // so a bit of code copy here... let raw = to_vec(&request).map_err(|serialize_err| { - StdError::generic_err(format!("Serializing QueryRequest: {}", serialize_err)) + StdError::generic_err(format!("Serializing QueryRequest: {serialize_err}")) })?; match self.raw_query(&raw) { SystemResult::Err(system_err) => Err(StdError::generic_err(format!( - "Querier system error: {}", - system_err + "Querier system error: {system_err}" ))), SystemResult::Ok(ContractResult::Err(contract_err)) => Err(StdError::generic_err( - format!("Querier contract error: {}", contract_err), + format!("Querier contract error: {contract_err}"), )), SystemResult::Ok(ContractResult::Ok(value)) => { if value.is_empty() { @@ -308,6 +438,13 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { self.query(&request) } + /// Given a code ID, query information about that code. + #[cfg(feature = "cosmwasm_1_2")] + pub fn query_wasm_code_info(&self, code_id: u64) -> StdResult { + let request = WasmQuery::CodeInfo { code_id }.into(); + self.query(&request) + } + #[cfg(feature = "staking")] pub fn query_all_validators(&self) -> StdResult> { let request = StakingQuery::AllValidators {}.into(); @@ -363,6 +500,8 @@ impl<'a, C: CustomQuery> QuerierWrapper<'a, C> { #[cfg(test)] mod tests { + use serde::Deserialize; + use super::*; use crate::testing::MockQuerier; use crate::{coins, from_slice, Uint128}; @@ -493,4 +632,16 @@ mod tests { } if msg == "Querier system error: No such contract: foobar" )); } + + #[test] + fn querier_into_empty() { + #[derive(Clone, Serialize, Deserialize)] + struct MyQuery; + impl CustomQuery for MyQuery {} + + let querier: MockQuerier = MockQuerier::new(&[]); + let wrapper = QuerierWrapper::::new(&querier); + + let _: QuerierWrapper = wrapper.into_empty(); + } } diff --git a/packages/std/testdata/instantiate2_addresses.json b/packages/std/testdata/instantiate2_addresses.json new file mode 100644 index 000000000..a12ad6952 --- /dev/null +++ b/packages/std/testdata/instantiate2_addresses.json @@ -0,0 +1,386 @@ +[ + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "61", + "msg": null + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000001610000000000000000", + "addressData": "5e865d3e45ad3e961f77fd77d46543417ced44d924dc3e079b5415ff6775f847" + }, + "out": { + "address": "purple1t6r960j945lfv8mhl4mage2rg97w63xeynwrupum2s2l7em4lprs9ce5hk" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "61", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc00000000000000016100000000000000027b7d", + "addressData": "0995499608947a5281e2c7ebd71bdb26a1ad981946dad57f6c4d3ee35de77835" + }, + "out": { + "address": "purple1px25n9sgj3a99q0zcl4awx7my6s6mxqegmdd2lmvf5lwxh080q6suttktr" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "61", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc000000000000000161000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "83326e554723b15bac664ceabc8a5887e27003abe9fbd992af8c7bcea4745167" + }, + "out": { + "address": "purple1svexu428ywc4htrxfn4tezjcsl38qqata8aany4033auafr529ns4v254c" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": null + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae0000000000000000", + "addressData": "9384c6248c0bb171e306fd7da0993ec1e20eba006452a3a9e078883eb3594564" + }, + "out": { + "address": "purple1jwzvvfyvpwchrccxl476pxf7c83qawsqv3f2820q0zyrav6eg4jqdcq7gc" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae00000000000000027b7d", + "addressData": "9a8d5f98fb186825401a26206158e7a1213311a9b6a87944469913655af52ffb" + }, + "out": { + "address": "purple1n2x4lx8mrp5z2sq6ycsxzk885ysnxydfk658j3zxnyfk2kh49lasesxf6j" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "932f07bc53f7d0b0b43cb5a54ac3e245b205e6ae6f7c1d991dc6af4a2ff9ac18" + }, + "out": { + "address": "purple1jvhs00zn7lgtpdpukkj54slzgkeqte4wda7pmxgac6h55tle4svq8cmp60" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "61", + "msg": null + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000001610000000000000000", + "addressData": "9725e94f528d8b78d33c25f3dfcd60e6142d8be60ab36f6a5b59036fd51560db" + }, + "out": { + "address": "purple1juj7jn6j3k9h35euyhealntquc2zmzlxp2ek76jmtypkl4g4vrdsfwmwxk" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "61", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff00000000000000016100000000000000027b7d", + "addressData": "b056e539bbaf447ba18f3f13b792970111fc78933eb6700f4d227b5216d63658" + }, + "out": { + "address": "purple1kptw2wdm4az8hgv08ufm0y5hqyglc7yn86m8qr6dyfa4y9kkxevqmkm9q3" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "61", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff000000000000000161000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "6c98434180f052294ff89fb6d2dae34f9f4468b0b8e6e7c002b2a44adee39abd" + }, + "out": { + "address": "purple1djvyxsvq7pfzjnlcn7md9khrf705g69shrnw0sqzk2jy4hhrn27sjh2ysy" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": null + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae0000000000000000", + "addressData": "0aaf1c31c5d529d21d898775bc35b3416f47bfd99188c334c6c716102cbd3101" + }, + "out": { + "address": "purple1p2h3cvw9655ay8vfsa6mcddng9h5007ejxyvxdxxcutpqt9axyqsagmmay" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae00000000000000027b7d", + "addressData": "36fe6ab732187cdfed46290b448b32eb7f4798e7a4968b0537de8a842cbf030e" + }, + "out": { + "address": "purple1xmlx4dejrp7dlm2x9y95fzejadl50x885jtgkpfhm69ggt9lqv8qk3vn4f" + } + }, + { + "in": { + "checksum": "13a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a5", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d00000000000000002013a1fc994cc6d1c81b746ee0c0ff6f90043875e0bf1d9be6b7d779fc978dc2a500000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "a0d0c942adac6f3e5e7c23116c4c42a24e96e0ab75f53690ec2d3de16067c751" + }, + "out": { + "address": "purple15rgvjs4d43hnuhnuyvgkcnzz5f8fdc9twh6ndy8v9577zcr8cags40l9dt" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "61", + "msg": null + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000001610000000000000000", + "addressData": "b95c467218d408a0f93046f227b6ece7fe18133ff30113db4d2a7becdfeca141" + }, + "out": { + "address": "purple1h9wyvusc6sy2p7fsgmez0dhvullpsyel7vq38k6d9fa7ehlv59qsvnyh36" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "61", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc00000000000000016100000000000000027b7d", + "addressData": "23fe45dbbd45dc6cd25244a74b6e99e7a65bf0bac2f2842a05049d37555a3ae6" + }, + "out": { + "address": "purple1y0lytkaaghwxe5jjgjn5km5eu7n9hu96ctegg2s9qjwnw4268tnqxhg60a" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "61", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc000000000000000161000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "6faea261ed63baa65b05726269e83b217fa6205dc7d9fb74f9667d004a69c082" + }, + "out": { + "address": "purple1d7h2yc0dvwa2vkc9wf3xn6pmy9l6vgzaclvlka8eve7sqjnfczpqqsdnwu" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": null + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae0000000000000000", + "addressData": "67a3ab6384729925fdb144574628ce96836fe098d2c6be4e84ac106b2728d96c" + }, + "out": { + "address": "purple1v736kcuyw2vjtld3g3t5v2xwj6pklcyc6trtun5y4sgxkfegm9kq7vgpnt" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae00000000000000027b7d", + "addressData": "23a121263bfce05c144f4af86f3d8a9f87dc56f9dc48dbcffc8c5a614da4c661" + }, + "out": { + "address": "purple1ywsjzf3mlns9c9z0ftux70v2n7rac4hem3ydhnlu33dxzndycesssc7x2m" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvhxf2py", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbcccccccccc", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000149999999999aaaaaaaaaabbbbbbbbbbcccccccccc0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "dd90dba6d6fcd5fb9c9c8f536314eb1bb29cb5aa084b633c5806b926a5636b58" + }, + "out": { + "address": "purple1mkgdhfkkln2lh8yu3afkx98trwefedd2pp9kx0zcq6ujdftrddvq50esay" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "61", + "msg": null + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000001610000000000000000", + "addressData": "547a743022f4f1af05b102f57bf1c1c7d7ee81bae427dc20d36b2c4ec57612ae" + }, + "out": { + "address": "purple123a8gvpz7nc67pd3qt6hhuwpclt7aqd6usnacgxndvkya3tkz2hq5hz38f" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "61", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff00000000000000016100000000000000027b7d", + "addressData": "416e169110e4b411bc53162d7503b2bbf14d6b36b1413a4f4c9af622696e9665" + }, + "out": { + "address": "purple1g9hpdygsuj6pr0znzckh2qajh0c566ekk9qn5n6vntmzy6twjejsrl9alk" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "61", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff000000000000000161000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "619a0988b92d8796cea91dea63cbb1f1aefa4a6b6ee5c5d1e937007252697220" + }, + "out": { + "address": "purple1vxdqnz9e9kredn4frh4x8ja37xh05jntdmjut50fxuq8y5nfwgsquu9mxh" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": null + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae0000000000000000", + "addressData": "d8af856a6a04852d19b647ad6d4336eb26e077f740aef1a0331db34d299a885a" + }, + "out": { + "address": "purple1mzhc26n2qjzj6xdkg7kk6sekavnwqalhgzh0rgpnrke562v63pdq8grp8q" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae00000000000000027b7d", + "addressData": "c7fb7bea96daab23e416c4fcf328215303005e1d0d5424257335568e5381e33c" + }, + "out": { + "address": "purple1clahh65km24j8eqkcn70x2pp2vpsqhsap42zgftnx4tgu5upuv7q9ywjws" + } + }, + { + "in": { + "checksum": "1da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b", + "creator": "purple1nxvenxve42424242hwamhwamenxvenxvmhwamhwaamhwamhwlllsatsy6m", + "creatorData": "9999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff", + "salt": "aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae", + "msg": "{\"some\":123,\"structure\":{\"nested\":[\"ok\",true]}}" + }, + "intermediate": { + "key": "7761736d0000000000000000201da6c16de2cbaf7ad8cbb66f0925ba33f5c278cb2491762d04658c1480ea229b00000000000000209999999999aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeffff0000000000000040aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbccddeeffffeeddbbccddaa66551155aaaabbcc787878789900aabbbbcc221100acadae000000000000002f7b22736f6d65223a3132332c22737472756374757265223a7b226e6573746564223a5b226f6b222c747275655d7d7d", + "addressData": "ccdf9dea141a6c2475870529ab38fae9dec30df28e005894fe6578b66133ab4a" + }, + "out": { + "address": "purple1en0em6s5rfkzgav8q556kw86a80vxr0j3cq93987v4utvcfn4d9q0tql4w" + } + } +] diff --git a/packages/storage/README.md b/packages/storage/README.md index ecafb54b4..9309fa209 100644 --- a/packages/storage/README.md +++ b/packages/storage/README.md @@ -4,7 +4,7 @@ _Forked from [CosmWasm/cosmwasm-storage](https://github.com/CosmWasm/cosmwasm/tr CosmWasm library with useful helpers for Storage patterns. You can use `Storage` implementations in `cosmwasm-std`, or rely on these to remove some common -boilterplate. +boilerplate. ## Contents diff --git a/packages/storage/src/bucket.rs b/packages/storage/src/bucket.rs index dd9e482f3..a870dfac4 100644 --- a/packages/storage/src/bucket.rs +++ b/packages/storage/src/bucket.rs @@ -1,11 +1,13 @@ use serde::{de::DeserializeOwned, ser::Serialize}; use std::marker::PhantomData; -use cosmwasm_std::{to_vec, StdError, StdResult, Storage}; +use cosmwasm_std::{ + storage_keys::{to_length_prefixed, to_length_prefixed_nested}, + to_vec, StdError, StdResult, Storage, +}; #[cfg(feature = "iterator")] use cosmwasm_std::{Order, Record}; -use crate::length_prefixed::{to_length_prefixed, to_length_prefixed_nested}; #[cfg(feature = "iterator")] use crate::namespace_helpers::range_with_prefix; use crate::namespace_helpers::{get_with_prefix, remove_with_prefix, set_with_prefix}; @@ -14,6 +16,9 @@ use crate::type_helpers::deserialize_kv; use crate::type_helpers::{may_deserialize, must_deserialize}; /// An alias of Bucket::new for less verbose usage +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn bucket<'a, T>(storage: &'a mut dyn Storage, namespace: &[u8]) -> Bucket<'a, T> where T: Serialize + DeserializeOwned, @@ -22,6 +27,9 @@ where } /// An alias of ReadonlyBucket::new for less verbose usage +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn bucket_read<'a, T>(storage: &'a dyn Storage, namespace: &[u8]) -> ReadonlyBucket<'a, T> where T: Serialize + DeserializeOwned, @@ -29,6 +37,9 @@ where ReadonlyBucket::new(storage, namespace) } +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub struct Bucket<'a, T> where T: Serialize + DeserializeOwned, @@ -110,6 +121,9 @@ where } } +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub struct ReadonlyBucket<'a, T> where T: Serialize + DeserializeOwned, @@ -395,7 +409,7 @@ mod tests { }); match res.unwrap_err() { MyError::NotFound { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/packages/storage/src/lib.rs b/packages/storage/src/lib.rs index 486d07079..3fd3a3794 100644 --- a/packages/storage/src/lib.rs +++ b/packages/storage/src/lib.rs @@ -1,5 +1,6 @@ +#![allow(deprecated)] + mod bucket; -mod length_prefixed; mod namespace_helpers; mod prefixed_storage; mod sequence; @@ -7,7 +8,10 @@ mod singleton; mod type_helpers; pub use bucket::{bucket, bucket_read, Bucket, ReadonlyBucket}; -pub use length_prefixed::{to_length_prefixed, to_length_prefixed_nested}; pub use prefixed_storage::{prefixed, prefixed_read, PrefixedStorage, ReadonlyPrefixedStorage}; pub use sequence::{currval, nextval, sequence}; pub use singleton::{singleton, singleton_read, ReadonlySingleton, Singleton}; + +// Re-exported for backwads compatibility. +// See https://github.com/CosmWasm/cosmwasm/pull/1676. +pub use cosmwasm_std::storage_keys::{to_length_prefixed, to_length_prefixed_nested}; diff --git a/packages/storage/src/namespace_helpers.rs b/packages/storage/src/namespace_helpers.rs index 1c2650b91..6a2482985 100644 --- a/packages/storage/src/namespace_helpers.rs +++ b/packages/storage/src/namespace_helpers.rs @@ -85,8 +85,7 @@ fn namespace_upper_bound(input: &[u8]) -> Vec { #[cfg(test)] mod tests { use super::*; - use crate::length_prefixed::to_length_prefixed; - use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::{storage_keys::to_length_prefixed, testing::MockStorage}; #[test] fn prefix_get_set() { diff --git a/packages/storage/src/prefixed_storage.rs b/packages/storage/src/prefixed_storage.rs index 6d7779541..97f5bb63a 100644 --- a/packages/storage/src/prefixed_storage.rs +++ b/packages/storage/src/prefixed_storage.rs @@ -1,18 +1,26 @@ -use cosmwasm_std::Storage; +use cosmwasm_std::{ + storage_keys::{to_length_prefixed, to_length_prefixed_nested}, + Storage, +}; #[cfg(feature = "iterator")] use cosmwasm_std::{Order, Record}; -use crate::length_prefixed::{to_length_prefixed, to_length_prefixed_nested}; #[cfg(feature = "iterator")] use crate::namespace_helpers::range_with_prefix; use crate::namespace_helpers::{get_with_prefix, remove_with_prefix, set_with_prefix}; /// An alias of PrefixedStorage::new for less verbose usage +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn prefixed<'a>(storage: &'a mut dyn Storage, namespace: &[u8]) -> PrefixedStorage<'a> { PrefixedStorage::new(storage, namespace) } /// An alias of ReadonlyPrefixedStorage::new for less verbose usage +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn prefixed_read<'a>( storage: &'a dyn Storage, namespace: &[u8], @@ -20,6 +28,9 @@ pub fn prefixed_read<'a>( ReadonlyPrefixedStorage::new(storage, namespace) } +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub struct PrefixedStorage<'a> { storage: &'a mut dyn Storage, prefix: Vec, @@ -69,6 +80,9 @@ impl<'a> Storage for PrefixedStorage<'a> { } } +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub struct ReadonlyPrefixedStorage<'a> { storage: &'a dyn Storage, prefix: Vec, diff --git a/packages/storage/src/sequence.rs b/packages/storage/src/sequence.rs index 30f9491cb..6d953f79c 100644 --- a/packages/storage/src/sequence.rs +++ b/packages/storage/src/sequence.rs @@ -3,18 +3,27 @@ use cosmwasm_std::{StdResult, Storage}; use crate::Singleton; /// Sequence creates a custom Singleton to hold an empty sequence +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn sequence<'a>(storage: &'a mut dyn Storage, key: &[u8]) -> Singleton<'a, u64> { Singleton::new(storage, key) } /// currval returns the last value returned by nextval. If the sequence has never been used, /// then it will return 0. +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn currval(seq: &Singleton) -> StdResult { Ok(seq.may_load()?.unwrap_or_default()) } /// nextval increments the counter by 1 and returns the new value. /// On the first time it is called (no sequence info in db) it will return 1. +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn nextval(seq: &mut Singleton) -> StdResult { let val = currval(seq)? + 1; seq.save(&val)?; diff --git a/packages/storage/src/singleton.rs b/packages/storage/src/singleton.rs index 782002b97..3d5e5c956 100644 --- a/packages/storage/src/singleton.rs +++ b/packages/storage/src/singleton.rs @@ -1,12 +1,14 @@ use serde::{de::DeserializeOwned, ser::Serialize}; use std::marker::PhantomData; -use cosmwasm_std::{to_vec, StdError, StdResult, Storage}; +use cosmwasm_std::{storage_keys::to_length_prefixed, to_vec, StdError, StdResult, Storage}; -use crate::length_prefixed::to_length_prefixed; use crate::type_helpers::{may_deserialize, must_deserialize}; /// An alias of Singleton::new for less verbose usage +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn singleton<'a, T>(storage: &'a mut dyn Storage, key: &[u8]) -> Singleton<'a, T> where T: Serialize + DeserializeOwned, @@ -15,6 +17,9 @@ where } /// An alias of ReadonlySingleton::new for less verbose usage +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub fn singleton_read<'a, T>(storage: &'a dyn Storage, key: &[u8]) -> ReadonlySingleton<'a, T> where T: Serialize + DeserializeOwned, @@ -26,6 +31,9 @@ where /// work on a single storage key. It performs the to_length_prefixed transformation /// on the given name to ensure no collisions, and then provides the standard /// TypedStorage accessors, without requiring a key (which is defined in the constructor) +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub struct Singleton<'a, T> where T: Serialize + DeserializeOwned, @@ -89,6 +97,9 @@ where /// ReadonlySingleton only requires a Storage and exposes only the /// methods of Singleton that don't modify state. +#[deprecated( + note = "The crate cosmwasm-storage is unmaintained and will be removed in CosmWasm 2.0. Please consider migrating to cw-storage-plus or simple cosmwasm-std storage calls." +)] pub struct ReadonlySingleton<'a, T> where T: Serialize + DeserializeOwned, @@ -260,7 +271,7 @@ mod tests { }); match output.unwrap_err() { StdError::Overflow { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } assert_eq!(writer.load().unwrap(), cfg); } @@ -303,7 +314,7 @@ mod tests { }); match res.unwrap_err() { MyError::Std(StdError::GenericErr { .. }) => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } assert_eq!(writer.load().unwrap(), cfg); } diff --git a/packages/storage/src/type_helpers.rs b/packages/storage/src/type_helpers.rs index 6a36f074e..233d2b146 100644 --- a/packages/storage/src/type_helpers.rs +++ b/packages/storage/src/type_helpers.rs @@ -83,7 +83,7 @@ mod tests { StdError::NotFound { kind, .. } => { assert_eq!(kind, "cosmwasm_storage::type_helpers::tests::Person") } - e => panic!("Unexpected error {}", e), + e => panic!("Unexpected error {e}"), } } } diff --git a/packages/vm/Cargo.toml b/packages/vm/Cargo.toml index 247b14e81..200c109b6 100644 --- a/packages/vm/Cargo.toml +++ b/packages/vm/Cargo.toml @@ -34,25 +34,22 @@ allow_interface_version_7 = [] # See https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options bench = false -[[example]] -name = "check_contract" -required-features = ["iterator"] - [dependencies] +bytes = "1.4.0" # need a higher version than the one required by Wasmer for the Bytes -> Vec implementation clru = "0.4.0" +crc32fast = "1.3.2" # Uses the path when built locally; uses the given version from crates.io when published cosmwasm-std = { path = "../std", version = "1.1.9+0.8.1", default-features = false } cosmwasm-crypto = { path = "../crypto", version = "1.1.9+0.8.1" } +derivative = "2" hex = "0.4" -parity-wasm = "0.42" schemars = "0.8.3" serde = { version = "1.0.103", default-features = false, features = ["derive", "alloc"] } serde_json = "1.0.40" sha2 = "0.10.3" -thiserror = "1.0.13" -wasmer = { version = "=2.3.0", default-features = false, features = ["cranelift", "universal", "singlepass"] } -wasmer-middlewares = "=2.3.0" -loupe = "0.1.3" +thiserror = "1.0.26" +wasmer = { version = "=4.1.2", default-features = false, features = ["cranelift", "singlepass"] } +wasmer-middlewares = "=4.1.2" # Dependencies that we do not use ourself. We add those entries # to bump the min version of them. @@ -61,19 +58,21 @@ enumset = "1.0.2" # Fixes https://github.com/Lymia/enumset/issues/17 (https://gi bitflags = "1.1.0" # https://github.com/CensoredUsername/dynasm-rs/pull/74 # Wasmer git/local (used for quick local debugging or patching) -# wasmer = { git = "https://github.com/wasmerio/wasmer", rev = "877ce1f7c44fad853c", default-features = false, features = ["cranelift", "universal", "singlepass"] } +# wasmer = { git = "https://github.com/wasmerio/wasmer", rev = "877ce1f7c44fad853c", default-features = false, features = ["cranelift", "singlepass"] } # wasmer-middlewares = { git = "https://github.com/wasmerio/wasmer", rev = "877ce1f7c44fad853c" } -# wasmer = { path = "../../../wasmer/lib/api", default-features = false, features = ["cranelift", "universal", "singlepass"] } +# wasmer = { path = "../../../wasmer/lib/api", default-features = false, features = ["cranelift", "singlepass"] } # wasmer-middlewares = { path = "../../../wasmer/lib/middlewares" } [dev-dependencies] -criterion = { version = "0.3", features = [ "html_reports" ] } +criterion = { version = "0.4", features = [ "html_reports" ] } +glob = "0.3.1" hex-literal = "0.3.1" tempfile = "3.1.0" wat = "1.0" -clap = "2.33.3" +clap = "4" rand = "0.8" leb128 = "0.2" +target-lexicon = "0.12" [[bench]] name = "main" diff --git a/packages/vm/README.md b/packages/vm/README.md index 5713d1792..c914981ee 100644 --- a/packages/vm/README.md +++ b/packages/vm/README.md @@ -50,23 +50,40 @@ run through [rust-optimizer](https://github.com/CosmWasm/rust-optimizer). To rebuild the test contracts, go to the repo root and do ```sh +docker run --rm -v "$(pwd)":/code \ + --mount type=volume,source="devcontract_cache_cyberpunk",target=/code/contracts/cyberpunk/target \ + --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ + cosmwasm/rust-optimizer:0.12.13 ./contracts/cyberpunk \ + && cp artifacts/cyberpunk.wasm packages/vm/testdata/cyberpunk.wasm + docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_hackatom",target=/code/contracts/hackatom/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/hackatom \ - && cp artifacts/hackatom.wasm packages/vm/testdata/hackatom_1.0.wasm + cosmwasm/rust-optimizer:0.12.13 ./contracts/hackatom \ + && cp artifacts/hackatom.wasm packages/vm/testdata/hackatom_1.2.wasm docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_ibc_reflect",target=/code/contracts/ibc-reflect/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/ibc-reflect \ - && cp artifacts/ibc_reflect.wasm packages/vm/testdata/ibc_reflect_1.0.wasm + cosmwasm/rust-optimizer:0.12.13 ./contracts/ibc-reflect \ + && cp artifacts/ibc_reflect.wasm packages/vm/testdata/ibc_reflect_1.2.wasm docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="devcontract_cache_floaty",target=/code/contracts/floaty/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ - cosmwasm/rust-optimizer:0.12.9 ./contracts/floaty \ - && cp artifacts/floaty.wasm packages/vm/testdata/floaty_1.0.wasm + cosmwasm/rust-optimizer:0.12.13 ./contracts/floaty \ + && cp artifacts/floaty.wasm packages/vm/testdata/floaty_1.2.wasm +``` + +The `cyberpunk_rust170.wasm` for +https://github.com/CosmWasm/cosmwasm/issues/1727 is built as follows +(non-reproducible): + +```sh +cd contracts/cyberpunk +rm -r target +RUSTFLAGS='-C link-arg=-s' cargo build --release --lib --target wasm32-unknown-unknown --locked +cp target/wasm32-unknown-unknown/release/cyberpunk.wasm ../../packages/vm/testdata/cyberpunk_rust170.wasm ``` ## Testing diff --git a/packages/vm/benches/main.rs b/packages/vm/benches/main.rs index 970a1ca9c..e0911e380 100644 --- a/packages/vm/benches/main.rs +++ b/packages/vm/benches/main.rs @@ -32,6 +32,7 @@ const INSTANTIATION_THREADS: usize = 128; const CONTRACTS: u64 = 10; static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); +static CYBERPUNK: &[u8] = include_bytes!("../testdata/cyberpunk.wasm"); fn bench_instance(c: &mut Criterion) { let mut group = c.benchmark_group("Instance"); @@ -94,12 +95,11 @@ fn bench_instance(c: &mut Criterion) { ..DEFAULT_INSTANCE_OPTIONS }; let mut instance = - Instance::from_code(CONTRACT, backend, much_gas, Some(DEFAULT_MEMORY_LIMIT)).unwrap(); + Instance::from_code(CYBERPUNK, backend, much_gas, Some(DEFAULT_MEMORY_LIMIT)).unwrap(); let info = mock_info("creator", &coins(1000, "earth")); - let msg = br#"{"verifier": "verifies", "beneficiary": "benefits"}"#; let contract_result = - call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, msg).unwrap(); + call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, b"{}").unwrap(); assert!(contract_result.into_result().is_ok()); let mut gas_used = 0; @@ -112,7 +112,7 @@ fn bench_instance(c: &mut Criterion) { assert!(contract_result.into_result().is_ok()); gas_used = gas_before - instance.get_gas_left(); }); - println!("Gas used: {}", gas_used); + println!("Gas used: {gas_used}"); }); group.finish(); @@ -149,6 +149,19 @@ fn bench_cache(c: &mut Criterion) { }); }); + group.bench_function("load wasm unchecked", |b| { + let options = CacheOptions { ..options.clone() }; + let mut cache: Cache = + unsafe { Cache::new(options).unwrap() }; + cache.set_module_unchecked(true); + let checksum = cache.save_wasm(CONTRACT).unwrap(); + + b.iter(|| { + let result = cache.load_wasm(&checksum); + assert!(result.is_ok()); + }); + }); + group.bench_function("analyze", |b| { let cache: Cache = unsafe { Cache::new(options.clone()).unwrap() }; @@ -182,6 +195,29 @@ fn bench_cache(c: &mut Criterion) { }); }); + group.bench_function("instantiate from fs unchecked", |b| { + let non_memcache = CacheOptions { + base_dir: TempDir::new().unwrap().into_path(), + available_capabilities: capabilities_from_csv("iterator,staking"), + memory_cache_size: Size(0), + instance_memory_limit: DEFAULT_MEMORY_LIMIT, + }; + let mut cache: Cache = + unsafe { Cache::new(non_memcache).unwrap() }; + cache.set_module_unchecked(true); + let checksum = cache.save_wasm(CONTRACT).unwrap(); + + b.iter(|| { + let _ = cache + .get_instance(&checksum, mock_backend(&[]), DEFAULT_INSTANCE_OPTIONS) + .unwrap(); + assert_eq!(cache.stats().hits_pinned_memory_cache, 0); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert!(cache.stats().hits_fs_cache >= 1); + assert_eq!(cache.stats().misses, 0); + }); + }); + group.bench_function("instantiate from memory", |b| { let checksum = Checksum::generate(CONTRACT); let cache: Cache = diff --git a/packages/vm/examples/check_contract.rs b/packages/vm/examples/check_contract.rs deleted file mode 100644 index 1d53b164e..000000000 --- a/packages/vm/examples/check_contract.rs +++ /dev/null @@ -1,57 +0,0 @@ -use std::fs::File; -use std::io::Read; - -use clap::{App, Arg}; - -use cosmwasm_vm::capabilities_from_csv; -use cosmwasm_vm::internals::{check_wasm, compile}; - -const DEFAULT_AVAILABLE_CAPABILITIES: &str = "iterator,staking,stargate,cosmwasm_1_1"; - -pub fn main() { - eprintln!("`check_contract` will be removed from the next version of `cosmwasm-vm` - please use `cosmwasm-check` instead."); - eprintln!("> cargo install cosmwasm-check"); - - let matches = App::new("Contract checking") - .version("0.1.0") - .long_about("Checks the given wasm file (memories, exports, imports, available capabilities, and non-determinism).") - .author("Mauro Lacy ") - .arg( - Arg::with_name("CAPABILITIES") - // `long` setting required to turn the position argument into an option 🤷 - .long("available-capabilities") - .aliases(&["FEATURES", "supported-features"]) // Old names - .value_name("CAPABILITIES") - .help("Sets the available capabilities that the desired target chain has") - .takes_value(true) - ) - .arg( - Arg::with_name("WASM") - .help("Wasm file to read and compile") - .required(true) - .index(1), - ) - .get_matches(); - - // Available capabilities - let available_capabilities_csv = matches - .value_of("CAPABILITIES") - .unwrap_or(DEFAULT_AVAILABLE_CAPABILITIES); - let available_capabilities = capabilities_from_csv(available_capabilities_csv); - println!("Available capabilities: {:?}", available_capabilities); - - // File - let path = matches.value_of("WASM").expect("Error parsing file name"); - let mut file = File::open(path).unwrap(); - - // Read wasm - let mut wasm = Vec::::new(); - file.read_to_end(&mut wasm).unwrap(); - - // Check wasm - check_wasm(&wasm, &available_capabilities).unwrap(); - - // Compile module - compile(&wasm, None, &[]).unwrap(); - println!("contract checks passed.") -} diff --git a/packages/vm/examples/module_size.rs b/packages/vm/examples/module_size.rs index ac62a6b69..9b1f1d973 100644 --- a/packages/vm/examples/module_size.rs +++ b/packages/vm/examples/module_size.rs @@ -2,19 +2,17 @@ use std::fs::File; use std::io::Read; use std::mem; -use clap::{App, Arg}; +use clap::{Arg, Command}; -use cosmwasm_vm::internals::compile; -use cosmwasm_vm::internals::make_runtime_store; -use cosmwasm_vm::Size; -use wasmer::Module; +use cosmwasm_vm::internals::{compile, make_compiling_engine}; +use wasmer::{Engine, Module}; pub fn main() { - let matches = App::new("Module size estimation") - .version("0.0.3") - .author("Mauro Lacy ") + let matches = Command::new("Module size estimation") + .version("0.0.4") + .author("Mauro Lacy ") .arg( - Arg::with_name("WASM") + Arg::new("WASM") .help("Wasm file to read and compile") .required(true) .index(1), @@ -22,7 +20,7 @@ pub fn main() { .get_matches(); // File - let path = matches.value_of("WASM").expect("Error parsing file name"); + let path: &String = matches.get_one("WASM").expect("Error parsing file name"); let mut file = File::open(path).unwrap(); mem::drop(matches); @@ -33,34 +31,25 @@ pub fn main() { // Report wasm size let wasm_size = wasm.len(); - println!("wasm size: {} bytes", wasm_size); - - let memory_limit = Some(Size::mebi(10)); + println!("wasm size: {wasm_size} bytes"); // Compile module - let module = module_compile(&wasm, memory_limit); + let engine = make_compiling_engine(None); + let module = compile(&engine, &wasm).unwrap(); mem::drop(wasm); - // Report loupe size - let loupe_size = loupe::size_of_val(&module); - println!("module size (loupe): {} bytes", loupe_size); - let serialized = module.serialize().unwrap(); mem::drop(module); // Deserialize module - let module = module_deserialize(&serialized, memory_limit); + let module = module_deserialize(&engine, &serialized); mem::drop(serialized); // Report (serialized) module size let serialized = module.serialize().unwrap(); mem::drop(module); let ser_size = serialized.len(); - println!("module size (serialized): {} bytes", ser_size); - println!( - "(loupe) module size ratio: {:.2}", - loupe_size as f32 / wasm_size as f32 - ); + println!("module size (serialized): {ser_size} bytes"); println!( "(serialized) module size ratio: {:.2}", ser_size as f32 / wasm_size as f32 @@ -68,13 +57,6 @@ pub fn main() { } #[inline(never)] -fn module_compile(wasm: &[u8], memory_limit: Option) -> Module { - compile(wasm, memory_limit, &[]).unwrap() -} - -#[inline(never)] -fn module_deserialize(serialized: &[u8], memory_limit: Option) -> Module { - // Deserialize using make_runtime_store() - let store = make_runtime_store(memory_limit); - unsafe { Module::deserialize(&store, serialized) }.unwrap() +fn module_deserialize(engine: &Engine, serialized: &[u8]) -> Module { + unsafe { Module::deserialize(&engine, serialized) }.unwrap() } diff --git a/packages/vm/examples/module_size.sh b/packages/vm/examples/module_size.sh index 80ed757a4..59bc4aa5f 100755 --- a/packages/vm/examples/module_size.sh +++ b/packages/vm/examples/module_size.sh @@ -1,8 +1,7 @@ #!/bin/bash # Uses valgrind's massif tool to compute heap memory consumption of compiled modules. -# For a wasmer `Modulej , it has been determined that this method underestimates the size +# For a wasmer `Module`, it has been determined that this method underestimates the size # of the module significanty. -# Use loupe::size_of_val instead, to get a better estimation. set -e MAX_SNAPSHOTS=1000 diff --git a/packages/vm/examples/multi_threaded_cache.rs b/packages/vm/examples/multi_threaded_cache.rs index 16053ee92..7be56be40 100644 --- a/packages/vm/examples/multi_threaded_cache.rs +++ b/packages/vm/examples/multi_threaded_cache.rs @@ -44,10 +44,10 @@ pub fn main() { threads.push(thread::spawn(move || { let checksum = cache.save_wasm(CONTRACT).unwrap(); - println!("Done saving Wasm {}", checksum); + println!("Done saving Wasm {checksum}"); })); } - for _ in 0..INSTANTIATION_THREADS { + for i in 0..INSTANTIATION_THREADS { let cache = Arc::clone(&cache); threads.push(thread::spawn(move || { @@ -55,7 +55,7 @@ pub fn main() { let mut instance = cache .get_instance(&checksum, mock_backend(&[]), DEFAULT_INSTANCE_OPTIONS) .unwrap(); - println!("Done instantiating contract"); + println!("Done instantiating contract {i}"); let info = mock_info("creator", &coins(1000, "earth")); let msg = br#"{"verifier": "verifies", "beneficiary": "benefits"}"#; @@ -74,7 +74,7 @@ pub fn main() { threads.into_iter().for_each(|thread| { thread .join() - .expect("The thread creating or execution failed !") + .expect("The threaded instantiation or execution failed !") }); assert_eq!(cache.stats().misses, 0); diff --git a/packages/vm/src/backend.rs b/packages/vm/src/backend.rs index ea9a08500..bd81d466c 100644 --- a/packages/vm/src/backend.rs +++ b/packages/vm/src/backend.rs @@ -10,6 +10,10 @@ use cosmwasm_std::{Order, Record}; /// A structure that represents gas cost to be deducted from the remaining gas. /// This is always needed when computations are performed outside of /// Wasm execution, such as calling crypto APIs or calls into the blockchain. +/// +/// All values are measured in [CosmWasm gas]. +/// +/// [CosmWasm gas]: https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct GasInfo { /// The gas cost of a computation that was executed already but not yet charged. @@ -19,6 +23,12 @@ pub struct GasInfo { pub cost: u64, /// Gas that was used and charged externally. This is needed to /// adjust the VM's gas limit but does not affect the gas usage. + /// + /// Since this is measured in [CosmWasm gas], the caller may need + /// to convert from Cosmos SDK gas in cases where an SDK gas meter + /// is used. + /// + /// [CosmWasm gas]: https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md pub externally_used: u64, } @@ -112,6 +122,34 @@ pub trait Storage { #[cfg(feature = "iterator")] fn next(&mut self, iterator_id: u32) -> BackendResult>; + /// Returns the next value of the iterator with the given ID. + /// Since the iterator is incremented, the corresponding key will never be accessible. + /// + /// If the ID is not found, a BackendError::IteratorDoesNotExist is returned. + /// + /// The default implementation uses [`Storage::next`] and discards the key. + /// More efficient implementations might be possible depending on the storage. + #[cfg(feature = "iterator")] + fn next_value(&mut self, iterator_id: u32) -> BackendResult>> { + let (result, gas_info) = self.next(iterator_id); + let result = result.map(|record| record.map(|(_, v)| v)); + (result, gas_info) + } + + /// Returns the next key of the iterator with the given ID. + /// Since the iterator is incremented, the corresponding value will never be accessible. + /// + /// If the ID is not found, a BackendError::IteratorDoesNotExist is returned. + /// + /// The default implementation uses [`Storage::next`] and discards the value. + /// More efficient implementations might be possible depending on the storage. + #[cfg(feature = "iterator")] + fn next_key(&mut self, iterator_id: u32) -> BackendResult>> { + let (result, gas_info) = self.next(iterator_id); + let result = result.map(|record| record.map(|(k, _)| k)); + (result, gas_info) + } + fn set(&mut self, key: &[u8], value: &[u8]) -> BackendResult<()>; /// Removes a database entry at `key`. @@ -141,10 +179,12 @@ pub trait Querier { /// knowing the custom format, or we can decode it, with the knowledge of the allowed /// types. /// - /// The gas limit describes how much VM gas this particular query is allowed + /// The gas limit describes how much [CosmWasm gas] this particular query is allowed /// to comsume when measured separately from the rest of the contract. /// The returned gas info (in BackendResult) can exceed the gas limit in cases /// where the query could not be aborted exactly at the limit. + /// + /// [CosmWasm gas]: https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md fn query_raw( &self, request: &[u8], @@ -153,8 +193,8 @@ pub trait Querier { } /// A result type for calling into the backend. Such a call can cause -/// non-negligible computational cost in both success and faiure case and must always have gas information -/// attached. +/// non-negligible computational cost in both success and faiure case and +/// must always have gas information attached. pub type BackendResult = (core::result::Result, GasInfo); #[derive(Error, Debug, PartialEq, Eq)] @@ -304,7 +344,7 @@ mod tests { let error = BackendError::foreign_panic(); match error { BackendError::ForeignPanic { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -313,7 +353,7 @@ mod tests { let error = BackendError::bad_argument(); match error { BackendError::BadArgument { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -322,7 +362,7 @@ mod tests { let error = BackendError::iterator_does_not_exist(15); match error { BackendError::IteratorDoesNotExist { id, .. } => assert_eq!(id, 15), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -331,7 +371,7 @@ mod tests { let error = BackendError::out_of_gas(); match error { BackendError::OutOfGas { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -340,7 +380,7 @@ mod tests { let error = BackendError::unknown("broken"); match error { BackendError::Unknown { msg, .. } => assert_eq!(msg, "broken"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -349,7 +389,7 @@ mod tests { let error = BackendError::user_err("invalid input"); match error { BackendError::UserErr { msg, .. } => assert_eq!(msg, "invalid input"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -360,7 +400,7 @@ mod tests { let error: BackendError = String::from_utf8(vec![0x80]).unwrap_err().into(); match error { BackendError::InvalidUtf8 { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } } diff --git a/packages/vm/src/cache.rs b/packages/vm/src/cache.rs index 6310f3ca4..28fa20d3b 100644 --- a/packages/vm/src/cache.rs +++ b/packages/vm/src/cache.rs @@ -1,20 +1,23 @@ use std::collections::HashSet; -use std::fs::{create_dir_all, File, OpenOptions}; +use std::fs::{self, File, OpenOptions}; use std::io::{Read, Write}; use std::marker::PhantomData; use std::path::{Path, PathBuf}; use std::sync::Mutex; +use wasmer::{Engine, Store}; use crate::backend::{Backend, BackendApi, Querier, Storage}; use crate::capabilities::required_capabilities_from_module; use crate::checksum::Checksum; use crate::compatibility::check_wasm; use crate::errors::{VmError, VmResult}; +use crate::filesystem::mkdir_p; use crate::instance::{Instance, InstanceOptions}; -use crate::modules::{FileSystemCache, InMemoryCache, PinnedMemoryCache}; +use crate::modules::{CachedModule, FileSystemCache, InMemoryCache, PinnedMemoryCache}; +use crate::parsed_wasm::ParsedWasm; use crate::size::Size; -use crate::static_analysis::{deserialize_wasm, has_ibc_entry_points}; -use crate::wasm_backend::{compile, make_runtime_store}; +use crate::static_analysis::has_ibc_entry_points; +use crate::wasm_backend::{compile, make_compiling_engine, make_runtime_engine}; const STATE_DIR: &str = "state"; // Things related to the state of the blockchain. @@ -24,6 +27,13 @@ const CACHE_DIR: &str = "cache"; // Cacheable things. const MODULES_DIR: &str = "modules"; +/// Statistics about the usage of a cache instance. Those values are node +/// specific and must not be used in a consensus critical context. +/// When a node is hit by a client for simulations or other queries, hits and misses +/// increase. Also a node restart will reset the values. +/// +/// All values should be increment using saturated addition to ensure the node does not +/// crash in case the stats exceed the integer limit. #[derive(Debug, Default, Clone, Copy)] pub struct Stats { pub hits_pinned_memory_cache: u32, @@ -43,6 +53,10 @@ pub struct Metrics { #[derive(Clone, Debug)] pub struct CacheOptions { + /// The base directory of this cache. + /// + /// If this does not exist, it will be created. Not sure if this behaviour + /// is desired but wasmd relies on it. pub base_dir: PathBuf, pub available_capabilities: HashSet, pub memory_cache_size: Size, @@ -52,14 +66,23 @@ pub struct CacheOptions { } pub struct CacheInner { + /// The directory in which the Wasm blobs are stored in the file system. wasm_path: PathBuf, - /// Instances memory limit in bytes. Use a value that is divisible by the Wasm page size 65536, - /// e.g. full MiBs. - instance_memory_limit: Size, pinned_memory_cache: PinnedMemoryCache, memory_cache: InMemoryCache, fs_cache: FileSystemCache, stats: Stats, + /// A single engine to execute all contracts in this cache instance (usually + /// this means all contracts in the process). + /// + /// This engine is headless, i.e. does not contain a Singlepass compiler. + /// It only executes modules compiled with other engines. + /// + /// The engine has one memory limit set which is the same for all contracts + /// running with it. If different memory limits would be needed for different + /// contracts at some point, we'd need multiple engines. This is because the tunables + /// that control the limit are attached to the engine. + runtime_engine: Engine, } pub struct Cache { @@ -108,27 +131,21 @@ where let wasm_path = state_path.join(WASM_DIR); // Ensure all the needed directories exist on disk. - for path in [&state_path, &cache_path, &wasm_path].iter() { - create_dir_all(path).map_err(|e| { - VmError::cache_err(format!( - "Error creating directory {}: {}", - path.display(), - e - )) - })?; - } + mkdir_p(&state_path).map_err(|_e| VmError::cache_err("Error creating state directory"))?; + mkdir_p(&cache_path).map_err(|_e| VmError::cache_err("Error creating cache directory"))?; + mkdir_p(&wasm_path).map_err(|_e| VmError::cache_err("Error creating wasm directory"))?; - let fs_cache = FileSystemCache::new(cache_path.join(MODULES_DIR)) - .map_err(|e| VmError::cache_err(format!("Error file system cache: {}", e)))?; + let fs_cache = FileSystemCache::new(cache_path.join(MODULES_DIR), false) + .map_err(|e| VmError::cache_err(format!("Error file system cache: {e}")))?; Ok(Cache { available_capabilities, inner: Mutex::new(CacheInner { wasm_path, - instance_memory_limit, pinned_memory_cache: PinnedMemoryCache::new(), memory_cache: InMemoryCache::new(memory_cache_size), fs_cache, stats: Stats::default(), + runtime_engine: make_runtime_engine(Some(instance_memory_limit)), }), type_storage: PhantomData::, type_api: PhantomData::, @@ -137,6 +154,16 @@ where }) } + /// If `unchecked` is true, the filesystem cache will use the `*_unchecked` wasmer functions for + /// loading modules from disk. + pub fn set_module_unchecked(&mut self, unchecked: bool) { + self.inner + .lock() + .unwrap() + .fs_cache + .set_module_unchecked(unchecked); + } + pub fn stats(&self) -> Stats { self.inner.lock().unwrap().stats } @@ -152,9 +179,30 @@ where } } + /// Takes a Wasm bytecode and stores it to the cache. + /// + /// This performs static checks, compiles the bytescode to a module and + /// stores the Wasm file on disk. + /// + /// This does the same as [`save_wasm_unchecked`] plus the static checks. + /// When a Wasm blob is stored the first time, use this function. pub fn save_wasm(&self, wasm: &[u8]) -> VmResult { check_wasm(wasm, &self.available_capabilities)?; - let module = compile(wasm, None, &[])?; + self.save_wasm_unchecked(wasm) + } + + /// Takes a Wasm bytecode and stores it to the cache. + /// + /// This compiles the bytescode to a module and + /// stores the Wasm file on disk. + /// + /// This does the same as [`save_wasm`] but without the static checks. + /// When a Wasm blob is stored which was previously checked (e.g. as part of state sync), + /// use this function. + pub fn save_wasm_unchecked(&self, wasm: &[u8]) -> VmResult { + // We need a new engine for each Wasm -> module compilation due to the metering middleware. + let compiling_engine = make_compiling_engine(None); + let module = compile(&compiling_engine, wasm)?; let mut cache = self.inner.lock().unwrap(); let checksum = save_wasm_to_disk(&cache.wasm_path, wasm)?; @@ -162,6 +210,25 @@ where Ok(checksum) } + /// Removes the Wasm blob for the given checksum from disk and its + /// compiled module from the file system cache. + /// + /// The existence of the original code is required since the caller (wasmd) + /// has to keep track of which entries we have here. + pub fn remove_wasm(&self, checksum: &Checksum) -> VmResult<()> { + let mut cache = self.inner.lock().unwrap(); + + // Remove compiled moduled from disk (if it exists). + // Here we could also delete from memory caches but this is not really + // necessary as they are pushed out from the LRU over time or disappear + // when the node process restarts. + cache.fs_cache.remove(checksum)?; + + let path = &cache.wasm_path; + remove_wasm_from_disk(path, checksum)?; + Ok(()) + } + /// Retrieves a Wasm blob that was previously stored via save_wasm. /// When the cache is instantiated with the same base dir, this finds Wasm files on disc across multiple cache instances (i.e. node restarts). /// This function is public to allow a checksum to Wasm lookup in the blockchain. @@ -188,7 +255,7 @@ where pub fn analyze(&self, checksum: &Checksum) -> VmResult { // Here we could use a streaming deserializer to slightly improve performance. However, this way it is DRYer. let wasm = self.load_wasm(checksum)?; - let module = deserialize_wasm(&wasm)?; + let module = ParsedWasm::parse(&wasm)?; Ok(AnalysisReport { has_ibc_entry_points: has_ibc_entry_points(&module), required_capabilities: required_capabilities_from_module(&module), @@ -197,40 +264,38 @@ where /// Pins a Module that was previously stored via save_wasm. /// - /// The module is lookup first in the memory cache, and then in the file system cache. - /// If not found, the code is loaded from the file system, compiled, and stored into the + /// The module is lookup first in the file system cache. If not found, + /// the code is loaded from the file system, compiled, and stored into the /// pinned cache. - /// If the given ID is not found, or the content does not match the hash (=ID), an error is returned. + /// + /// If the given contract for the given checksum is not found, or the content + /// does not match the checksum, an error is returned. pub fn pin(&self, checksum: &Checksum) -> VmResult<()> { let mut cache = self.inner.lock().unwrap(); if cache.pinned_memory_cache.has(checksum) { return Ok(()); } - // Try to get module from the memory cache - if let Some(module) = cache.memory_cache.load(checksum)? { - cache.stats.hits_memory_cache += 1; - return cache - .pinned_memory_cache - .store(checksum, module.module, module.size); - } + // We don't load from the memory cache because we had to create new store here and + // serialize/deserialize the artifact to get a full clone. Could be done but adds some code + // for a not-so-relevant use case. // Try to get module from file system cache - let store = make_runtime_store(Some(cache.instance_memory_limit)); - if let Some(module) = cache.fs_cache.load(checksum, &store)? { - cache.stats.hits_fs_cache += 1; - let module_size = loupe::size_of_val(&module); + if let Some((module, module_size)) = cache.fs_cache.load(checksum, &cache.runtime_engine)? { + cache.stats.hits_fs_cache = cache.stats.hits_fs_cache.saturating_add(1); return cache .pinned_memory_cache .store(checksum, module, module_size); } // Re-compile from original Wasm bytecode - let code = self.load_wasm_with_path(&cache.wasm_path, checksum)?; - let module = compile(&code, Some(cache.instance_memory_limit), &[])?; + let wasm = self.load_wasm_with_path(&cache.wasm_path, checksum)?; + cache.stats.misses = cache.stats.misses.saturating_add(1); + // Module will run with a different engine, so we can set memory limit to None + let engine = make_compiling_engine(None); + let module = compile(&engine, &wasm)?; // Store into the fs cache too - cache.fs_cache.store(checksum, &module)?; - let module_size = loupe::size_of_val(&module); + let module_size = cache.fs_cache.store(checksum, &module)?; cache .pinned_memory_cache .store(checksum, module, module_size) @@ -257,9 +322,10 @@ where backend: Backend, options: InstanceOptions, ) -> VmResult> { - let module = self.get_module(checksum)?; + let (cached, store) = self.get_module(checksum)?; let instance = Instance::from_module( - &module, + store, + &cached.module, backend, options.gas_limit, options.print_debug, @@ -272,29 +338,36 @@ where /// Returns a module tied to a previously saved Wasm. /// Depending on availability, this is either generated from a memory cache, file system cache or Wasm code. /// This is part of `get_instance` but pulled out to reduce the locking time. - fn get_module(&self, checksum: &Checksum) -> VmResult { + fn get_module(&self, checksum: &Checksum) -> VmResult<(CachedModule, Store)> { let mut cache = self.inner.lock().unwrap(); // Try to get module from the pinned memory cache - if let Some(module) = cache.pinned_memory_cache.load(checksum)? { - cache.stats.hits_pinned_memory_cache += 1; - return Ok(module); + if let Some(element) = cache.pinned_memory_cache.load(checksum)? { + cache.stats.hits_pinned_memory_cache = + cache.stats.hits_pinned_memory_cache.saturating_add(1); + let store = Store::new(cache.runtime_engine.clone()); + return Ok((element, store)); } // Get module from memory cache - if let Some(module) = cache.memory_cache.load(checksum)? { - cache.stats.hits_memory_cache += 1; - return Ok(module.module); + if let Some(element) = cache.memory_cache.load(checksum)? { + cache.stats.hits_memory_cache = cache.stats.hits_memory_cache.saturating_add(1); + let store = Store::new(cache.runtime_engine.clone()); + return Ok((element, store)); } // Get module from file system cache - let store = make_runtime_store(Some(cache.instance_memory_limit)); - if let Some(module) = cache.fs_cache.load(checksum, &store)? { - cache.stats.hits_fs_cache += 1; - let module_size = loupe::size_of_val(&module); + if let Some((module, module_size)) = cache.fs_cache.load(checksum, &cache.runtime_engine)? { + cache.stats.hits_fs_cache = cache.stats.hits_fs_cache.saturating_add(1); + cache .memory_cache .store(checksum, module.clone(), module_size)?; - return Ok(module); + let cached = CachedModule { + module, + size_estimate: module_size, + }; + let store = Store::new(cache.runtime_engine.clone()); + return Ok((cached, store)); } // Re-compile module from wasm @@ -303,14 +376,21 @@ where // serialization format. If you do not replay all transactions, previous calls of `save_wasm` // stored the old module format. let wasm = self.load_wasm_with_path(&cache.wasm_path, checksum)?; - cache.stats.misses += 1; - let module = compile(&wasm, Some(cache.instance_memory_limit), &[])?; - cache.fs_cache.store(checksum, &module)?; - let module_size = loupe::size_of_val(&module); + cache.stats.misses = cache.stats.misses.saturating_add(1); + // Module will run with a different engine, so we can set memory limit to None + let engine = make_compiling_engine(None); + let module = compile(&engine, &wasm)?; + let module_size = cache.fs_cache.store(checksum, &module)?; + cache .memory_cache .store(checksum, module.clone(), module_size)?; - Ok(module) + let cached = CachedModule { + module, + size_estimate: module_size, + }; + let store = Store::new(cache.runtime_engine.clone()); + Ok((cached, store)) } } @@ -337,7 +417,7 @@ fn save_wasm_to_disk(dir: impl Into, wasm: &[u8]) -> VmResult // calculate filename let checksum = Checksum::generate(wasm); let filename = checksum.to_hex(); - let filepath = dir.into().join(&filename); + let filepath = dir.into().join(filename).with_extension("wasm"); // write data to file // Since the same filename (a collision resistent hash) cannot be generated from two different byte codes @@ -346,25 +426,57 @@ fn save_wasm_to_disk(dir: impl Into, wasm: &[u8]) -> VmResult .write(true) .create(true) .open(filepath) - .map_err(|e| VmError::cache_err(format!("Error opening Wasm file for writing: {}", e)))?; + .map_err(|e| VmError::cache_err(format!("Error opening Wasm file for writing: {e}")))?; file.write_all(wasm) - .map_err(|e| VmError::cache_err(format!("Error writing Wasm file: {}", e)))?; + .map_err(|e| VmError::cache_err(format!("Error writing Wasm file: {e}")))?; Ok(checksum) } fn load_wasm_from_disk(dir: impl Into, checksum: &Checksum) -> VmResult> { // this requires the directory and file to exist + // The files previously had no extension, so to allow for a smooth transition, + // we also try to load the file without the wasm extension. let path = dir.into().join(checksum.to_hex()); - let mut file = File::open(path) - .map_err(|e| VmError::cache_err(format!("Error opening Wasm file for reading: {}", e)))?; + let mut file = File::open(path.with_extension("wasm")) + .or_else(|_| File::open(path)) + .map_err(|_e| VmError::cache_err("Error opening Wasm file for reading"))?; let mut wasm = Vec::::new(); file.read_to_end(&mut wasm) - .map_err(|e| VmError::cache_err(format!("Error reading Wasm file: {}", e)))?; + .map_err(|_e| VmError::cache_err("Error reading Wasm file"))?; Ok(wasm) } +/// Removes the Wasm blob for the given checksum from disk. +/// +/// In contrast to the file system cache, the existence of the original +/// code is required. So a non-existent file leads to an error as it +/// indicates a bug. +fn remove_wasm_from_disk(dir: impl Into, checksum: &Checksum) -> VmResult<()> { + // the files previously had no extension, so to allow for a smooth transition, we delete both + let path = dir.into().join(checksum.to_hex()); + let wasm_path = path.with_extension("wasm"); + + let path_exists = path.exists(); + let wasm_path_exists = wasm_path.exists(); + if !path_exists && !wasm_path_exists { + return Err(VmError::cache_err("Wasm file does not exist")); + } + + if path_exists { + fs::remove_file(path) + .map_err(|_e| VmError::cache_err("Error removing Wasm file from disk"))?; + } + + if wasm_path_exists { + fs::remove_file(wasm_path) + .map_err(|_e| VmError::cache_err("Error removing Wasm file from disk"))?; + } + + Ok(()) +} + #[cfg(test)] mod tests { use super::*; @@ -373,7 +485,7 @@ mod tests { use crate::errors::VmError; use crate::testing::{mock_backend, mock_env, mock_info, MockApi, MockQuerier, MockStorage}; use cosmwasm_std::{coins, Empty}; - use std::fs::OpenOptions; + use std::fs::{create_dir_all, remove_dir_all, OpenOptions}; use std::io::Write; use tempfile::TempDir; @@ -387,6 +499,14 @@ mod tests { static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); static IBC_CONTRACT: &[u8] = include_bytes!("../testdata/ibc_reflect.wasm"); + // Invalid because it doesn't contain required memory and exports + static INVALID_CONTRACT_WAT: &str = r#"(module + (type $t0 (func (param i32) (result i32))) + (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) + local.get $p0 + i32.const 1 + i32.add)) + "#; fn default_capabilities() -> HashSet { capabilities_from_csv("iterator,staking") @@ -412,6 +532,21 @@ mod tests { } } + #[test] + fn new_base_dir_will_be_created() { + let my_base_dir = TempDir::new() + .unwrap() + .into_path() + .join("non-existent-sub-dir"); + let options = CacheOptions { + base_dir: my_base_dir.clone(), + ..make_testing_options() + }; + assert!(!my_base_dir.is_dir()); + let _cache = unsafe { Cache::::new(options).unwrap() }; + assert!(my_base_dir.is_dir()); + } + #[test] fn save_wasm_works() { let cache: Cache = @@ -430,26 +565,16 @@ mod tests { #[test] fn save_wasm_rejects_invalid_contract() { - // Invalid because it doesn't contain required memory and exports - let wasm = wat::parse_str( - r#"(module - (type $t0 (func (param i32) (result i32))) - (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 - i32.const 1 - i32.add)) - "#, - ) - .unwrap(); + let wasm = wat::parse_str(INVALID_CONTRACT_WAT).unwrap(); let cache: Cache = unsafe { Cache::new(make_testing_options()).unwrap() }; let save_result = cache.save_wasm(&wasm); match save_result.unwrap_err() { VmError::StaticValidationErr { msg, .. } => { - assert_eq!(msg, "Wasm contract doesn\'t have a memory section") + assert_eq!(msg, "Wasm contract must contain exactly one memory") } - e => panic!("Unexpected error {:?}", e), + e => panic!("Unexpected error {e:?}"), } } @@ -471,6 +596,22 @@ mod tests { assert_eq!(cache.stats().misses, 0); } + #[test] + fn save_wasm_unchecked_works() { + let cache: Cache = + unsafe { Cache::new(make_testing_options()).unwrap() }; + cache.save_wasm_unchecked(CONTRACT).unwrap(); + } + + #[test] + fn save_wasm_unchecked_accepts_invalid_contract() { + let wasm = wat::parse_str(INVALID_CONTRACT_WAT).unwrap(); + + let cache: Cache = + unsafe { Cache::new(make_testing_options()).unwrap() }; + cache.save_wasm_unchecked(&wasm).unwrap(); + } + #[test] fn load_wasm_works() { let cache: Cache = @@ -523,10 +664,9 @@ mod tests { match cache.load_wasm(&checksum).unwrap_err() { VmError::CacheErr { msg, .. } => { - assert!(msg - .starts_with("Error opening Wasm file for reading: No such file or directory")) + assert_eq!(msg, "Error opening Wasm file for reading") } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -548,18 +688,50 @@ mod tests { .path() .join(STATE_DIR) .join(WASM_DIR) - .join(&checksum.to_hex()); + .join(checksum.to_hex()) + .with_extension("wasm"); let mut file = OpenOptions::new().write(true).open(filepath).unwrap(); file.write_all(b"broken data").unwrap(); let res = cache.load_wasm(&checksum); match res { Err(VmError::IntegrityErr { .. }) => {} - Err(e) => panic!("Unexpected error: {:?}", e), + Err(e) => panic!("Unexpected error: {e:?}"), Ok(_) => panic!("This must not succeed"), } } + #[test] + fn remove_wasm_works() { + let cache: Cache = + unsafe { Cache::new(make_testing_options()).unwrap() }; + + // Store + let checksum = cache.save_wasm(CONTRACT).unwrap(); + + // Exists + cache.load_wasm(&checksum).unwrap(); + + // Remove + cache.remove_wasm(&checksum).unwrap(); + + // Does not exist anymore + match cache.load_wasm(&checksum).unwrap_err() { + VmError::CacheErr { msg, .. } => { + assert_eq!(msg, "Error opening Wasm file for reading") + } + e => panic!("Unexpected error: {e:?}"), + } + + // Removing again fails + match cache.remove_wasm(&checksum).unwrap_err() { + VmError::CacheErr { msg, .. } => { + assert_eq!(msg, "Wasm file does not exist") + } + e => panic!("Unexpected error: {e:?}"), + } + } + #[test] fn get_instance_finds_cached_module() { let cache = unsafe { Cache::new(make_testing_options()).unwrap() }; @@ -611,11 +783,11 @@ mod tests { assert_eq!(cache.stats().hits_fs_cache, 1); assert_eq!(cache.stats().misses, 0); - // pinning hits the memory cache + // pinning hits the file system cache cache.pin(&checksum).unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 0); - assert_eq!(cache.stats().hits_memory_cache, 3); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 2); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // from pinned memory cache @@ -623,8 +795,8 @@ mod tests { .get_instance(&checksum, backend4, TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 1); - assert_eq!(cache.stats().hits_memory_cache, 3); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 2); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // from pinned memory cache again @@ -632,11 +804,41 @@ mod tests { .get_instance(&checksum, backend5, TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 2); - assert_eq!(cache.stats().hits_memory_cache, 3); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 2); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); } + #[test] + fn get_instance_recompiles_module() { + let options = make_testing_options(); + let cache = unsafe { Cache::new(options.clone()).unwrap() }; + let checksum = cache.save_wasm(CONTRACT).unwrap(); + + // Remove compiled module from disk + remove_dir_all(options.base_dir.join(CACHE_DIR).join(MODULES_DIR)).unwrap(); + + // The first get_instance recompiles the Wasm (miss) + let backend = mock_backend(&[]); + let _instance = cache + .get_instance(&checksum, backend, TESTING_OPTIONS) + .unwrap(); + assert_eq!(cache.stats().hits_pinned_memory_cache, 0); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert_eq!(cache.stats().hits_fs_cache, 0); + assert_eq!(cache.stats().misses, 1); + + // The second get_instance finds the module in cache (hit) + let backend = mock_backend(&[]); + let _instance = cache + .get_instance(&checksum, backend, TESTING_OPTIONS) + .unwrap(); + assert_eq!(cache.stats().hits_pinned_memory_cache, 0); + assert_eq!(cache.stats().hits_memory_cache, 1); + assert_eq!(cache.stats().hits_fs_cache, 0); + assert_eq!(cache.stats().misses, 1); + } + #[test] fn call_instantiate_on_cached_contract() { let cache = unsafe { Cache::new(make_testing_options()).unwrap() }; @@ -688,8 +890,8 @@ mod tests { .get_instance(&checksum, mock_backend(&[]), TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 1); - assert_eq!(cache.stats().hits_memory_cache, 2); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 1); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // init @@ -771,8 +973,8 @@ mod tests { .get_instance(&checksum, mock_backend(&[]), TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 1); - assert_eq!(cache.stats().hits_memory_cache, 2); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 1); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // init @@ -875,7 +1077,7 @@ mod tests { assert!(instance1.get_gas_left() < original_gas); // Init from memory cache - let instance2 = cache + let mut instance2 = cache .get_instance(&checksum, backend2, TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 0); @@ -909,7 +1111,7 @@ mod tests { .unwrap_err() { VmError::GasDepletion { .. } => (), // all good, continue - e => panic!("unexpected error, {:?}", e), + e => panic!("unexpected error, {e:?}"), } assert_eq!(instance1.get_gas_left(), 0); @@ -975,6 +1177,23 @@ mod tests { assert_eq!(code, loaded); } + #[test] + fn remove_wasm_from_disk_works() { + let tmp_dir = TempDir::new().unwrap(); + let path = tmp_dir.path(); + let code = vec![12u8; 17]; + let checksum = save_wasm_to_disk(path, &code).unwrap(); + + remove_wasm_from_disk(path, &checksum).unwrap(); + + // removing again fails + + match remove_wasm_from_disk(path, &checksum).unwrap_err() { + VmError::CacheErr { msg } => assert_eq!(msg, "Wasm file does not exist"), + err => panic!("Unexpected error: {err:?}"), + } + } + #[test] fn analyze_works() { let cache: Cache = @@ -996,9 +1215,8 @@ mod tests { report2, AnalysisReport { has_ibc_entry_points: true, - required_capabilities: HashSet::from_iter(vec![ + required_capabilities: HashSet::from_iter([ "iterator".to_string(), - "staking".to_string(), "stargate".to_string() ]), } @@ -1020,18 +1238,18 @@ mod tests { assert_eq!(cache.stats().hits_fs_cache, 1); assert_eq!(cache.stats().misses, 0); - // first pin hits memory cache + // first pin hits file system cache cache.pin(&checksum).unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 0); - assert_eq!(cache.stats().hits_memory_cache, 1); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // consecutive pins are no-ops cache.pin(&checksum).unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 0); - assert_eq!(cache.stats().hits_memory_cache, 1); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // check pinned @@ -1040,8 +1258,8 @@ mod tests { .get_instance(&checksum, backend, TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 1); - assert_eq!(cache.stats().hits_memory_cache, 1); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // unpin @@ -1053,8 +1271,8 @@ mod tests { .get_instance(&checksum, backend, TESTING_OPTIONS) .unwrap(); assert_eq!(cache.stats().hits_pinned_memory_cache, 1); - assert_eq!(cache.stats().hits_memory_cache, 2); - assert_eq!(cache.stats().hits_fs_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 1); + assert_eq!(cache.stats().hits_fs_cache, 2); assert_eq!(cache.stats().misses, 0); // unpin again has no effect @@ -1064,4 +1282,59 @@ mod tests { let non_id = Checksum::generate(b"non_existent"); cache.unpin(&non_id).unwrap(); } + + #[test] + fn pin_recompiles_module() { + let options = make_testing_options(); + let cache: Cache = + unsafe { Cache::new(options.clone()).unwrap() }; + let checksum = cache.save_wasm(CONTRACT).unwrap(); + + // Remove compiled module from disk + remove_dir_all(options.base_dir.join(CACHE_DIR).join(MODULES_DIR)).unwrap(); + + // Pin misses, forcing a re-compile of the module + cache.pin(&checksum).unwrap(); + assert_eq!(cache.stats().hits_pinned_memory_cache, 0); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert_eq!(cache.stats().hits_fs_cache, 0); + assert_eq!(cache.stats().misses, 1); + + // After the compilation in pin, the module can be used from pinned memory cache + let backend = mock_backend(&[]); + let _ = cache + .get_instance(&checksum, backend, TESTING_OPTIONS) + .unwrap(); + assert_eq!(cache.stats().hits_pinned_memory_cache, 1); + assert_eq!(cache.stats().hits_memory_cache, 0); + assert_eq!(cache.stats().hits_fs_cache, 0); + assert_eq!(cache.stats().misses, 1); + } + + #[test] + fn loading_without_extension_works() { + let tmp_dir = TempDir::new().unwrap(); + let options = CacheOptions { + base_dir: tmp_dir.path().to_path_buf(), + available_capabilities: default_capabilities(), + memory_cache_size: TESTING_MEMORY_CACHE_SIZE, + instance_memory_limit: TESTING_MEMORY_LIMIT, + }; + let cache: Cache = + unsafe { Cache::new(options).unwrap() }; + let checksum = cache.save_wasm(CONTRACT).unwrap(); + + // Move the saved wasm to the old path (without extension) + let old_path = tmp_dir + .path() + .join(STATE_DIR) + .join(WASM_DIR) + .join(checksum.to_hex()); + let new_path = old_path.with_extension("wasm"); + fs::rename(new_path, old_path).unwrap(); + + // loading wasm from before the wasm extension was added should still work + let restored = cache.load_wasm(&checksum).unwrap(); + assert_eq!(restored, CONTRACT); + } } diff --git a/packages/vm/src/calls.rs b/packages/vm/src/calls.rs index 55ec230e5..dc24a11a6 100644 --- a/packages/vm/src/calls.rs +++ b/packages/vm/src/calls.rs @@ -1,5 +1,5 @@ use serde::de::DeserializeOwned; -use wasmer::Val; +use wasmer::Value; use cosmwasm_std::{ContractResult, CustomMsg, Env, MessageInfo, QueryResponse, Reply, Response}; #[cfg(feature = "stargate")] @@ -206,9 +206,8 @@ where from_slice(&data, deserialization_limits::RESULT_QUERY)?; // Ensure query response is valid JSON if let ContractResult::Ok(binary_response) = &result { - serde_json::from_slice::(binary_response.as_slice()).map_err(|e| { - VmError::generic_err(format!("Query response must be valid JSON. {}", e)) - })?; + serde_json::from_slice::(binary_response.as_slice()) + .map_err(|e| VmError::generic_err(format!("Query response must be valid JSON. {e}")))?; } Ok(result) @@ -574,7 +573,7 @@ where S: Storage + 'static, Q: Querier + 'static, { - let mut arg_region_ptrs = Vec::::with_capacity(args.len()); + let mut arg_region_ptrs = Vec::::with_capacity(args.len()); for arg in args { let region_ptr = instance.allocate(arg.len())?; instance.write_memory(region_ptr, arg)?; @@ -595,6 +594,7 @@ mod tests { use cosmwasm_std::{coins, Empty}; static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); + static CYBERPUNK: &[u8] = include_bytes!("../testdata/cyberpunk.wasm"); #[test] fn call_instantiate_works() { @@ -627,6 +627,70 @@ mod tests { .unwrap(); } + #[test] + fn call_execute_runs_out_of_gas() { + let mut instance = mock_instance(CYBERPUNK, &[]); + + // init + let info = mock_info("creator", &[]); + call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{}"#) + .unwrap() + .unwrap(); + + // execute + let info = mock_info("looper", &[]); + let msg = br#"{"cpu_loop":{}}"#; + let err = + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, msg).unwrap_err(); + assert!(matches!(err, VmError::GasDepletion {})); + } + + #[test] + fn call_execute_handles_panic() { + let mut instance = mock_instance(CYBERPUNK, &[]); + + let info = mock_info("creator", &[]); + call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{}"#) + .unwrap() + .unwrap(); + + // execute + let info = mock_info("troll", &[]); + let msg = br#"{"panic":{}}"#; + let err = + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, msg).unwrap_err(); + match err { + VmError::RuntimeErr { msg } => { + assert!(msg.contains( + "RuntimeError: Aborted: panicked at 'This page intentionally faulted'" + )) + } + err => panic!("Unexpected error: {err:?}"), + } + } + + #[test] + fn call_execute_handles_unreachable() { + let mut instance = mock_instance(CYBERPUNK, &[]); + + let info = mock_info("creator", &[]); + call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{}"#) + .unwrap() + .unwrap(); + + // execute + let info = mock_info("troll", &[]); + let msg = br#"{"unreachable":{}}"#; + let err = + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, msg).unwrap_err(); + match err { + VmError::RuntimeErr { msg } => { + assert!(msg.contains("RuntimeError: unreachable")) + } + err => panic!("Unexpected error: {err:?}"), + } + } + #[test] fn call_migrate_works() { let mut instance = mock_instance(CONTRACT, &[]); diff --git a/packages/vm/src/capabilities.rs b/packages/vm/src/capabilities.rs index 85dabe9c9..828110501 100644 --- a/packages/vm/src/capabilities.rs +++ b/packages/vm/src/capabilities.rs @@ -15,7 +15,7 @@ pub fn capabilities_from_csv(csv: &str) -> HashSet { /// Implementation for check_wasm, based on static analysis of the bytecode. /// This is used for code upload, to perform check before compiling the Wasm. -pub fn required_capabilities_from_module(module: &impl ExportInfo) -> HashSet { +pub fn required_capabilities_from_module(module: impl ExportInfo) -> HashSet { module .exported_function_names(Some(REQUIRES_PREFIX)) .into_iter() @@ -32,8 +32,9 @@ pub fn required_capabilities_from_module(module: &impl ExportInfo) -> HashSet fmt::Result { for byte in self.0.iter() { - write!(f, "{:02x}", byte)?; + write!(f, "{byte:02x}")?; } Ok(()) } @@ -82,7 +82,7 @@ mod tests { let wasm = vec![0x68, 0x69, 0x6a]; let checksum = Checksum::generate(&wasm); // echo -n "hij" | sha256sum - let embedded = format!("Check: {}", checksum); + let embedded = format!("Check: {checksum}"); assert_eq!( embedded, "Check: 722c8c993fd75a7627d69ed941344fe2a1423a3e75efd3e6778a142884227104" diff --git a/packages/vm/src/compatibility.rs b/packages/vm/src/compatibility.rs index c65f7a65a..6123c2fe2 100644 --- a/packages/vm/src/compatibility.rs +++ b/packages/vm/src/compatibility.rs @@ -1,11 +1,14 @@ -use parity_wasm::elements::{External, ImportEntry, Module}; use std::collections::BTreeSet; use std::collections::HashSet; +use wasmer::wasmparser::Import; +use wasmer::wasmparser::TypeRef; + use crate::capabilities::required_capabilities_from_module; use crate::errors::{VmError, VmResult}; use crate::limited::LimitedDisplay; -use crate::static_analysis::{deserialize_wasm, ExportInfo}; +use crate::parsed_wasm::ParsedWasm; +use crate::static_analysis::ExportInfo; /// Lists all imports we provide upon instantiating the instance in Instance::from_module() /// This should be updated when new imports are added @@ -28,6 +31,10 @@ const SUPPORTED_IMPORTS: &[&str] = &[ "env.db_scan", #[cfg(feature = "iterator")] "env.db_next", + #[cfg(feature = "iterator")] + "env.db_next_key", + #[cfg(feature = "iterator")] + "env.db_next_value", ]; /// Lists all entry points we expect to be present when calling a contract. @@ -50,47 +57,80 @@ const SUPPORTED_INTERFACE_VERSIONS: &[&str] = &[ ]; const MEMORY_LIMIT: u32 = 512; // in pages +/// The upper limit for the `max` value of each table. CosmWasm contracts have +/// initial=max for 1 table. See +/// +/// ```plain +/// $ wasm-objdump --section=table -x packages/vm/testdata/hackatom.wasm +/// Section Details: +/// +/// Table[1]: +/// - table[0] type=funcref initial=161 max=161 +/// ``` +/// +/// As of March 2023, on Juno mainnet the largest value for production contracts +/// is 485. Most are between 100 and 300. +const TABLE_SIZE_LIMIT: u32 = 2500; // entries + +/// If the contract has more than this amount of imports, it will be rejected +/// during static validation before even looking into the imports. We keep this +/// number high since failing early gives less detailed error messages. Especially +/// when a user accidentally includes wasm-bindgen, they get a bunch of unsupported imports. +const MAX_IMPORTS: usize = 100; /// Checks if the data is valid wasm and compatibility with the CosmWasm API (imports and exports) pub fn check_wasm(wasm_code: &[u8], available_capabilities: &HashSet) -> VmResult<()> { - let module = deserialize_wasm(wasm_code)?; + let module = ParsedWasm::parse(wasm_code)?; + + check_wasm_tables(&module)?; check_wasm_memories(&module)?; check_interface_version(&module)?; check_wasm_exports(&module)?; check_wasm_imports(&module, SUPPORTED_IMPORTS)?; check_wasm_capabilities(&module, available_capabilities)?; + Ok(()) } -fn check_wasm_memories(module: &Module) -> VmResult<()> { - let section = match module.memory_section() { - Some(section) => section, - None => { - return Err(VmError::static_validation_err( - "Wasm contract doesn't have a memory section", - )); +fn check_wasm_tables(module: &ParsedWasm) -> VmResult<()> { + match module.tables.len() { + 0 => Ok(()), + 1 => { + let limits = &module.tables[0]; + if let Some(maximum) = limits.maximum { + if maximum > TABLE_SIZE_LIMIT { + return Err(VmError::static_validation_err( + "Wasm contract's first table section has a too large max limit", + )); + } + Ok(()) + } else { + Err(VmError::static_validation_err( + "Wasm contract must not have unbound table section", + )) + } } - }; + _ => Err(VmError::static_validation_err( + "Wasm contract must not have more than 1 table section", + )), + } +} - let memories = section.entries(); - if memories.len() != 1 { +fn check_wasm_memories(module: &ParsedWasm) -> VmResult<()> { + if module.memories.len() != 1 { return Err(VmError::static_validation_err( "Wasm contract must contain exactly one memory", )); } + let memory = &module.memories[0]; - let memory = memories[0]; - // println!("Memory: {:?}", memory); - let limits = memory.limits(); - - if limits.initial() > MEMORY_LIMIT { + if memory.initial > MEMORY_LIMIT as u64 { return Err(VmError::static_validation_err(format!( - "Wasm contract memory's minimum must not exceed {} pages.", - MEMORY_LIMIT + "Wasm contract memory's minimum must not exceed {MEMORY_LIMIT} pages." ))); } - if limits.maximum().is_some() { + if memory.maximum.is_some() { return Err(VmError::static_validation_err( "Wasm contract memory's maximum must be unset. The host will set it for you.", )); @@ -98,7 +138,7 @@ fn check_wasm_memories(module: &Module) -> VmResult<()> { Ok(()) } -fn check_interface_version(module: &Module) -> VmResult<()> { +fn check_interface_version(module: &ParsedWasm) -> VmResult<()> { let mut interface_version_exports = module .exported_function_names(Some(INTERFACE_VERSION_PREFIX)) .into_iter(); @@ -128,13 +168,12 @@ fn check_interface_version(module: &Module) -> VmResult<()> { } } -fn check_wasm_exports(module: &Module) -> VmResult<()> { +fn check_wasm_exports(module: &ParsedWasm) -> VmResult<()> { let available_exports: HashSet = module.exported_function_names(None); for required_export in REQUIRED_EXPORTS { if !available_exports.contains(*required_export) { return Err(VmError::static_validation_err(format!( - "Wasm contract doesn't have required export: \"{}\". Exports required by VM: {:?}.", - required_export, REQUIRED_EXPORTS + "Wasm contract doesn't have required export: \"{required_export}\". Exports required by VM: {REQUIRED_EXPORTS:?}." ))); } } @@ -144,39 +183,42 @@ fn check_wasm_exports(module: &Module) -> VmResult<()> { /// Checks if the import requirements of the contract are satisfied. /// When this is not the case, we either have an incompatibility between contract and VM /// or a error in the contract. -fn check_wasm_imports(module: &Module, supported_imports: &[&str]) -> VmResult<()> { - let required_imports: Vec = module - .import_section() - .map_or(vec![], |import_section| import_section.entries().to_vec()); - let required_import_names: BTreeSet<_> = - required_imports.iter().map(full_import_name).collect(); - - for required_import in required_imports { - let full_name = full_import_name(&required_import); +fn check_wasm_imports(module: &ParsedWasm, supported_imports: &[&str]) -> VmResult<()> { + if module.imports.len() > MAX_IMPORTS { + return Err(VmError::static_validation_err(format!( + "Import count exceeds limit. Imports: {}. Limit: {}.", + module.imports.len(), + MAX_IMPORTS + ))); + } + + for required_import in &module.imports { + let full_name = full_import_name(required_import); if !supported_imports.contains(&full_name.as_str()) { + let required_import_names: BTreeSet<_> = + module.imports.iter().map(full_import_name).collect(); return Err(VmError::static_validation_err(format!( "Wasm contract requires unsupported import: \"{}\". Required imports: {}. Available imports: {:?}.", full_name, required_import_names.to_string_limited(200), supported_imports ))); } - match required_import.external() { - External::Function(_) => {}, // ok + match required_import.ty { + TypeRef::Func(_) => {} // ok _ => return Err(VmError::static_validation_err(format!( - "Wasm contract requires non-function import: \"{}\". Right now, all supported imports are functions.", - full_name - ))), - }; + "Wasm contract requires non-function import: \"{full_name}\". Right now, all supported imports are functions." + ))) + } } Ok(()) } -fn full_import_name(ie: &ImportEntry) -> String { - format!("{}.{}", ie.module(), ie.field()) +fn full_import_name(ie: &Import) -> String { + format!("{}.{}", ie.module, ie.name) } fn check_wasm_capabilities( - module: &Module, + module: &ParsedWasm, available_capabilities: &HashSet, ) -> VmResult<()> { let required_capabilities = required_capabilities_from_module(module); @@ -203,6 +245,7 @@ mod tests { static CONTRACT_0_14: &[u8] = include_bytes!("../testdata/hackatom_0.14.wasm"); static CONTRACT_0_15: &[u8] = include_bytes!("../testdata/hackatom_0.15.wasm"); static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); + static CONTRACT_RUST_170: &[u8] = include_bytes!("../testdata/cyberpunk_rust170.wasm"); fn default_capabilities() -> HashSet { ["staking".to_string()].into_iter().collect() @@ -214,6 +257,12 @@ mod tests { check_wasm(CONTRACT, &default_capabilities()).unwrap(); } + #[test] + fn check_wasm_allows_sign_ext() { + // See https://github.com/CosmWasm/cosmwasm/issues/1727 + check_wasm(CONTRACT_RUST_170, &default_capabilities()).unwrap(); + } + #[test] fn check_wasm_old_contract() { match check_wasm(CONTRACT_0_15, &default_capabilities()) { @@ -221,7 +270,7 @@ mod tests { msg, "Wasm contract has unknown interface_version_* marker export (see https://github.com/CosmWasm/cosmwasm/blob/main/packages/vm/README.md)" ), - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("This must not succeeed"), }; @@ -230,43 +279,78 @@ mod tests { msg, "Wasm contract has unknown interface_version_* marker export (see https://github.com/CosmWasm/cosmwasm/blob/main/packages/vm/README.md)" ), - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("This must not succeeed"), }; match check_wasm(CONTRACT_0_12, &default_capabilities()) { - Err(VmError::StaticValidationErr { msg, .. }) => assert_eq!( - msg, - "Wasm contract missing a required marker export: interface_version_*" - ), - Err(e) => panic!("Unexpected error {:?}", e), + Err(VmError::StaticValidationErr { msg, .. }) => { + assert!(msg.contains( + "Wasm contract missing a required marker export: interface_version_*" + )) + } + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("This must not succeeed"), }; match check_wasm(CONTRACT_0_7, &default_capabilities()) { - Err(VmError::StaticValidationErr { msg, .. }) => assert_eq!( - msg, - "Wasm contract missing a required marker export: interface_version_*" - ), - Err(e) => panic!("Unexpected error {:?}", e), + Err(VmError::StaticValidationErr { msg, .. }) => { + assert!(msg.contains( + "Wasm contract missing a required marker export: interface_version_*" + )) + } + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("This must not succeeed"), }; } + #[test] + fn check_wasm_tables_works() { + // No tables is fine + let wasm = wat::parse_str("(module)").unwrap(); + assert!(ParsedWasm::parse(&wasm).unwrap().tables.is_empty()); + + // One table (bound) + let wasm = wat::parse_str("(module (table $name 123 123 funcref))").unwrap(); + check_wasm_tables(&ParsedWasm::parse(&wasm).unwrap()).unwrap(); + + // One table (bound, initial > max) + let wasm = wat::parse_str("(module (table $name 124 123 funcref))").unwrap(); + // this should be caught by the validator + let err = &ParsedWasm::parse(&wasm).unwrap_err(); + assert!(err + .to_string() + .contains("size minimum must not be greater than maximum")); + + // One table (bound, max too large) + let wasm = wat::parse_str("(module (table $name 100 9999 funcref))").unwrap(); + let err = check_wasm_tables(&ParsedWasm::parse(&wasm).unwrap()).unwrap_err(); + assert!(err + .to_string() + .contains("Wasm contract's first table section has a too large max limit")); + + // One table (unbound) + let wasm = wat::parse_str("(module (table $name 100 funcref))").unwrap(); + let err = check_wasm_tables(&ParsedWasm::parse(&wasm).unwrap()).unwrap_err(); + assert!(err + .to_string() + .contains("Wasm contract must not have unbound table section")); + } + #[test] fn check_wasm_memories_ok() { let wasm = wat::parse_str("(module (memory 1))").unwrap(); - check_wasm_memories(&deserialize_wasm(&wasm).unwrap()).unwrap() + check_wasm_memories(&ParsedWasm::parse(&wasm).unwrap()).unwrap() } #[test] fn check_wasm_memories_no_memory() { let wasm = wat::parse_str("(module)").unwrap(); - match check_wasm_memories(&deserialize_wasm(&wasm).unwrap()) { + match check_wasm_memories(&ParsedWasm::parse(&wasm).unwrap()) { Err(VmError::StaticValidationErr { msg, .. }) => { - assert!(msg.starts_with("Wasm contract doesn't have a memory section")); + assert!(msg.starts_with("Wasm contract must contain exactly one memory")); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } @@ -286,11 +370,12 @@ mod tests { )) .unwrap(); - match check_wasm_memories(&deserialize_wasm(&wasm).unwrap()) { + // wrong number of memories should be caught by the validator + match ParsedWasm::parse(&wasm) { Err(VmError::StaticValidationErr { msg, .. }) => { - assert!(msg.starts_with("Wasm contract must contain exactly one memory")); + assert!(msg.contains("multiple memories")); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } @@ -307,11 +392,11 @@ mod tests { )) .unwrap(); - match check_wasm_memories(&deserialize_wasm(&wasm).unwrap()) { + match check_wasm_memories(&ParsedWasm::parse(&wasm).unwrap()) { Err(VmError::StaticValidationErr { msg, .. }) => { assert!(msg.starts_with("Wasm contract must contain exactly one memory")); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } @@ -319,14 +404,14 @@ mod tests { #[test] fn check_wasm_memories_initial_size() { let wasm_ok = wat::parse_str("(module (memory 512))").unwrap(); - check_wasm_memories(&deserialize_wasm(&wasm_ok).unwrap()).unwrap(); + check_wasm_memories(&ParsedWasm::parse(&wasm_ok).unwrap()).unwrap(); let wasm_too_big = wat::parse_str("(module (memory 513))").unwrap(); - match check_wasm_memories(&deserialize_wasm(&wasm_too_big).unwrap()) { + match check_wasm_memories(&ParsedWasm::parse(&wasm_too_big).unwrap()) { Err(VmError::StaticValidationErr { msg, .. }) => { assert!(msg.starts_with("Wasm contract memory's minimum must not exceed 512 pages")); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } @@ -334,11 +419,11 @@ mod tests { #[test] fn check_wasm_memories_maximum_size() { let wasm_max = wat::parse_str("(module (memory 1 5))").unwrap(); - match check_wasm_memories(&deserialize_wasm(&wasm_max).unwrap()) { + match check_wasm_memories(&ParsedWasm::parse(&wasm_max).unwrap()) { Err(VmError::StaticValidationErr { msg, .. }) => { assert!(msg.starts_with("Wasm contract memory's maximum must be unset")); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } @@ -358,7 +443,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); check_interface_version(&module).unwrap(); #[cfg(feature = "allow_interface_version_7")] @@ -376,7 +461,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); check_interface_version(&module).unwrap(); } @@ -392,7 +477,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); match check_interface_version(&module).unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert_eq!( @@ -400,7 +485,7 @@ mod tests { "Wasm contract missing a required marker export: interface_version_*" ); } - err => panic!("Unexpected error {:?}", err), + err => panic!("Unexpected error {err:?}"), } // multiple @@ -417,7 +502,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); match check_interface_version(&module).unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert_eq!( @@ -425,7 +510,7 @@ mod tests { "Wasm contract contains more than one marker export: interface_version_*" ); } - err => panic!("Unexpected error {:?}", err), + err => panic!("Unexpected error {err:?}"), } // CosmWasm 0.15 @@ -441,12 +526,12 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); match check_interface_version(&module).unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert_eq!(msg, "Wasm contract has unknown interface_version_* marker export (see https://github.com/CosmWasm/cosmwasm/blob/main/packages/vm/README.md)"); } - err => panic!("Unexpected error {:?}", err), + err => panic!("Unexpected error {err:?}"), } // Unknown value @@ -462,12 +547,12 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); match check_interface_version(&module).unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert_eq!(msg, "Wasm contract has unknown interface_version_* marker export (see https://github.com/CosmWasm/cosmwasm/blob/main/packages/vm/README.md)"); } - err => panic!("Unexpected error {:?}", err), + err => panic!("Unexpected error {err:?}"), } } @@ -485,7 +570,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); check_wasm_exports(&module).unwrap(); // this is invalid, as it doesn't any required export @@ -497,12 +582,12 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); match check_wasm_exports(&module) { Err(VmError::StaticValidationErr { msg, .. }) => { assert!(msg.starts_with("Wasm contract doesn't have required export: \"allocate\"")); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } @@ -516,28 +601,28 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); match check_wasm_exports(&module) { Err(VmError::StaticValidationErr { msg, .. }) => { assert!( msg.starts_with("Wasm contract doesn't have required export: \"deallocate\"") ); } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } #[test] fn check_wasm_exports_of_old_contract() { - let module = deserialize_wasm(CONTRACT_0_7).unwrap(); + let module = ParsedWasm::parse(CONTRACT_0_7).unwrap(); match check_wasm_exports(&module) { Err(VmError::StaticValidationErr { msg, .. }) => { assert!( msg.starts_with("Wasm contract doesn't have required export: \"instantiate\"") ) } - Err(e) => panic!("Unexpected error {:?}", e), + Err(e) => panic!("Unexpected error {e:?}"), Ok(_) => panic!("Didn't reject wasm with invalid api"), } } @@ -560,7 +645,125 @@ mod tests { )"#, ) .unwrap(); - check_wasm_imports(&deserialize_wasm(&wasm).unwrap(), SUPPORTED_IMPORTS).unwrap(); + check_wasm_imports(&ParsedWasm::parse(&wasm).unwrap(), SUPPORTED_IMPORTS).unwrap(); + } + + #[test] + fn check_wasm_imports_exceeds_limit() { + let wasm = wat::parse_str( + r#"(module + (import "env" "db_write" (func (param i32 i32) (result i32))) + (import "env" "db_remove" (func (param i32) (result i32))) + (import "env" "addr_validate" (func (param i32) (result i32))) + (import "env" "addr_canonicalize" (func (param i32 i32) (result i32))) + (import "env" "addr_humanize" (func (param i32 i32) (result i32))) + (import "env" "secp256k1_verify" (func (param i32 i32 i32) (result i32))) + (import "env" "secp256k1_recover_pubkey" (func (param i32 i32 i32) (result i64))) + (import "env" "ed25519_verify" (func (param i32 i32 i32) (result i32))) + (import "env" "ed25519_batch_verify" (func (param i32 i32 i32) (result i32))) + (import "env" "spam01" (func (param i32 i32) (result i32))) + (import "env" "spam02" (func (param i32 i32) (result i32))) + (import "env" "spam03" (func (param i32 i32) (result i32))) + (import "env" "spam04" (func (param i32 i32) (result i32))) + (import "env" "spam05" (func (param i32 i32) (result i32))) + (import "env" "spam06" (func (param i32 i32) (result i32))) + (import "env" "spam07" (func (param i32 i32) (result i32))) + (import "env" "spam08" (func (param i32 i32) (result i32))) + (import "env" "spam09" (func (param i32 i32) (result i32))) + (import "env" "spam10" (func (param i32 i32) (result i32))) + (import "env" "spam11" (func (param i32 i32) (result i32))) + (import "env" "spam12" (func (param i32 i32) (result i32))) + (import "env" "spam13" (func (param i32 i32) (result i32))) + (import "env" "spam14" (func (param i32 i32) (result i32))) + (import "env" "spam15" (func (param i32 i32) (result i32))) + (import "env" "spam16" (func (param i32 i32) (result i32))) + (import "env" "spam17" (func (param i32 i32) (result i32))) + (import "env" "spam18" (func (param i32 i32) (result i32))) + (import "env" "spam19" (func (param i32 i32) (result i32))) + (import "env" "spam20" (func (param i32 i32) (result i32))) + (import "env" "spam21" (func (param i32 i32) (result i32))) + (import "env" "spam22" (func (param i32 i32) (result i32))) + (import "env" "spam23" (func (param i32 i32) (result i32))) + (import "env" "spam24" (func (param i32 i32) (result i32))) + (import "env" "spam25" (func (param i32 i32) (result i32))) + (import "env" "spam26" (func (param i32 i32) (result i32))) + (import "env" "spam27" (func (param i32 i32) (result i32))) + (import "env" "spam28" (func (param i32 i32) (result i32))) + (import "env" "spam29" (func (param i32 i32) (result i32))) + (import "env" "spam30" (func (param i32 i32) (result i32))) + (import "env" "spam31" (func (param i32 i32) (result i32))) + (import "env" "spam32" (func (param i32 i32) (result i32))) + (import "env" "spam33" (func (param i32 i32) (result i32))) + (import "env" "spam34" (func (param i32 i32) (result i32))) + (import "env" "spam35" (func (param i32 i32) (result i32))) + (import "env" "spam36" (func (param i32 i32) (result i32))) + (import "env" "spam37" (func (param i32 i32) (result i32))) + (import "env" "spam38" (func (param i32 i32) (result i32))) + (import "env" "spam39" (func (param i32 i32) (result i32))) + (import "env" "spam40" (func (param i32 i32) (result i32))) + (import "env" "spam41" (func (param i32 i32) (result i32))) + (import "env" "spam42" (func (param i32 i32) (result i32))) + (import "env" "spam43" (func (param i32 i32) (result i32))) + (import "env" "spam44" (func (param i32 i32) (result i32))) + (import "env" "spam45" (func (param i32 i32) (result i32))) + (import "env" "spam46" (func (param i32 i32) (result i32))) + (import "env" "spam47" (func (param i32 i32) (result i32))) + (import "env" "spam48" (func (param i32 i32) (result i32))) + (import "env" "spam49" (func (param i32 i32) (result i32))) + (import "env" "spam50" (func (param i32 i32) (result i32))) + (import "env" "spam51" (func (param i32 i32) (result i32))) + (import "env" "spam52" (func (param i32 i32) (result i32))) + (import "env" "spam53" (func (param i32 i32) (result i32))) + (import "env" "spam54" (func (param i32 i32) (result i32))) + (import "env" "spam55" (func (param i32 i32) (result i32))) + (import "env" "spam56" (func (param i32 i32) (result i32))) + (import "env" "spam57" (func (param i32 i32) (result i32))) + (import "env" "spam58" (func (param i32 i32) (result i32))) + (import "env" "spam59" (func (param i32 i32) (result i32))) + (import "env" "spam60" (func (param i32 i32) (result i32))) + (import "env" "spam61" (func (param i32 i32) (result i32))) + (import "env" "spam62" (func (param i32 i32) (result i32))) + (import "env" "spam63" (func (param i32 i32) (result i32))) + (import "env" "spam64" (func (param i32 i32) (result i32))) + (import "env" "spam65" (func (param i32 i32) (result i32))) + (import "env" "spam66" (func (param i32 i32) (result i32))) + (import "env" "spam67" (func (param i32 i32) (result i32))) + (import "env" "spam68" (func (param i32 i32) (result i32))) + (import "env" "spam69" (func (param i32 i32) (result i32))) + (import "env" "spam70" (func (param i32 i32) (result i32))) + (import "env" "spam71" (func (param i32 i32) (result i32))) + (import "env" "spam72" (func (param i32 i32) (result i32))) + (import "env" "spam73" (func (param i32 i32) (result i32))) + (import "env" "spam74" (func (param i32 i32) (result i32))) + (import "env" "spam75" (func (param i32 i32) (result i32))) + (import "env" "spam76" (func (param i32 i32) (result i32))) + (import "env" "spam77" (func (param i32 i32) (result i32))) + (import "env" "spam78" (func (param i32 i32) (result i32))) + (import "env" "spam79" (func (param i32 i32) (result i32))) + (import "env" "spam80" (func (param i32 i32) (result i32))) + (import "env" "spam81" (func (param i32 i32) (result i32))) + (import "env" "spam82" (func (param i32 i32) (result i32))) + (import "env" "spam83" (func (param i32 i32) (result i32))) + (import "env" "spam84" (func (param i32 i32) (result i32))) + (import "env" "spam85" (func (param i32 i32) (result i32))) + (import "env" "spam86" (func (param i32 i32) (result i32))) + (import "env" "spam87" (func (param i32 i32) (result i32))) + (import "env" "spam88" (func (param i32 i32) (result i32))) + (import "env" "spam89" (func (param i32 i32) (result i32))) + (import "env" "spam90" (func (param i32 i32) (result i32))) + (import "env" "spam91" (func (param i32 i32) (result i32))) + (import "env" "spam92" (func (param i32 i32) (result i32))) + )"#, + ) + .unwrap(); + let err = + check_wasm_imports(&ParsedWasm::parse(&wasm).unwrap(), SUPPORTED_IMPORTS).unwrap_err(); + match err { + VmError::StaticValidationErr { msg, .. } => { + assert_eq!(msg, "Import count exceeds limit. Imports: 101. Limit: 100."); + } + err => panic!("Unexpected error: {err:?}"), + } } #[test] @@ -591,44 +794,44 @@ mod tests { "env.debug", "env.query_chain", ]; - let result = check_wasm_imports(&deserialize_wasm(&wasm).unwrap(), supported_imports); + let result = check_wasm_imports(&ParsedWasm::parse(&wasm).unwrap(), supported_imports); match result.unwrap_err() { VmError::StaticValidationErr { msg, .. } => { - println!("{}", msg); + println!("{msg}"); assert_eq!( msg, r#"Wasm contract requires unsupported import: "env.foo". Required imports: {"env.bar", "env.foo", "env.spammyspam01", "env.spammyspam02", "env.spammyspam03", "env.spammyspam04", "env.spammyspam05", "env.spammyspam06", "env.spammyspam07", "env.spammyspam08", ... 2 more}. Available imports: ["env.db_read", "env.db_write", "env.db_remove", "env.addr_canonicalize", "env.addr_humanize", "env.debug", "env.query_chain"]."# ); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } #[test] fn check_wasm_imports_of_old_contract() { - let module = deserialize_wasm(CONTRACT_0_7).unwrap(); - let result = check_wasm_imports(&module, SUPPORTED_IMPORTS); + let module = &ParsedWasm::parse(CONTRACT_0_7).unwrap(); + let result = check_wasm_imports(module, SUPPORTED_IMPORTS); match result.unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert!( msg.starts_with("Wasm contract requires unsupported import: \"env.read_db\"") ); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } #[test] fn check_wasm_imports_wrong_type() { let wasm = wat::parse_str(r#"(module (import "env" "db_read" (memory 1 1)))"#).unwrap(); - let result = check_wasm_imports(&deserialize_wasm(&wasm).unwrap(), SUPPORTED_IMPORTS); + let result = check_wasm_imports(&ParsedWasm::parse(&wasm).unwrap(), SUPPORTED_IMPORTS); match result.unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert!( msg.starts_with("Wasm contract requires non-function import: \"env.db_read\"") ); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -647,7 +850,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); let available = [ "water".to_string(), "nutrients".to_string(), @@ -674,7 +877,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); // Available set 1 let available = [ diff --git a/packages/vm/src/conversion.rs b/packages/vm/src/conversion.rs index 8723cd0eb..ef9577c4a 100644 --- a/packages/vm/src/conversion.rs +++ b/packages/vm/src/conversion.rs @@ -53,7 +53,7 @@ mod tests { assert_eq!(to_type, "u32"); assert_eq!(input, "4294967296"); } - Err(err) => panic!("unexpected error: {:?}", err), + Err(err) => panic!("unexpected error: {err:?}"), Ok(_) => panic!("must not succeed"), }; } @@ -77,7 +77,7 @@ mod tests { assert_eq!(to_type, "u32"); assert_eq!(input, "4294967296"); } - Err(err) => panic!("unexpected error: {:?}", err), + Err(err) => panic!("unexpected error: {err:?}"), Ok(_) => panic!("must not succeed"), }; } @@ -99,7 +99,7 @@ mod tests { assert_eq!(to_type, "u32"); assert_eq!(input, "-1"); } - Err(err) => panic!("unexpected error: {:?}", err), + Err(err) => panic!("unexpected error: {err:?}"), Ok(_) => panic!("must not succeed"), }; } @@ -121,7 +121,7 @@ mod tests { assert_eq!(to_type, "u32"); assert_eq!(input, "-1"); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), }; // usize @@ -141,7 +141,7 @@ mod tests { assert_eq!(to_type, "u32"); assert_eq!(input, "4294967296"); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), }; } @@ -162,7 +162,7 @@ mod tests { assert_eq!(to_type, "i32"); assert_eq!(input, "2147483648"); } - Err(err) => panic!("unexpected error: {:?}", err), + Err(err) => panic!("unexpected error: {err:?}"), Ok(_) => panic!("must not succeed"), }; } @@ -188,7 +188,7 @@ mod tests { assert_eq!(to_type, "i32"); assert_eq!(input, "-2147483649"); } - Err(err) => panic!("unexpected error: {:?}", err), + Err(err) => panic!("unexpected error: {err:?}"), Ok(_) => panic!("must not succeed"), }; } diff --git a/packages/vm/src/environment.rs b/packages/vm/src/environment.rs index aa2cae848..121759ddf 100644 --- a/packages/vm/src/environment.rs +++ b/packages/vm/src/environment.rs @@ -1,14 +1,25 @@ //! Internal details to be used by instance.rs only use std::borrow::{Borrow, BorrowMut}; +use std::cell::RefCell; +use std::marker::PhantomData; use std::ptr::NonNull; +use std::rc::Rc; use std::sync::{Arc, RwLock}; -use wasmer::{HostEnvInitError, Instance as WasmerInstance, Memory, Val, WasmerEnv}; +use derivative::Derivative; +use wasmer::{AsStoreMut, Instance as WasmerInstance, Memory, MemoryView, Value}; use wasmer_middlewares::metering::{get_remaining_points, set_remaining_points, MeteringPoints}; use crate::backend::{BackendApi, GasInfo, Querier, Storage}; use crate::errors::{VmError, VmResult}; +/// Keep this as low as necessary to avoid deepy nested errors like this: +/// +/// ```plain +/// RuntimeErr { msg: "Wasmer runtime error: RuntimeError: Error executing Wasm: Wasmer runtime error: RuntimeError: Error executing Wasm: Wasmer runtime error: RuntimeError: Error executing Wasm: Wasmer runtime error: RuntimeError: Error executing Wasm: Wasmer runtime error: RuntimeError: Maximum call depth exceeded." } +/// ``` +const MAX_CALL_DEPTH: usize = 2; + /// Never can never be instantiated. /// Replace this with the [never primitive type](https://doc.rust-lang.org/std/primitive.never.html) when stable. #[derive(Debug)] @@ -76,11 +87,35 @@ impl GasState { } } +/// Additional environmental information in a debug call. +/// +/// The currently unused lifetime parameter 'a allows accessing referenced data in the debug implementation +/// without cloning it. +#[derive(Derivative)] +#[derivative(Debug)] +#[non_exhaustive] +pub struct DebugInfo<'a> { + pub gas_remaining: u64, + // This field is just to allow us to add the unused lifetime parameter. It can be removed + // at any time. + #[doc(hidden)] + #[derivative(Debug = "ignore")] + pub(crate) __lifetime: PhantomData<&'a ()>, +} + +// Unfortunately we cannot create an alias for the trait (https://github.com/rust-lang/rust/issues/41517). +// So we need to copy it in a few places. +// +// /- BEGIN TRAIT END TRAIT \ +// | | +// v v +pub type DebugHandlerFn = dyn for<'a, 'b> FnMut(/* msg */ &'a str, DebugInfo<'b>); + /// A environment that provides access to the ContextData. /// The environment is clonable but clones access the same underlying data. -pub struct Environment { +pub struct Environment { + pub memory: Option, pub api: A, - pub print_debug: bool, pub gas_config: GasConfig, data: Arc>>, } @@ -92,30 +127,37 @@ unsafe impl Sync for Environment impl Clone for Environment { fn clone(&self) -> Self { Environment { + memory: None, api: self.api, - print_debug: self.print_debug, gas_config: self.gas_config.clone(), data: self.data.clone(), } } } -impl WasmerEnv for Environment { - fn init_with_instance(&mut self, _instance: &WasmerInstance) -> Result<(), HostEnvInitError> { - Ok(()) - } -} - impl Environment { - pub fn new(api: A, gas_limit: u64, print_debug: bool) -> Self { + pub fn new(api: A, gas_limit: u64) -> Self { Environment { + memory: None, api, - print_debug, gas_config: GasConfig::default(), data: Arc::new(RwLock::new(ContextData::new(gas_limit))), } } + pub fn set_debug_handler(&self, debug_handler: Option>>) { + self.with_context_data_mut(|context_data| { + context_data.debug_handler = debug_handler; + }) + } + + pub fn debug_handler(&self) -> Option>> { + self.with_context_data(|context_data| { + // This clone here requires us to wrap the function in Rc instead of Box + context_data.debug_handler.clone() + }) + } + fn with_context_data_mut(&self, callback: C) -> R where C: FnOnce(&mut ContextData) -> R, @@ -165,26 +207,39 @@ impl Environment { /// The number of return values is variable and controlled by the guest. /// Usually we expect 0 or 1 return values. Use [`Self::call_function0`] /// or [`Self::call_function1`] to ensure the number of return values is checked. - fn call_function(&self, name: &str, args: &[Val]) -> VmResult> { + fn call_function( + &self, + store: &mut impl AsStoreMut, + name: &str, + args: &[Value], + ) -> VmResult> { // Clone function before calling it to avoid dead locks let func = self.with_wasmer_instance(|instance| { let func = instance.exports.get_function(name)?; Ok(func.clone()) })?; - func.call(args).map_err(|runtime_err| -> VmError { + self.increment_call_depth()?; + let res = func.call(store, args).map_err(|runtime_err| -> VmError { self.with_wasmer_instance::<_, Never>(|instance| { - let err: VmError = match get_remaining_points(instance) { + let err: VmError = match get_remaining_points(store, instance) { MeteringPoints::Remaining(_) => VmError::from(runtime_err), MeteringPoints::Exhausted => VmError::gas_depletion(), }; Err(err) }) .unwrap_err() // with_wasmer_instance can only succeed if the callback succeeds - }) + }); + self.decrement_call_depth(); + res } - pub fn call_function0(&self, name: &str, args: &[Val]) -> VmResult<()> { - let result = self.call_function(name, args)?; + pub fn call_function0( + &self, + store: &mut impl AsStoreMut, + name: &str, + args: &[Value], + ) -> VmResult<()> { + let result = self.call_function(store, name, args)?; let expected = 0; let actual = result.len(); if actual != expected { @@ -193,8 +248,13 @@ impl Environment { Ok(()) } - pub fn call_function1(&self, name: &str, args: &[Val]) -> VmResult { - let result = self.call_function(name, args)?; + pub fn call_function1( + &self, + store: &mut impl AsStoreMut, + name: &str, + args: &[Value], + ) -> VmResult { + let result = self.call_function(store, name, args)?; let expected = 1; let actual = result.len(); if actual != expected { @@ -241,9 +301,37 @@ impl Environment { }) } - pub fn get_gas_left(&self) -> u64 { + /// Increments the call depth by 1 and returns the new value + pub fn increment_call_depth(&self) -> VmResult { + let new = self.with_context_data_mut(|context_data| { + let new = context_data.call_depth + 1; + context_data.call_depth = new; + new + }); + if new > MAX_CALL_DEPTH { + return Err(VmError::max_call_depth_exceeded()); + } + Ok(new) + } + + /// Decrements the call depth by 1 and returns the new value + pub fn decrement_call_depth(&self) -> usize { + self.with_context_data_mut(|context_data| { + let new = context_data + .call_depth + .checked_sub(1) + .expect("Call depth < 0. This is a bug."); + context_data.call_depth = new; + new + }) + } + + /// Returns the remaining gas measured in [CosmWasm gas]. + /// + /// [CosmWasm gas]: https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md + pub fn get_gas_left(&self, store: &mut impl AsStoreMut) -> u64 { self.with_wasmer_instance(|instance| { - Ok(match get_remaining_points(instance) { + Ok(match get_remaining_points(store, instance) { MeteringPoints::Remaining(count) => count, MeteringPoints::Exhausted => 0, }) @@ -251,9 +339,12 @@ impl Environment { .expect("Wasmer instance is not set. This is a bug in the lifecycle.") } - pub fn set_gas_left(&self, new_value: u64) { + /// Sets the remaining gas measured in [CosmWasm gas]. + /// + /// [CosmWasm gas]: https://github.com/CosmWasm/cosmwasm/blob/main/docs/GAS.md + pub fn set_gas_left(&self, store: &mut impl AsStoreMut, new_value: u64) { self.with_wasmer_instance(|instance| { - set_remaining_points(instance, new_value); + set_remaining_points(store, instance, new_value); Ok(()) }) .expect("Wasmer instance is not set. This is a bug in the lifecycle.") @@ -263,39 +354,29 @@ impl Environment { /// If the amount exceeds the available gas, the remaining gas is set to 0 and /// an VmError::GasDepletion error is returned. #[allow(unused)] // used in tests - pub fn decrease_gas_left(&self, amount: u64) -> VmResult<()> { + pub fn decrease_gas_left(&self, store: &mut impl AsStoreMut, amount: u64) -> VmResult<()> { self.with_wasmer_instance(|instance| { - let remaining = match get_remaining_points(instance) { + let remaining = match get_remaining_points(store, instance) { MeteringPoints::Remaining(count) => count, MeteringPoints::Exhausted => 0, }; if amount > remaining { - set_remaining_points(instance, 0); + set_remaining_points(store, instance, 0); Err(VmError::gas_depletion()) } else { - set_remaining_points(instance, remaining - amount); + set_remaining_points(store, instance, remaining - amount); Ok(()) } }) } - pub fn memory(&self) -> Memory { - self.with_wasmer_instance(|instance| { - let first: Option = instance - .exports - .iter() - .memories() - .next() - .map(|pair| pair.1.clone()); - // Every contract in CosmWasm must have exactly one exported memory. - // This is ensured by `check_wasm`/`check_wasm_memories`, which is called for every - // contract added to the Cache as well as in integration tests. - // It is possible to bypass this check when using `Instance::from_code` but then you - // learn the hard way when this panics, or when trying to upload the contract to chain. - let memory = first.expect("A contract must have exactly one exported memory."); - Ok(memory) - }) - .expect("Wasmer instance is not set. This is a bug in the lifecycle.") + /// Creates a MemoryView. + /// This must be short living and not be used after the memory was grown. + pub fn memory<'a>(&self, store: &'a mut impl AsStoreMut) -> MemoryView<'a> { + self.memory + .as_ref() + .expect("Memory is not set. This is a bug in the lifecycle.") + .view(store) } /// Moves owned instances of storage and querier into the env. @@ -316,11 +397,13 @@ impl Environment { } } -pub struct ContextData { +pub struct ContextData { gas_state: GasState, storage: Option, storage_readonly: bool, + call_depth: usize, querier: Option, + debug_handler: Option>>, /// A non-owning link to the wasmer instance wasmer_instance: Option>, } @@ -331,7 +414,9 @@ impl ContextData { gas_state: GasState::with_limit(gas_limit), storage: None, storage_readonly: true, + call_depth: 0, querier: None, + debug_handler: None, wasmer_instance: None, } } @@ -339,9 +424,10 @@ impl ContextData { pub fn process_gas_info( env: &Environment, + store: &mut impl AsStoreMut, info: GasInfo, ) -> VmResult<()> { - let gas_left = env.get_gas_left(); + let gas_left = env.get_gas_left(store); let new_limit = env.with_gas_state_mut(|gas_state| { gas_state.externally_used_gas += info.externally_used; @@ -353,7 +439,7 @@ pub fn process_gas_info( }); // This tells wasmer how much more gas it can consume from this point in time. - env.set_gas_left(new_limit); + env.set_gas_left(store, new_limit); if info.externally_used + info.cost > gas_left { Err(VmError::gas_depletion()) @@ -370,11 +456,11 @@ mod tests { use crate::errors::VmError; use crate::size::Size; use crate::testing::{MockApi, MockQuerier, MockStorage}; - use crate::wasm_backend::compile; + use crate::wasm_backend::{compile, make_compiling_engine}; use cosmwasm_std::{ coins, from_binary, to_vec, AllBalanceResponse, BankQuery, Empty, QueryRequest, }; - use wasmer::{imports, Function, Instance as WasmerInstance}; + use wasmer::{imports, Function, Instance as WasmerInstance, Store}; static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); @@ -394,39 +480,45 @@ mod tests { gas_limit: u64, ) -> ( Environment, + Store, Box, ) { - let env = Environment::new(MockApi::default(), gas_limit, false); + let env = Environment::new(MockApi::default(), gas_limit); + + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine, CONTRACT).unwrap(); + let mut store = Store::new(engine); - let module = compile(CONTRACT, TESTING_MEMORY_LIMIT, &[]).unwrap(); - let store = module.store(); // we need stubs for all required imports let import_obj = imports! { "env" => { - "db_read" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "db_write" => Function::new_native(store, |_a: u32, _b: u32| {}), - "db_remove" => Function::new_native(store, |_a: u32| {}), - "db_scan" => Function::new_native(store, |_a: u32, _b: u32, _c: i32| -> u32 { 0 }), - "db_next" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "query_chain" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "addr_validate" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "addr_canonicalize" => Function::new_native(store, |_a: u32, _b: u32| -> u32 { 0 }), - "addr_humanize" => Function::new_native(store, |_a: u32, _b: u32| -> u32 { 0 }), - "secp256k1_verify" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), - "secp256k1_recover_pubkey" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u64 { 0 }), - "ed25519_verify" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), - "ed25519_batch_verify" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), - "sha1_calculate" => Function::new_native(store, |_a: u32| -> u64 { 0 }), - "debug" => Function::new_native(store, |_a: u32| {}), + "db_read" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "db_write" => Function::new_typed(&mut store, |_a: u32, _b: u32| {}), + "db_remove" => Function::new_typed(&mut store, |_a: u32| {}), + "db_scan" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: i32| -> u32 { 0 }), + "db_next" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "db_next_key" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "db_next_value" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "query_chain" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "addr_validate" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "addr_canonicalize" => Function::new_typed(&mut store, |_a: u32, _b: u32| -> u32 { 0 }), + "addr_humanize" => Function::new_typed(&mut store, |_a: u32, _b: u32| -> u32 { 0 }), + "secp256k1_verify" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), + "secp256k1_recover_pubkey" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u64 { 0 }), + "ed25519_verify" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), + "ed25519_batch_verify" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), + "sha1_calculate" => Function::new_typed(&mut store, |_a: u32| -> u64 { 0 }), + "debug" => Function::new_typed(&mut store, |_a: u32| {}), + "abort" => Function::new_typed(&mut store, |_a: u32| {}), }, }; - let instance = Box::from(WasmerInstance::new(&module, &import_obj).unwrap()); + let instance = Box::from(WasmerInstance::new(&mut store, &module, &import_obj).unwrap()); let instance_ptr = NonNull::from(instance.as_ref()); env.set_wasmer_instance(Some(instance_ptr)); - env.set_gas_left(gas_limit); + env.set_gas_left(&mut store, gas_limit); - (env, instance) + (env, store, instance) } fn leave_default_data(env: &Environment) { @@ -443,7 +535,7 @@ mod tests { #[test] fn move_out_works() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); // empty data on start let (inits, initq) = env.move_out(); @@ -468,90 +560,90 @@ mod tests { #[test] fn process_gas_info_works_for_cost() { - let (env, _instance) = make_instance(100); - assert_eq!(env.get_gas_left(), 100); + let (env, mut store, _instance) = make_instance(100); + assert_eq!(env.get_gas_left(&mut store), 100); // Consume all the Gas that we allocated - process_gas_info(&env, GasInfo::with_cost(70)).unwrap(); - assert_eq!(env.get_gas_left(), 30); - process_gas_info(&env, GasInfo::with_cost(4)).unwrap(); - assert_eq!(env.get_gas_left(), 26); - process_gas_info(&env, GasInfo::with_cost(6)).unwrap(); - assert_eq!(env.get_gas_left(), 20); - process_gas_info(&env, GasInfo::with_cost(20)).unwrap(); - assert_eq!(env.get_gas_left(), 0); + process_gas_info(&env, &mut store, GasInfo::with_cost(70)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 30); + process_gas_info(&env, &mut store, GasInfo::with_cost(4)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 26); + process_gas_info(&env, &mut store, GasInfo::with_cost(6)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 20); + process_gas_info(&env, &mut store, GasInfo::with_cost(20)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 0); // Using one more unit of gas triggers a failure - match process_gas_info(&env, GasInfo::with_cost(1)).unwrap_err() { + match process_gas_info(&env, &mut store, GasInfo::with_cost(1)).unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } } #[test] fn process_gas_info_works_for_externally_used() { - let (env, _instance) = make_instance(100); - assert_eq!(env.get_gas_left(), 100); + let (env, mut store, _instance) = make_instance(100); + assert_eq!(env.get_gas_left(&mut store), 100); // Consume all the Gas that we allocated - process_gas_info(&env, GasInfo::with_externally_used(70)).unwrap(); - assert_eq!(env.get_gas_left(), 30); - process_gas_info(&env, GasInfo::with_externally_used(4)).unwrap(); - assert_eq!(env.get_gas_left(), 26); - process_gas_info(&env, GasInfo::with_externally_used(6)).unwrap(); - assert_eq!(env.get_gas_left(), 20); - process_gas_info(&env, GasInfo::with_externally_used(20)).unwrap(); - assert_eq!(env.get_gas_left(), 0); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(70)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 30); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(4)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 26); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(6)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 20); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(20)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 0); // Using one more unit of gas triggers a failure - match process_gas_info(&env, GasInfo::with_externally_used(1)).unwrap_err() { + match process_gas_info(&env, &mut store, GasInfo::with_externally_used(1)).unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } } #[test] fn process_gas_info_works_for_cost_and_externally_used() { - let (env, _instance) = make_instance(100); - assert_eq!(env.get_gas_left(), 100); + let (env, mut store, _instance) = make_instance(100); + assert_eq!(env.get_gas_left(&mut store), 100); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 0); - process_gas_info(&env, GasInfo::new(17, 4)).unwrap(); - assert_eq!(env.get_gas_left(), 79); + process_gas_info(&env, &mut store, GasInfo::new(17, 4)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 79); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 4); - process_gas_info(&env, GasInfo::new(9, 0)).unwrap(); - assert_eq!(env.get_gas_left(), 70); + process_gas_info(&env, &mut store, GasInfo::new(9, 0)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 70); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 4); - process_gas_info(&env, GasInfo::new(0, 70)).unwrap(); - assert_eq!(env.get_gas_left(), 0); + process_gas_info(&env, &mut store, GasInfo::new(0, 70)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 0); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 74); // More cost fail but do not change stats - match process_gas_info(&env, GasInfo::new(1, 0)).unwrap_err() { + match process_gas_info(&env, &mut store, GasInfo::new(1, 0)).unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } - assert_eq!(env.get_gas_left(), 0); + assert_eq!(env.get_gas_left(&mut store), 0); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 74); // More externally used fails and changes stats - match process_gas_info(&env, GasInfo::new(0, 1)).unwrap_err() { + match process_gas_info(&env, &mut store, GasInfo::new(0, 1)).unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } - assert_eq!(env.get_gas_left(), 0); + assert_eq!(env.get_gas_left(&mut store), 0); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 75); @@ -561,13 +653,13 @@ mod tests { fn process_gas_info_zeros_gas_left_when_exceeded() { // with_externally_used { - let (env, _instance) = make_instance(100); - let result = process_gas_info(&env, GasInfo::with_externally_used(120)); + let (env, mut store, _instance) = make_instance(100); + let result = process_gas_info(&env, &mut store, GasInfo::with_externally_used(120)); match result.unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } - assert_eq!(env.get_gas_left(), 0); + assert_eq!(env.get_gas_left(&mut store), 0); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 120); @@ -575,13 +667,13 @@ mod tests { // with_cost { - let (env, _instance) = make_instance(100); - let result = process_gas_info(&env, GasInfo::with_cost(120)); + let (env, mut store, _instance) = make_instance(100); + let result = process_gas_info(&env, &mut store, GasInfo::with_cost(120)); match result.unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } - assert_eq!(env.get_gas_left(), 0); + assert_eq!(env.get_gas_left(&mut store), 0); let gas_state = env.with_gas_state(|gas_state| gas_state.clone()); assert_eq!(gas_state.gas_limit, 100); assert_eq!(gas_state.externally_used_gas, 0); @@ -590,34 +682,34 @@ mod tests { #[test] fn process_gas_info_works_correctly_with_gas_consumption_in_wasmer() { - let (env, _instance) = make_instance(100); - assert_eq!(env.get_gas_left(), 100); + let (env, mut store, _instance) = make_instance(100); + assert_eq!(env.get_gas_left(&mut store), 100); // Some gas was consumed externally - process_gas_info(&env, GasInfo::with_externally_used(50)).unwrap(); - assert_eq!(env.get_gas_left(), 50); - process_gas_info(&env, GasInfo::with_externally_used(4)).unwrap(); - assert_eq!(env.get_gas_left(), 46); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(50)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 50); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(4)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 46); // Consume 20 gas directly in wasmer - env.decrease_gas_left(20).unwrap(); - assert_eq!(env.get_gas_left(), 26); + env.decrease_gas_left(&mut store, 20).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 26); - process_gas_info(&env, GasInfo::with_externally_used(6)).unwrap(); - assert_eq!(env.get_gas_left(), 20); - process_gas_info(&env, GasInfo::with_externally_used(20)).unwrap(); - assert_eq!(env.get_gas_left(), 0); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(6)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 20); + process_gas_info(&env, &mut store, GasInfo::with_externally_used(20)).unwrap(); + assert_eq!(env.get_gas_left(&mut store), 0); // Using one more unit of gas triggers a failure - match process_gas_info(&env, GasInfo::with_externally_used(1)).unwrap_err() { + match process_gas_info(&env, &mut store, GasInfo::with_externally_used(1)).unwrap_err() { VmError::GasDepletion { .. } => {} - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } } #[test] fn is_storage_readonly_defaults_to_true() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); assert!(env.is_storage_readonly()); @@ -625,7 +717,7 @@ mod tests { #[test] fn set_storage_readonly_can_change_flag() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); // change @@ -643,57 +735,60 @@ mod tests { #[test] fn call_function_works() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); - let result = env.call_function("allocate", &[10u32.into()]).unwrap(); + let result = env + .call_function(&mut store, "allocate", &[10u32.into()]) + .unwrap(); let ptr = ref_to_u32(&result[0]).unwrap(); assert!(ptr > 0); } #[test] fn call_function_fails_for_missing_instance() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); // Clear context's wasmer_instance env.set_wasmer_instance(None); - let res = env.call_function("allocate", &[]); + let res = env.call_function(&mut store, "allocate", &[]); match res.unwrap_err() { VmError::UninitializedContextData { kind, .. } => assert_eq!(kind, "wasmer_instance"), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } #[test] fn call_function_fails_for_missing_function() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); - let res = env.call_function("doesnt_exist", &[]); + let res = env.call_function(&mut store, "doesnt_exist", &[]); match res.unwrap_err() { VmError::ResolveErr { msg, .. } => { assert_eq!(msg, "Could not get export: Missing export doesnt_exist"); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } #[test] fn call_function0_works() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); - env.call_function0("interface_version_8", &[]).unwrap(); + env.call_function0(&mut store, "interface_version_8", &[]) + .unwrap(); } #[test] fn call_function0_errors_for_wrong_result_count() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); - let result = env.call_function0("allocate", &[10u32.into()]); + let result = env.call_function0(&mut store, "allocate", &[10u32.into()]); match result.unwrap_err() { VmError::ResultMismatch { function_name, @@ -705,30 +800,34 @@ mod tests { assert_eq!(expected, 0); assert_eq!(actual, 1); } - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } } #[test] fn call_function1_works() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); - let result = env.call_function1("allocate", &[10u32.into()]).unwrap(); + let result = env + .call_function1(&mut store, "allocate", &[10u32.into()]) + .unwrap(); let ptr = ref_to_u32(&result).unwrap(); assert!(ptr > 0); } #[test] fn call_function1_errors_for_wrong_result_count() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, mut store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); - let result = env.call_function1("allocate", &[10u32.into()]).unwrap(); + let result = env + .call_function1(&mut store, "allocate", &[10u32.into()]) + .unwrap(); let ptr = ref_to_u32(&result).unwrap(); assert!(ptr > 0); - let result = env.call_function1("deallocate", &[ptr.into()]); + let result = env.call_function1(&mut store, "deallocate", &[ptr.into()]); match result.unwrap_err() { VmError::ResultMismatch { function_name, @@ -740,13 +839,13 @@ mod tests { assert_eq!(expected, 1); assert_eq!(actual, 0); } - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), } } #[test] fn with_storage_from_context_set_get() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); let val = env @@ -779,7 +878,7 @@ mod tests { #[test] #[should_panic(expected = "A panic occurred in the callback.")] fn with_storage_from_context_handles_panics() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); env.with_storage_from_context::<_, ()>(|_store| { @@ -790,7 +889,7 @@ mod tests { #[test] fn with_querier_from_context_works() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); let res = env @@ -813,7 +912,7 @@ mod tests { #[test] #[should_panic(expected = "A panic occurred in the callback.")] fn with_querier_from_context_handles_panics() { - let (env, _instance) = make_instance(TESTING_GAS_LIMIT); + let (env, _store, _instance) = make_instance(TESTING_GAS_LIMIT); leave_default_data(&env); env.with_querier_from_context::<_, ()>(|_querier| { diff --git a/packages/vm/src/errors/communication_error.rs b/packages/vm/src/errors/communication_error.rs index a5fb88e0e..f298a46d3 100644 --- a/packages/vm/src/errors/communication_error.rs +++ b/packages/vm/src/errors/communication_error.rs @@ -2,6 +2,7 @@ use std::fmt::Debug; use thiserror::Error; use super::region_validation_error::RegionValidationError; +use crate::memory::Region; /// An error in the communcation between contract and host. Those happen around imports and exports. #[derive(Error, Debug)] @@ -32,6 +33,12 @@ pub enum CommunicationError { RegionLengthTooBig { length: usize, max_length: usize }, #[error("Region too small. Got {}, required {}", size, required)] RegionTooSmall { size: usize, required: usize }, + #[error("Tried to access memory of region {:?} in Wasm memory of size {} bytes. This typically happens when the given Region pointer does not point to a proper Region struct.", region, memory_size)] + RegionAccessErr { + region: Region, + /// Current size of the linear memory in bytes + memory_size: usize, + }, #[error("Got a zero Wasm address")] ZeroAddress {}, } @@ -64,6 +71,13 @@ impl CommunicationError { CommunicationError::RegionTooSmall { size, required } } + pub(crate) fn region_access_err(region: Region, memory_size: usize) -> Self { + CommunicationError::RegionAccessErr { + region, + memory_size, + } + } + pub(crate) fn zero_address() -> Self { CommunicationError::ZeroAddress {} } @@ -83,7 +97,7 @@ mod tests { assert_eq!(offset, 345); assert_eq!(msg, "broken stuff"); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -92,7 +106,7 @@ mod tests { let error = CommunicationError::invalid_order(-745); match error { CommunicationError::InvalidOrder { value, .. } => assert_eq!(value, -745), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -101,7 +115,7 @@ mod tests { let error = CommunicationError::invalid_utf8("broken"); match error { CommunicationError::InvalidUtf8 { msg, .. } => assert_eq!(msg, "broken"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -115,7 +129,7 @@ mod tests { assert_eq!(length, 50); assert_eq!(max_length, 20); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -127,7 +141,7 @@ mod tests { assert_eq!(size, 12); assert_eq!(required, 33); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -136,7 +150,7 @@ mod tests { let error = CommunicationError::zero_address(); match error { CommunicationError::ZeroAddress { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } } diff --git a/packages/vm/src/errors/region_validation_error.rs b/packages/vm/src/errors/region_validation_error.rs index 7fc407e7c..bf9dd5e36 100644 --- a/packages/vm/src/errors/region_validation_error.rs +++ b/packages/vm/src/errors/region_validation_error.rs @@ -51,7 +51,7 @@ mod tests { assert_eq!(length, 50); assert_eq!(capacity, 20); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -65,7 +65,7 @@ mod tests { assert_eq!(offset, u32::MAX); assert_eq!(capacity, 1); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -74,7 +74,7 @@ mod tests { let error = RegionValidationError::zero_offset(); match error { RegionValidationError::ZeroOffset { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } } diff --git a/packages/vm/src/errors/vm_error.rs b/packages/vm/src/errors/vm_error.rs index 6140799bc..b0ed25f9a 100644 --- a/packages/vm/src/errors/vm_error.rs +++ b/packages/vm/src/errors/vm_error.rs @@ -145,6 +145,11 @@ pub enum VmError { #[cfg(feature = "backtraces")] backtrace: Backtrace, }, + #[error("Maximum call depth exceeded.")] + MaxCallDepthExceeded { + #[cfg(feature = "backtraces")] + backtrace: Backtrace, + }, } impl VmError { @@ -314,6 +319,13 @@ impl VmError { backtrace: Backtrace::capture(), } } + + pub(crate) fn max_call_depth_exceeded() -> Self { + VmError::MaxCallDepthExceeded { + #[cfg(feature = "backtraces")] + backtrace: Backtrace::capture(), + } + } } impl From for VmError { @@ -331,21 +343,29 @@ impl From for VmError { } } +impl From for VmError { + fn from(original: wasmer::wasmparser::BinaryReaderError) -> Self { + VmError::static_validation_err(format!( + "Wasm bytecode could not be deserialized. Deserialization error: \"{original}\"" + )) + } +} + impl From for VmError { fn from(original: wasmer::ExportError) -> Self { - VmError::resolve_err(format!("Could not get export: {}", original)) + VmError::resolve_err(format!("Could not get export: {original}")) } } impl From for VmError { fn from(original: wasmer::SerializeError) -> Self { - VmError::cache_err(format!("Could not serialize module: {}", original)) + VmError::cache_err(format!("Could not serialize module: {original}")) } } impl From for VmError { fn from(original: wasmer::DeserializeError) -> Self { - VmError::cache_err(format!("Could not deserialize module: {}", original)) + VmError::cache_err(format!("Could not deserialize module: {original}")) } } @@ -369,7 +389,7 @@ impl From for VmError { impl From for VmError { fn from(original: wasmer::CompileError) -> Self { - VmError::compile_err(format!("Could not compile: {}", original)) + VmError::compile_err(format!("Could not compile: {original}")) } } @@ -400,7 +420,7 @@ mod tests { source: BackendError::Unknown { msg }, .. } => assert_eq!(msg, "something went wrong"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -409,7 +429,7 @@ mod tests { let error = VmError::cache_err("something went wrong"); match error { VmError::CacheErr { msg, .. } => assert_eq!(msg, "something went wrong"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -418,7 +438,7 @@ mod tests { let error = VmError::compile_err("something went wrong"); match error { VmError::CompileErr { msg, .. } => assert_eq!(msg, "something went wrong"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -436,7 +456,7 @@ mod tests { assert_eq!(to_type, "u32"); assert_eq!(input, "-9"); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -448,7 +468,7 @@ mod tests { source: CryptoError::GenericErr { msg, .. }, .. } => assert_eq!(msg, "something went wrong"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -457,19 +477,19 @@ mod tests { let error = VmError::gas_depletion(); match error { VmError::GasDepletion { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn generic_err_works() { let guess = 7; - let error = VmError::generic_err(format!("{} is too low", guess)); + let error = VmError::generic_err(format!("{guess} is too low")); match error { VmError::GenericErr { msg, .. } => { assert_eq!(msg, String::from("7 is too low")); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -478,7 +498,7 @@ mod tests { let error = VmError::instantiation_err("something went wrong"); match error { VmError::InstantiationErr { msg, .. } => assert_eq!(msg, "something went wrong"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -487,7 +507,7 @@ mod tests { let error = VmError::integrity_err(); match error { VmError::IntegrityErr { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -501,7 +521,7 @@ mod tests { assert_eq!(target_type, "Book"); assert_eq!(msg, "Missing field: title"); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -515,7 +535,7 @@ mod tests { assert_eq!(source_type, "Book"); assert_eq!(msg, "Content too long"); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -524,7 +544,7 @@ mod tests { let error = VmError::resolve_err("function has different signature"); match error { VmError::ResolveErr { msg, .. } => assert_eq!(msg, "function has different signature"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -542,7 +562,7 @@ mod tests { assert_eq!(expected, 0); assert_eq!(actual, 1); } - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -551,7 +571,7 @@ mod tests { let error = VmError::runtime_err("something went wrong"); match error { VmError::RuntimeErr { msg, .. } => assert_eq!(msg, "something went wrong"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -560,7 +580,7 @@ mod tests { let error = VmError::static_validation_err("export xy missing"); match error { VmError::StaticValidationErr { msg, .. } => assert_eq!(msg, "export xy missing"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -569,7 +589,7 @@ mod tests { let error = VmError::uninitialized_context_data("foo"); match error { VmError::UninitializedContextData { kind, .. } => assert_eq!(kind, "foo"), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -578,7 +598,7 @@ mod tests { let error = VmError::write_access_denied(); match error { VmError::WriteAccessDenied { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } } diff --git a/packages/vm/src/filesystem.rs b/packages/vm/src/filesystem.rs new file mode 100644 index 000000000..45a60f435 --- /dev/null +++ b/packages/vm/src/filesystem.rs @@ -0,0 +1,43 @@ +use std::{fs::create_dir_all, path::Path}; + +#[derive(Debug)] +pub struct MkdirPFailure; + +/// An implementation for `mkdir -p`. +/// +/// This is a thin wrapper around fs::create_dir_all that +/// hides all OS specific error messages to ensure they don't end up +/// breaking consensus. +pub fn mkdir_p(path: &Path) -> Result<(), MkdirPFailure> { + create_dir_all(path).map_err(|_e| MkdirPFailure) +} + +#[cfg(test)] +mod tests { + use tempfile::TempDir; + + use super::*; + + #[test] + fn mkdir_p_works() { + let tmp_root = TempDir::new().unwrap(); + + // Can create + let path = tmp_root.path().join("something"); + assert!(!path.is_dir()); + mkdir_p(&path).unwrap(); + assert!(path.is_dir()); + + // Can be called on existing dir + let path = tmp_root.path().join("something else"); + assert!(!path.is_dir()); + mkdir_p(&path).unwrap(); + assert!(path.is_dir()); + mkdir_p(&path).unwrap(); // no-op + assert!(path.is_dir()); + + // Fails for dir with null + let path = tmp_root.path().join("something\0with NULL"); + mkdir_p(&path).unwrap_err(); + } +} diff --git a/packages/vm/src/imports.rs b/packages/vm/src/imports.rs index a0d60f145..87b722f71 100644 --- a/packages/vm/src/imports.rs +++ b/packages/vm/src/imports.rs @@ -1,6 +1,7 @@ //! Import implementations use std::cmp::max; +use std::marker::PhantomData; use cosmwasm_crypto::{ ed25519_batch_verify, ed25519_verify, secp256k1_recover_pubkey, secp256k1_verify, @@ -12,10 +13,11 @@ use cosmwasm_crypto::{ #[cfg(feature = "iterator")] use cosmwasm_std::Order; +use wasmer::{AsStoreMut, FunctionEnvMut}; use crate::backend::{BackendApi, BackendError, Querier, Storage}; use crate::conversion::{ref_to_u32, to_u32}; -use crate::environment::{process_gas_info, Environment}; +use crate::environment::{process_gas_info, DebugInfo, Environment}; use crate::errors::{CommunicationError, VmError, VmResult}; #[cfg(feature = "iterator")] use crate::memory::maybe_read_region; @@ -75,168 +77,211 @@ const MAX_LENGTH_ABORT: usize = 2 * MI; // through the env. /// Reads a storage entry from the VM's storage into Wasm memory -pub fn do_db_read( - env: &Environment, +pub fn do_db_read( + mut env: FunctionEnvMut>, key_ptr: u32, ) -> VmResult { - let key = read_region(&env.memory(), key_ptr, MAX_LENGTH_DB_KEY)?; + let (data, mut store) = env.data_and_store_mut(); - let (result, gas_info) = env.with_storage_from_context::<_, _>(|store| Ok(store.get(&key)))?; - process_gas_info::(env, gas_info)?; + let key = read_region(&data.memory(&mut store), key_ptr, MAX_LENGTH_DB_KEY)?; + + let (result, gas_info) = data.with_storage_from_context::<_, _>(|store| Ok(store.get(&key)))?; + process_gas_info(data, &mut store, gas_info)?; let value = result?; let out_data = match value { Some(data) => data, None => return Ok(0), }; - write_to_contract::(env, &out_data) + write_to_contract(data, &mut store, &out_data) } /// Writes a storage entry from Wasm memory into the VM's storage -pub fn do_db_write( - env: &Environment, +pub fn do_db_write( + mut env: FunctionEnvMut>, key_ptr: u32, value_ptr: u32, ) -> VmResult<()> { - if env.is_storage_readonly() { + let (data, mut store) = env.data_and_store_mut(); + + if data.is_storage_readonly() { return Err(VmError::write_access_denied()); } - let key = read_region(&env.memory(), key_ptr, MAX_LENGTH_DB_KEY)?; - let value = read_region(&env.memory(), value_ptr, MAX_LENGTH_DB_VALUE)?; + let key = read_region(&data.memory(&mut store), key_ptr, MAX_LENGTH_DB_KEY)?; + let value = read_region(&data.memory(&mut store), value_ptr, MAX_LENGTH_DB_VALUE)?; let (result, gas_info) = - env.with_storage_from_context::<_, _>(|store| Ok(store.set(&key, &value)))?; - process_gas_info::(env, gas_info)?; + data.with_storage_from_context::<_, _>(|store| Ok(store.set(&key, &value)))?; + process_gas_info(data, &mut store, gas_info)?; result?; Ok(()) } -pub fn do_db_remove( - env: &Environment, +pub fn do_db_remove( + mut env: FunctionEnvMut>, key_ptr: u32, ) -> VmResult<()> { - if env.is_storage_readonly() { + let (data, mut store) = env.data_and_store_mut(); + + if data.is_storage_readonly() { return Err(VmError::write_access_denied()); } - let key = read_region(&env.memory(), key_ptr, MAX_LENGTH_DB_KEY)?; + let key = read_region(&data.memory(&mut store), key_ptr, MAX_LENGTH_DB_KEY)?; let (result, gas_info) = - env.with_storage_from_context::<_, _>(|store| Ok(store.remove(&key)))?; - process_gas_info(env, gas_info)?; + data.with_storage_from_context::<_, _>(|store| Ok(store.remove(&key)))?; + process_gas_info(data, &mut store, gas_info)?; result?; Ok(()) } -pub fn do_addr_validate( - env: &Environment, +pub fn do_addr_validate( + mut env: FunctionEnvMut>, source_ptr: u32, ) -> VmResult { - let source_data = read_region(&env.memory(), source_ptr, MAX_LENGTH_HUMAN_ADDRESS)?; + let (data, mut store) = env.data_and_store_mut(); + + let source_data = read_region( + &data.memory(&mut store), + source_ptr, + MAX_LENGTH_HUMAN_ADDRESS, + )?; if source_data.is_empty() { - return write_to_contract::(env, b"Input is empty"); + return write_to_contract(data, &mut store, b"Input is empty"); } let source_string = match String::from_utf8(source_data) { Ok(s) => s, - Err(_) => return write_to_contract::(env, b"Input is not valid UTF-8"), + Err(_) => return write_to_contract(data, &mut store, b"Input is not valid UTF-8"), }; - let (result, gas_info) = env.api.canonical_address(&source_string); - process_gas_info::(env, gas_info)?; + let (result, gas_info) = data.api.canonical_address(&source_string); + process_gas_info(data, &mut store, gas_info)?; let canonical = match result { Ok(data) => data, Err(BackendError::UserErr { msg, .. }) => { - return write_to_contract::(env, msg.as_bytes()) + return write_to_contract(data, &mut store, msg.as_bytes()) } Err(err) => return Err(VmError::from(err)), }; - let (result, gas_info) = env.api.human_address(&canonical); - process_gas_info::(env, gas_info)?; + let (result, gas_info) = data.api.human_address(&canonical); + process_gas_info(data, &mut store, gas_info)?; let normalized = match result { Ok(addr) => addr, Err(BackendError::UserErr { msg, .. }) => { - return write_to_contract::(env, msg.as_bytes()) + return write_to_contract(data, &mut store, msg.as_bytes()) } Err(err) => return Err(VmError::from(err)), }; if normalized != source_string { - return write_to_contract::(env, b"Address is not normalized"); + return write_to_contract(data, &mut store, b"Address is not normalized"); } Ok(0) } -pub fn do_addr_canonicalize( - env: &Environment, +pub fn do_addr_canonicalize( + mut env: FunctionEnvMut>, source_ptr: u32, destination_ptr: u32, ) -> VmResult { - let source_data = read_region(&env.memory(), source_ptr, MAX_LENGTH_HUMAN_ADDRESS)?; + let (data, mut store) = env.data_and_store_mut(); + + let source_data = read_region( + &data.memory(&mut store), + source_ptr, + MAX_LENGTH_HUMAN_ADDRESS, + )?; if source_data.is_empty() { - return write_to_contract::(env, b"Input is empty"); + return write_to_contract(data, &mut store, b"Input is empty"); } let source_string = match String::from_utf8(source_data) { Ok(s) => s, - Err(_) => return write_to_contract::(env, b"Input is not valid UTF-8"), + Err(_) => return write_to_contract(data, &mut store, b"Input is not valid UTF-8"), }; - let (result, gas_info) = env.api.canonical_address(&source_string); - process_gas_info::(env, gas_info)?; + let (result, gas_info) = data.api.canonical_address(&source_string); + process_gas_info(data, &mut store, gas_info)?; match result { Ok(canonical) => { - write_region(&env.memory(), destination_ptr, canonical.as_slice())?; + write_region( + &data.memory(&mut store), + destination_ptr, + canonical.as_slice(), + )?; Ok(0) } Err(BackendError::UserErr { msg, .. }) => { - Ok(write_to_contract::(env, msg.as_bytes())?) + Ok(write_to_contract(data, &mut store, msg.as_bytes())?) } Err(err) => Err(VmError::from(err)), } } -pub fn do_addr_humanize( - env: &Environment, +pub fn do_addr_humanize( + mut env: FunctionEnvMut>, source_ptr: u32, destination_ptr: u32, ) -> VmResult { - let canonical = read_region(&env.memory(), source_ptr, MAX_LENGTH_CANONICAL_ADDRESS)?; + let (data, mut store) = env.data_and_store_mut(); - let (result, gas_info) = env.api.human_address(&canonical); - process_gas_info::(env, gas_info)?; + let canonical = read_region( + &data.memory(&mut store), + source_ptr, + MAX_LENGTH_CANONICAL_ADDRESS, + )?; + + let (result, gas_info) = data.api.human_address(&canonical); + process_gas_info(data, &mut store, gas_info)?; match result { Ok(human) => { - write_region(&env.memory(), destination_ptr, human.as_bytes())?; + write_region(&data.memory(&mut store), destination_ptr, human.as_bytes())?; Ok(0) } Err(BackendError::UserErr { msg, .. }) => { - Ok(write_to_contract::(env, msg.as_bytes())?) + Ok(write_to_contract(data, &mut store, msg.as_bytes())?) } Err(err) => Err(VmError::from(err)), } } -pub fn do_secp256k1_verify( - env: &Environment, +/// Return code (error code) for a valid signature +const SECP256K1_VERIFY_CODE_VALID: u32 = 0; + +/// Return code (error code) for an invalid signature +const SECP256K1_VERIFY_CODE_INVALID: u32 = 1; + +pub fn do_secp256k1_verify( + mut env: FunctionEnvMut>, hash_ptr: u32, signature_ptr: u32, pubkey_ptr: u32, ) -> VmResult { - let hash = read_region(&env.memory(), hash_ptr, MESSAGE_HASH_MAX_LEN)?; - let signature = read_region(&env.memory(), signature_ptr, ECDSA_SIGNATURE_LEN)?; - let pubkey = read_region(&env.memory(), pubkey_ptr, ECDSA_PUBKEY_MAX_LEN)?; + let (data, mut store) = env.data_and_store_mut(); + + let hash = read_region(&data.memory(&mut store), hash_ptr, MESSAGE_HASH_MAX_LEN)?; + let signature = read_region(&data.memory(&mut store), signature_ptr, ECDSA_SIGNATURE_LEN)?; + let pubkey = read_region(&data.memory(&mut store), pubkey_ptr, ECDSA_PUBKEY_MAX_LEN)?; - let gas_info = GasInfo::with_cost(env.gas_config.secp256k1_verify_cost); - process_gas_info::(env, gas_info)?; + let gas_info = GasInfo::with_cost(data.gas_config.secp256k1_verify_cost); + process_gas_info(data, &mut store, gas_info)?; let result = secp256k1_verify(&hash, &signature, &pubkey); - Ok(result.map_or_else( - |err| match err { + let code = match result { + Ok(valid) => { + if valid { + SECP256K1_VERIFY_CODE_VALID + } else { + SECP256K1_VERIFY_CODE_INVALID + } + } + Err(err) => match err { CryptoError::InvalidHashFormat { .. } | CryptoError::InvalidPubkeyFormat { .. } | CryptoError::InvalidSignatureFormat { .. } @@ -246,29 +291,35 @@ pub fn do_secp256k1_verify( | CryptoError::InputsTooLarger { .. } | CryptoError::InputTooLong { .. } => panic!("Error must not happen for this call"), }, - |valid| if valid { 0 } else { 1 }, - )) + }; + Ok(code) } -pub fn do_secp256k1_recover_pubkey( - env: &Environment, +pub fn do_secp256k1_recover_pubkey< + A: BackendApi + 'static, + S: Storage + 'static, + Q: Querier + 'static, +>( + mut env: FunctionEnvMut>, hash_ptr: u32, signature_ptr: u32, recover_param: u32, ) -> VmResult { - let hash = read_region(&env.memory(), hash_ptr, MESSAGE_HASH_MAX_LEN)?; - let signature = read_region(&env.memory(), signature_ptr, ECDSA_SIGNATURE_LEN)?; + let (data, mut store) = env.data_and_store_mut(); + + let hash = read_region(&data.memory(&mut store), hash_ptr, MESSAGE_HASH_MAX_LEN)?; + let signature = read_region(&data.memory(&mut store), signature_ptr, ECDSA_SIGNATURE_LEN)?; let recover_param: u8 = match recover_param.try_into() { Ok(rp) => rp, Err(_) => return Ok((CryptoError::invalid_recovery_param().code() as u64) << 32), }; - let gas_info = GasInfo::with_cost(env.gas_config.secp256k1_recover_pubkey_cost); - process_gas_info::(env, gas_info)?; + let gas_info = GasInfo::with_cost(data.gas_config.secp256k1_recover_pubkey_cost); + process_gas_info(data, &mut store, gas_info)?; let result = secp256k1_recover_pubkey(&hash, &signature, recover_param); match result { Ok(pubkey) => { - let pubkey_ptr = write_to_contract::(env, pubkey.as_ref())?; + let pubkey_ptr = write_to_contract(data, &mut store, pubkey.as_ref())?; Ok(to_low_half(pubkey_ptr)) } Err(err) => match err { @@ -284,21 +335,44 @@ pub fn do_secp256k1_recover_pubkey( } } -pub fn do_ed25519_verify( - env: &Environment, +/// Return code (error code) for a valid signature +const ED25519_VERIFY_CODE_VALID: u32 = 0; + +/// Return code (error code) for an invalid signature +const ED25519_VERIFY_CODE_INVALID: u32 = 1; + +pub fn do_ed25519_verify( + mut env: FunctionEnvMut>, message_ptr: u32, signature_ptr: u32, pubkey_ptr: u32, ) -> VmResult { - let message = read_region(&env.memory(), message_ptr, MAX_LENGTH_ED25519_MESSAGE)?; - let signature = read_region(&env.memory(), signature_ptr, MAX_LENGTH_ED25519_SIGNATURE)?; - let pubkey = read_region(&env.memory(), pubkey_ptr, EDDSA_PUBKEY_LEN)?; + let (data, mut store) = env.data_and_store_mut(); - let gas_info = GasInfo::with_cost(env.gas_config.ed25519_verify_cost); - process_gas_info::(env, gas_info)?; + let message = read_region( + &data.memory(&mut store), + message_ptr, + MAX_LENGTH_ED25519_MESSAGE, + )?; + let signature = read_region( + &data.memory(&mut store), + signature_ptr, + MAX_LENGTH_ED25519_SIGNATURE, + )?; + let pubkey = read_region(&data.memory(&mut store), pubkey_ptr, EDDSA_PUBKEY_LEN)?; + + let gas_info = GasInfo::with_cost(data.gas_config.ed25519_verify_cost); + process_gas_info(data, &mut store, gas_info)?; let result = ed25519_verify(&message, &signature, &pubkey); - Ok(result.map_or_else( - |err| match err { + let code = match result { + Ok(valid) => { + if valid { + ED25519_VERIFY_CODE_VALID + } else { + ED25519_VERIFY_CODE_INVALID + } + } + Err(err) => match err { CryptoError::InvalidPubkeyFormat { .. } | CryptoError::InvalidSignatureFormat { .. } | CryptoError::GenericErr { .. } => err.code(), @@ -308,28 +382,34 @@ pub fn do_ed25519_verify( | CryptoError::InputsTooLarger { .. } | CryptoError::InputTooLong { .. } => panic!("Error must not happen for this call"), }, - |valid| if valid { 0 } else { 1 }, - )) + }; + Ok(code) } -pub fn do_ed25519_batch_verify( - env: &Environment, +pub fn do_ed25519_batch_verify< + A: BackendApi + 'static, + S: Storage + 'static, + Q: Querier + 'static, +>( + mut env: FunctionEnvMut>, messages_ptr: u32, signatures_ptr: u32, public_keys_ptr: u32, ) -> VmResult { + let (data, mut store) = env.data_and_store_mut(); + let messages = read_region( - &env.memory(), + &data.memory(&mut store), messages_ptr, (MAX_LENGTH_ED25519_MESSAGE + 4) * MAX_COUNT_ED25519_BATCH, )?; let signatures = read_region( - &env.memory(), + &data.memory(&mut store), signatures_ptr, (MAX_LENGTH_ED25519_SIGNATURE + 4) * MAX_COUNT_ED25519_BATCH, )?; let public_keys = read_region( - &env.memory(), + &data.memory(&mut store), public_keys_ptr, (EDDSA_PUBKEY_LEN + 4) * MAX_COUNT_ED25519_BATCH, )?; @@ -339,15 +419,22 @@ pub fn do_ed25519_batch_verify( let public_keys = decode_sections(&public_keys); let gas_cost = if public_keys.len() == 1 { - env.gas_config.ed25519_batch_verify_one_pubkey_cost + data.gas_config.ed25519_batch_verify_one_pubkey_cost } else { - env.gas_config.ed25519_batch_verify_cost + data.gas_config.ed25519_batch_verify_cost } * signatures.len() as u64; - let gas_info = GasInfo::with_cost(max(gas_cost, env.gas_config.ed25519_verify_cost)); - process_gas_info::(env, gas_info)?; + let gas_info = GasInfo::with_cost(max(gas_cost, data.gas_config.ed25519_verify_cost)); + process_gas_info(data, &mut store, gas_info)?; let result = ed25519_batch_verify(&messages, &signatures, &public_keys); - Ok(result.map_or_else( - |err| match err { + let code = match result { + Ok(valid) => { + if valid { + ED25519_VERIFY_CODE_VALID + } else { + ED25519_VERIFY_CODE_INVALID + } + } + Err(err) => match err { CryptoError::BatchErr { .. } | CryptoError::InvalidPubkeyFormat { .. } | CryptoError::InvalidSignatureFormat { .. } @@ -357,32 +444,34 @@ pub fn do_ed25519_batch_verify( | CryptoError::InputsTooLarger { .. } | CryptoError::InputTooLong { .. } => panic!("Error must not happen for this call"), }, - |valid| (!valid).into(), - )) + }; + Ok(code) } -pub fn do_sha1_calculate( - env: &Environment, +pub fn do_sha1_calculate( + mut env: FunctionEnvMut>, hash_inputs_ptr: u32, ) -> VmResult { + let (data, mut store) = env.data_and_store_mut(); + let hash_inputs = read_region( - &env.memory(), + &data.memory(&mut store), hash_inputs_ptr, (MAX_LENGTH_SHA1_MESSAGE + 4) * MAX_COUNT_SHA1_INPUT, )?; let hash_inputs = decode_sections(&hash_inputs); let result = sha1_calculate(&hash_inputs); - let mut gas_cost = env.gas_config.sha1_calculate_cost; + let mut gas_cost = data.gas_config.sha1_calculate_cost; //For sha1, the execution time does not increase linearly by the number of updates(count of inputs). if hash_inputs.len() > 1 { - gas_cost += (env.gas_config.sha1_calculate_cost * (hash_inputs.len() - 1) as u64) / 2; + gas_cost += (data.gas_config.sha1_calculate_cost * (hash_inputs.len() - 1) as u64) / 2; } let gas_info = GasInfo::with_cost(gas_cost); - process_gas_info::(env, gas_info)?; + process_gas_info::(data, &mut store, gas_info)?; match result { Ok(hash) => { - let hash_ptr = write_to_contract::(env, &hash)?; + let hash_ptr = write_to_contract(data, &mut store, &hash)?; Ok(to_low_half(hash_ptr)) } Err(err) => match err { @@ -403,93 +492,156 @@ pub fn do_sha1_calculate( /// Prints a debug message to console. /// This does not charge gas, so debug printing should be disabled when used in a blockchain module. -pub fn do_debug( - env: &Environment, +pub fn do_debug( + mut env: FunctionEnvMut>, message_ptr: u32, ) -> VmResult<()> { - if env.print_debug { - let message_data = read_region(&env.memory(), message_ptr, MAX_LENGTH_DEBUG)?; + let (data, mut store) = env.data_and_store_mut(); + + if let Some(debug_handler) = data.debug_handler() { + let message_data = read_region(&data.memory(&mut store), message_ptr, MAX_LENGTH_DEBUG)?; let msg = String::from_utf8_lossy(&message_data); - println!("{}", msg); + let gas_remaining = data.get_gas_left(&mut store); + debug_handler.borrow_mut()( + &msg, + DebugInfo { + gas_remaining, + __lifetime: PhantomData, + }, + ); } Ok(()) } /// Aborts the contract and shows the given error message -pub fn do_abort( - env: &Environment, +pub fn do_abort( + mut env: FunctionEnvMut>, message_ptr: u32, ) -> VmResult<()> { - let message_data = read_region(&env.memory(), message_ptr, MAX_LENGTH_ABORT)?; + let (data, mut store) = env.data_and_store_mut(); + + let message_data = read_region(&data.memory(&mut store), message_ptr, MAX_LENGTH_ABORT)?; let msg = String::from_utf8_lossy(&message_data); Err(VmError::aborted(msg)) } -/// Creates a Region in the contract, writes the given data to it and returns the memory location -fn write_to_contract( - env: &Environment, - input: &[u8], -) -> VmResult { - let out_size = to_u32(input.len())?; - let result = env.call_function1("allocate", &[out_size.into()])?; - let target_ptr = ref_to_u32(&result)?; - if target_ptr == 0 { - return Err(CommunicationError::zero_address().into()); - } - write_region(&env.memory(), target_ptr, input)?; - Ok(target_ptr) -} - -pub fn do_query_chain( - env: &Environment, +pub fn do_query_chain( + mut env: FunctionEnvMut>, request_ptr: u32, ) -> VmResult { - let request = read_region(&env.memory(), request_ptr, MAX_LENGTH_QUERY_CHAIN_REQUEST)?; + let (data, mut store) = env.data_and_store_mut(); + + let request = read_region( + &data.memory(&mut store), + request_ptr, + MAX_LENGTH_QUERY_CHAIN_REQUEST, + )?; - let gas_remaining = env.get_gas_left(); - let (result, gas_info) = env.with_querier_from_context::<_, _>(|querier| { + let gas_remaining = data.get_gas_left(&mut store); + let (result, gas_info) = data.with_querier_from_context::<_, _>(|querier| { Ok(querier.query_raw(&request, gas_remaining)) })?; - process_gas_info::(env, gas_info)?; + process_gas_info(data, &mut store, gas_info)?; let serialized = to_vec(&result?)?; - write_to_contract::(env, &serialized) + write_to_contract(data, &mut store, &serialized) } #[cfg(feature = "iterator")] -pub fn do_db_scan( - env: &Environment, +pub fn do_db_scan( + mut env: FunctionEnvMut>, start_ptr: u32, end_ptr: u32, order: i32, ) -> VmResult { - let start = maybe_read_region(&env.memory(), start_ptr, MAX_LENGTH_DB_KEY)?; - let end = maybe_read_region(&env.memory(), end_ptr, MAX_LENGTH_DB_KEY)?; + let (data, mut store) = env.data_and_store_mut(); + + let start = maybe_read_region(&data.memory(&mut store), start_ptr, MAX_LENGTH_DB_KEY)?; + let end = maybe_read_region(&data.memory(&mut store), end_ptr, MAX_LENGTH_DB_KEY)?; let order: Order = order .try_into() .map_err(|_| CommunicationError::invalid_order(order))?; - let (result, gas_info) = env.with_storage_from_context::<_, _>(|store| { + let (result, gas_info) = data.with_storage_from_context::<_, _>(|store| { Ok(store.scan(start.as_deref(), end.as_deref(), order)) })?; - process_gas_info::(env, gas_info)?; + process_gas_info(data, &mut store, gas_info)?; let iterator_id = result?; Ok(iterator_id) } #[cfg(feature = "iterator")] -pub fn do_db_next( - env: &Environment, +pub fn do_db_next( + mut env: FunctionEnvMut>, iterator_id: u32, ) -> VmResult { + let (data, mut store) = env.data_and_store_mut(); + let (result, gas_info) = - env.with_storage_from_context::<_, _>(|store| Ok(store.next(iterator_id)))?; - process_gas_info::(env, gas_info)?; + data.with_storage_from_context::<_, _>(|store| Ok(store.next(iterator_id)))?; + + process_gas_info(data, &mut store, gas_info)?; // Empty key will later be treated as _no more element_. let (key, value) = result?.unwrap_or_else(|| (Vec::::new(), Vec::::new())); let out_data = encode_sections(&[key, value])?; - write_to_contract::(env, &out_data) + write_to_contract(data, &mut store, &out_data) +} + +#[cfg(feature = "iterator")] +pub fn do_db_next_key( + mut env: FunctionEnvMut>, + iterator_id: u32, +) -> VmResult { + let (data, mut store) = env.data_and_store_mut(); + + let (result, gas_info) = + data.with_storage_from_context::<_, _>(|store| Ok(store.next_key(iterator_id)))?; + + process_gas_info(data, &mut store, gas_info)?; + + let key = match result? { + Some(key) => key, + None => return Ok(0), + }; + + write_to_contract(data, &mut store, &key) +} + +#[cfg(feature = "iterator")] +pub fn do_db_next_value( + mut env: FunctionEnvMut>, + iterator_id: u32, +) -> VmResult { + let (data, mut store) = env.data_and_store_mut(); + + let (result, gas_info) = + data.with_storage_from_context::<_, _>(|store| Ok(store.next_value(iterator_id)))?; + + process_gas_info(data, &mut store, gas_info)?; + + let value = match result? { + Some(value) => value, + None => return Ok(0), + }; + + write_to_contract(data, &mut store, &value) +} + +/// Creates a Region in the contract, writes the given data to it and returns the memory location +fn write_to_contract( + data: &Environment, + store: &mut impl AsStoreMut, + input: &[u8], +) -> VmResult { + let out_size = to_u32(input.len())?; + let result = data.call_function1(store, "allocate", &[out_size.into()])?; + let target_ptr = ref_to_u32(&result)?; + if target_ptr == 0 { + return Err(CommunicationError::zero_address().into()); + } + write_region(&data.memory(store), target_ptr, input)?; + Ok(target_ptr) } /// Returns the data shifted by 32 bits towards the most significant bit. @@ -521,12 +673,12 @@ mod tests { }; use hex_literal::hex; use std::ptr::NonNull; - use wasmer::{imports, Function, Instance as WasmerInstance}; + use wasmer::{imports, Function, FunctionEnv, Instance as WasmerInstance, Store}; use crate::backend::{BackendError, Storage}; use crate::size::Size; use crate::testing::{MockApi, MockQuerier, MockStorage}; - use crate::wasm_backend::compile; + use crate::wasm_backend::{compile, make_compiling_engine}; static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); @@ -556,45 +708,70 @@ mod tests { fn make_instance( api: MockApi, ) -> ( - Environment, + FunctionEnv>, + Store, Box, ) { let gas_limit = TESTING_GAS_LIMIT; - let env = Environment::new(api, gas_limit, false); + let env = Environment::new(api, gas_limit); + + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine, CONTRACT).unwrap(); + let mut store = Store::new(engine); + + let fe = FunctionEnv::new(&mut store, env); - let module = compile(CONTRACT, TESTING_MEMORY_LIMIT, &[]).unwrap(); - let store = module.store(); // we need stubs for all required imports let import_obj = imports! { "env" => { - "db_read" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "db_write" => Function::new_native(store, |_a: u32, _b: u32| {}), - "db_remove" => Function::new_native(store, |_a: u32| {}), - "db_scan" => Function::new_native(store, |_a: u32, _b: u32, _c: i32| -> u32 { 0 }), - "db_next" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "query_chain" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "addr_validate" => Function::new_native(store, |_a: u32| -> u32 { 0 }), - "addr_canonicalize" => Function::new_native(store, |_a: u32, _b: u32| -> u32 { 0 }), - "addr_humanize" => Function::new_native(store, |_a: u32, _b: u32| -> u32 { 0 }), - "secp256k1_verify" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), - "secp256k1_recover_pubkey" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u64 { 0 }), - "ed25519_verify" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), - "ed25519_batch_verify" => Function::new_native(store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), - "sha1_calculate" => Function::new_native(store, |_a: u32| -> u64 { 0 }), - "debug" => Function::new_native(store, |_a: u32| {}), + "db_read" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "db_write" => Function::new_typed(&mut store, |_a: u32, _b: u32| {}), + "db_remove" => Function::new_typed(&mut store, |_a: u32| {}), + "db_scan" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: i32| -> u32 { 0 }), + "db_next" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "db_next_key" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "db_next_value" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "query_chain" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "addr_validate" => Function::new_typed(&mut store, |_a: u32| -> u32 { 0 }), + "addr_canonicalize" => Function::new_typed(&mut store, |_a: u32, _b: u32| -> u32 { 0 }), + "addr_humanize" => Function::new_typed(&mut store, |_a: u32, _b: u32| -> u32 { 0 }), + "secp256k1_verify" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), + "secp256k1_recover_pubkey" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u64 { 0 }), + "ed25519_verify" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), + "ed25519_batch_verify" => Function::new_typed(&mut store, |_a: u32, _b: u32, _c: u32| -> u32 { 0 }), + "debug" => Function::new_typed(&mut store, |_a: u32| {}), + "abort" => Function::new_typed(&mut store, |_a: u32| {}), }, }; - let instance = Box::from(WasmerInstance::new(&module, &import_obj).unwrap()); + let wasmer_instance = + Box::from(WasmerInstance::new(&mut store, &module, &import_obj).unwrap()); + let memory = wasmer_instance + .exports + .get_memory("memory") + .unwrap() + .clone(); + + fe.as_mut(&mut store).memory = Some(memory); - let instance_ptr = NonNull::from(instance.as_ref()); - env.set_wasmer_instance(Some(instance_ptr)); - env.set_gas_left(gas_limit); - env.set_storage_readonly(false); + let instance_ptr = NonNull::from(wasmer_instance.as_ref()); - (env, instance) + { + let mut fe_mut = fe.clone().into_mut(&mut store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + env.set_wasmer_instance(Some(instance_ptr)); + env.set_gas_left(&mut store, gas_limit); + env.set_storage_readonly(false); + } + + (fe, store, wasmer_instance) } - fn leave_default_data(env: &Environment) { + fn leave_default_data( + fe_mut: &mut FunctionEnvMut>, + ) { + let (env, mut _store) = fe_mut.data_and_store_mut(); + // create some mock data let mut storage = MockStorage::new(); storage.set(KEY1, VALUE1).0.expect("error setting"); @@ -604,88 +781,106 @@ mod tests { env.move_in(storage, querier); } - fn write_data(env: &Environment, data: &[u8]) -> u32 { + fn write_data( + fe_mut: &mut FunctionEnvMut>, + data: &[u8], + ) -> u32 { + let (env, mut store) = fe_mut.data_and_store_mut(); + let result = env - .call_function1("allocate", &[(data.len() as u32).into()]) + .call_function1(&mut store, "allocate", &[(data.len() as u32).into()]) .unwrap(); let region_ptr = ref_to_u32(&result).unwrap(); - write_region(&env.memory(), region_ptr, data).expect("error writing"); + write_region(&env.memory(&mut store), region_ptr, data).expect("error writing"); region_ptr } - fn create_empty(wasmer_instance: &mut WasmerInstance, capacity: u32) -> u32 { + fn create_empty( + wasmer_instance: &mut WasmerInstance, + fe_mut: &mut FunctionEnvMut>, + capacity: u32, + ) -> u32 { + let (_, mut store) = fe_mut.data_and_store_mut(); let allocate = wasmer_instance .exports .get_function("allocate") .expect("error getting function"); let result = allocate - .call(&[capacity.into()]) + .call(&mut store, &[capacity.into()]) .expect("error calling allocate"); ref_to_u32(&result[0]).expect("error converting result") } /// A Region reader that is just good enough for the tests in this file fn force_read( - env: &Environment, + fe_mut: &mut FunctionEnvMut>, region_ptr: u32, ) -> Vec { - read_region(&env.memory(), region_ptr, 5000).unwrap() + let (env, mut store) = fe_mut.data_and_store_mut(); + + read_region(&env.memory(&mut store), region_ptr, 5000).unwrap() } #[test] fn do_db_read_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); - let key_ptr = write_data(&env, KEY1); - let result = do_db_read(&env, key_ptr); + let key_ptr = write_data(&mut fe_mut, KEY1); + let result = do_db_read(fe_mut.as_mut(), key_ptr); let value_ptr = result.unwrap(); assert!(value_ptr > 0); - assert_eq!(force_read(&env, value_ptr as u32), VALUE1); + leave_default_data(&mut fe_mut); + assert_eq!(force_read(&mut fe_mut, value_ptr), VALUE1); } #[test] fn do_db_read_works_for_non_existent_key() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); - let key_ptr = write_data(&env, b"I do not exist in storage"); - let result = do_db_read(&env, key_ptr); + let key_ptr = write_data(&mut fe_mut, b"I do not exist in storage"); + let result = do_db_read(fe_mut, key_ptr); assert_eq!(result.unwrap(), 0); } #[test] fn do_db_read_fails_for_large_key() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); - let key_ptr = write_data(&env, &vec![7u8; 300 * 1024]); - let result = do_db_read(&env, key_ptr); + let key_ptr = write_data(&mut fe_mut, &vec![7u8; 300 * 1024]); + let result = do_db_read(fe_mut, key_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, 300 * 1024), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_db_write_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, b"new storage key"); - let value_ptr = write_data(&env, b"new value"); + let key_ptr = write_data(&mut fe_mut, b"new storage key"); + let value_ptr = write_data(&mut fe_mut, b"new value"); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - do_db_write(&env, key_ptr, value_ptr).unwrap(); + do_db_write(fe_mut.as_mut(), key_ptr, value_ptr).unwrap(); - let val = env + let val = fe_mut + .data() .with_storage_from_context::<_, _>(|store| { Ok(store .get(b"new storage key") @@ -699,16 +894,18 @@ mod tests { #[test] fn do_db_write_can_override() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, KEY1); - let value_ptr = write_data(&env, VALUE2); + let key_ptr = write_data(&mut fe_mut, KEY1); + let value_ptr = write_data(&mut fe_mut, VALUE2); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - do_db_write(&env, key_ptr, value_ptr).unwrap(); + do_db_write(fe_mut.as_mut(), key_ptr, value_ptr).unwrap(); - let val = env + let val = fe_mut + .data() .with_storage_from_context::<_, _>(|store| { Ok(store.get(KEY1).0.expect("error getting value")) }) @@ -719,16 +916,18 @@ mod tests { #[test] fn do_db_write_works_for_empty_value() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, b"new storage key"); - let value_ptr = write_data(&env, b""); + let key_ptr = write_data(&mut fe_mut, b"new storage key"); + let value_ptr = write_data(&mut fe_mut, b""); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - do_db_write(&env, key_ptr, value_ptr).unwrap(); + do_db_write(fe_mut.as_mut(), key_ptr, value_ptr).unwrap(); - let val = env + let val = fe_mut + .data() .with_storage_from_context::<_, _>(|store| { Ok(store .get(b"new storage key") @@ -742,14 +941,15 @@ mod tests { #[test] fn do_db_write_fails_for_large_key() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, &vec![4u8; 300 * 1024]); - let value_ptr = write_data(&env, b"new value"); + let key_ptr = write_data(&mut fe_mut, &vec![4u8; 300 * 1024]); + let value_ptr = write_data(&mut fe_mut, b"new value"); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_db_write(&env, key_ptr, value_ptr); + let result = do_db_write(fe_mut, key_ptr, value_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: @@ -761,21 +961,22 @@ mod tests { assert_eq!(length, 300 * 1024); assert_eq!(max_length, MAX_LENGTH_DB_KEY); } - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), }; } #[test] fn do_db_write_fails_for_large_value() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, b"new storage key"); - let value_ptr = write_data(&env, &vec![5u8; 300 * 1024]); + let key_ptr = write_data(&mut fe_mut, b"new storage key"); + let value_ptr = write_data(&mut fe_mut, &vec![5u8; 300 * 1024]); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_db_write(&env, key_ptr, value_ptr); + let result = do_db_write(fe_mut, key_ptr, value_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: @@ -787,53 +988,60 @@ mod tests { assert_eq!(length, 300 * 1024); assert_eq!(max_length, MAX_LENGTH_DB_VALUE); } - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), }; } #[test] fn do_db_write_is_prohibited_in_readonly_contexts() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, b"new storage key"); - let value_ptr = write_data(&env, b"new value"); + let key_ptr = write_data(&mut fe_mut, b"new storage key"); + let value_ptr = write_data(&mut fe_mut, b"new value"); - leave_default_data(&env); - env.set_storage_readonly(true); + leave_default_data(&mut fe_mut); + fe_mut.data().set_storage_readonly(true); - let result = do_db_write(&env, key_ptr, value_ptr); + let result = do_db_write(fe_mut, key_ptr, value_ptr); match result.unwrap_err() { VmError::WriteAccessDenied { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_db_remove_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let existing_key = KEY1; - let key_ptr = write_data(&env, existing_key); + let key_ptr = write_data(&mut fe_mut, existing_key); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - env.with_storage_from_context::<_, _>(|store| { - println!("{:?}", store); - Ok(()) - }) - .unwrap(); + fe_mut + .data() + .with_storage_from_context::<_, _>(|store| { + println!("{store:?}"); + Ok(()) + }) + .unwrap(); - do_db_remove(&env, key_ptr).unwrap(); + do_db_remove(fe_mut.as_mut(), key_ptr).unwrap(); - env.with_storage_from_context::<_, _>(|store| { - println!("{:?}", store); - Ok(()) - }) - .unwrap(); + fe_mut + .data() + .with_storage_from_context::<_, _>(|store| { + println!("{store:?}"); + Ok(()) + }) + .unwrap(); - let value = env + let value = fe_mut + .data() .with_storage_from_context::<_, _>(|store| { Ok(store.get(existing_key).0.expect("error getting value")) }) @@ -844,17 +1052,19 @@ mod tests { #[test] fn do_db_remove_works_for_non_existent_key() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let non_existent_key = b"I do not exist"; - let key_ptr = write_data(&env, non_existent_key); + let key_ptr = write_data(&mut fe_mut, non_existent_key); - leave_default_data(&env); + leave_default_data(&mut fe_mut); // Note: right now we cannot differnetiate between an existent and a non-existent key - do_db_remove(&env, key_ptr).unwrap(); + do_db_remove(fe_mut.as_mut(), key_ptr).unwrap(); - let value = env + let value = fe_mut + .data() .with_storage_from_context::<_, _>(|store| { Ok(store.get(non_existent_key).0.expect("error getting value")) }) @@ -865,13 +1075,14 @@ mod tests { #[test] fn do_db_remove_fails_for_large_key() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, &vec![26u8; 300 * 1024]); + let key_ptr = write_data(&mut fe_mut, &vec![26u8; 300 * 1024]); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_db_remove(&env, key_ptr); + let result = do_db_remove(fe_mut, key_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: @@ -883,101 +1094,109 @@ mod tests { assert_eq!(length, 300 * 1024); assert_eq!(max_length, MAX_LENGTH_DB_KEY); } - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), }; } #[test] fn do_db_remove_is_prohibited_in_readonly_contexts() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let key_ptr = write_data(&env, b"a storage key"); + let key_ptr = write_data(&mut fe_mut, b"a storage key"); - leave_default_data(&env); - env.set_storage_readonly(true); + leave_default_data(&mut fe_mut); + fe_mut.data().set_storage_readonly(true); - let result = do_db_remove(&env, key_ptr); + let result = do_db_remove(fe_mut, key_ptr); match result.unwrap_err() { VmError::WriteAccessDenied { .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_addr_validate_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr1 = write_data(&env, b"foo"); - let source_ptr2 = write_data(&env, b"eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw"); + let source_ptr1 = write_data(&mut fe_mut, b"foo"); + let source_ptr2 = write_data(&mut fe_mut, b"eth1n48g2mjh9ezz7zjtya37wtgg5r5emr0drkwlgw"); - let res = do_addr_validate(&env, source_ptr1).unwrap(); + let res = do_addr_validate(fe_mut.as_mut(), source_ptr1).unwrap(); assert_eq!(res, 0); - let res = do_addr_validate(&env, source_ptr2).unwrap(); + let res = do_addr_validate(fe_mut.as_mut(), source_ptr2).unwrap(); assert_eq!(res, 0); } #[test] fn do_addr_validate_reports_invalid_input_back_to_contract() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr1 = write_data(&env, b"fo\x80o"); // invalid UTF-8 (fo�o) - let source_ptr2 = write_data(&env, b""); // empty - let source_ptr3 = write_data(&env, b"addressexceedingaddressspacesuperlongreallylongiamensuringthatitislongerthaneverything"); // too long - let source_ptr4 = write_data(&env, b"fooBar"); // Not normalized. The definition of normalized is chain-dependent but the MockApi requires lower case. + let source_ptr1 = write_data(&mut fe_mut, b"fo\x80o"); // invalid UTF-8 (fo�o) + let source_ptr2 = write_data(&mut fe_mut, b""); // empty + let source_ptr3 = write_data(&mut fe_mut, b"addressexceedingaddressspacesuperlongreallylongiamensuringthatitislongerthaneverything"); // too long + let source_ptr4 = write_data(&mut fe_mut, b"fooBar"); // Not normalized. The definition of normalized is chain-dependent but the MockApi requires lower case. - let res = do_addr_validate(&env, source_ptr1).unwrap(); + let res = do_addr_validate(fe_mut.as_mut(), source_ptr1).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); assert_eq!(err, "Input is not valid UTF-8"); - let res = do_addr_validate(&env, source_ptr2).unwrap(); + let res = do_addr_validate(fe_mut.as_mut(), source_ptr2).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); assert_eq!(err, "Input is empty"); - let res = do_addr_validate(&env, source_ptr3).unwrap(); + let res = do_addr_validate(fe_mut.as_mut(), source_ptr3).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); - assert_eq!(err, "Invalid input: human address too long"); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); + assert_eq!( + err, + "Invalid input: human address too long for this mock implementation (must be <= 64)." + ); - let res = do_addr_validate(&env, source_ptr4).unwrap(); + let res = do_addr_validate(fe_mut.as_mut(), source_ptr4).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); assert_eq!(err, "Address is not normalized"); } #[test] fn do_addr_validate_fails_for_broken_backend() { let api = MockApi::new_failing("Temporarily unavailable"); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, b"foo"); + let source_ptr = write_data(&mut fe_mut, b"foo"); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_validate(&env, source_ptr); + let result = do_addr_validate(fe_mut, source_ptr); match result.unwrap_err() { VmError::BackendErr { source: BackendError::Unknown { msg, .. }, .. } => assert_eq!(msg, "Temporarily unavailable"), - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_addr_validate_fails_for_large_inputs() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, &[61; 333]); + let source_ptr = write_data(&mut fe_mut, &[61; 333]); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_validate(&env, source_ptr); + let result = do_addr_validate(fe_mut, source_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: @@ -989,87 +1208,94 @@ mod tests { assert_eq!(length, 333); assert_eq!(max_length, 256); } - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_addr_canonicalize_works() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let api = MockApi::default(); - let source_ptr = write_data(&env, b"foo"); - let dest_ptr = create_empty(&mut instance, api.canonical_length() as u32); + let source_ptr = write_data(&mut fe_mut, b"foo"); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, api.canonical_length() as u32); - leave_default_data(&env); + leave_default_data(&mut fe_mut); let api = MockApi::default(); - let res = do_addr_canonicalize(&env, source_ptr, dest_ptr).unwrap(); + let res = do_addr_canonicalize(fe_mut.as_mut(), source_ptr, dest_ptr).unwrap(); assert_eq!(res, 0); - let data = force_read(&env, dest_ptr); + let data = force_read(&mut fe_mut, dest_ptr); assert_eq!(data.len(), api.canonical_length()); } #[test] fn do_addr_canonicalize_reports_invalid_input_back_to_contract() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr1 = write_data(&env, b"fo\x80o"); // invalid UTF-8 (fo�o) - let source_ptr2 = write_data(&env, b""); // empty - let source_ptr3 = write_data(&env, b"addressexceedingaddressspacesuperlongreallylongiamensuringthatitislongerthaneverything"); // too long - let dest_ptr = create_empty(&mut instance, 70); + let source_ptr1 = write_data(&mut fe_mut, b"fo\x80o"); // invalid UTF-8 (fo�o) + let source_ptr2 = write_data(&mut fe_mut, b""); // empty + let source_ptr3 = write_data(&mut fe_mut, b"addressexceedingaddressspacesuperlongreallylongiamensuringthatitislongerthaneverything"); // too long + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 70); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let res = do_addr_canonicalize(&env, source_ptr1, dest_ptr).unwrap(); + let res = do_addr_canonicalize(fe_mut.as_mut(), source_ptr1, dest_ptr).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); assert_eq!(err, "Input is not valid UTF-8"); - let res = do_addr_canonicalize(&env, source_ptr2, dest_ptr).unwrap(); + let res = do_addr_canonicalize(fe_mut.as_mut(), source_ptr2, dest_ptr).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); assert_eq!(err, "Input is empty"); - let res = do_addr_canonicalize(&env, source_ptr3, dest_ptr).unwrap(); + let res = do_addr_canonicalize(fe_mut.as_mut(), source_ptr3, dest_ptr).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); - assert_eq!(err, "Invalid input: human address too long"); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); + assert_eq!( + err, + "Invalid input: human address too long for this mock implementation (must be <= 64)." + ); } #[test] fn do_addr_canonicalize_fails_for_broken_backend() { let api = MockApi::new_failing("Temporarily unavailable"); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, b"foo"); - let dest_ptr = create_empty(&mut instance, 7); + let source_ptr = write_data(&mut fe_mut, b"foo"); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 7); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_canonicalize(&env, source_ptr, dest_ptr); + let result = do_addr_canonicalize(fe_mut.as_mut(), source_ptr, dest_ptr); match result.unwrap_err() { VmError::BackendErr { source: BackendError::Unknown { msg, .. }, .. } => assert_eq!(msg, "Temporarily unavailable"), - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_addr_canonicalize_fails_for_large_inputs() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, &[61; 333]); - let dest_ptr = create_empty(&mut instance, 8); + let source_ptr = write_data(&mut fe_mut, &[61; 333]); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 8); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_canonicalize(&env, source_ptr, dest_ptr); + let result = do_addr_canonicalize(fe_mut.as_mut(), source_ptr, dest_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: @@ -1081,21 +1307,22 @@ mod tests { assert_eq!(length, 333); assert_eq!(max_length, 256); } - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_addr_canonicalize_fails_for_small_destination_region() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, b"foo"); - let dest_ptr = create_empty(&mut instance, 7); + let source_ptr = write_data(&mut fe_mut, b"foo"); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 7); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_canonicalize(&env, source_ptr, dest_ptr); + let result = do_addr_canonicalize(fe_mut, source_ptr, dest_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionTooSmall { size, required, .. }, @@ -1104,74 +1331,78 @@ mod tests { assert_eq!(size, 7); assert_eq!(required, api.canonical_length()); } - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_addr_humanize_works() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let api = MockApi::default(); let source_data = vec![0x22; api.canonical_length()]; - let source_ptr = write_data(&env, &source_data); - let dest_ptr = create_empty(&mut instance, 70); + let source_ptr = write_data(&mut fe_mut, &source_data); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 70); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let error_ptr = do_addr_humanize(&env, source_ptr, dest_ptr).unwrap(); + let error_ptr = do_addr_humanize(fe_mut.as_mut(), source_ptr, dest_ptr).unwrap(); assert_eq!(error_ptr, 0); - assert_eq!(force_read(&env, dest_ptr), source_data); + assert_eq!(force_read(&mut fe_mut, dest_ptr), source_data); } #[test] fn do_addr_humanize_reports_invalid_input_back_to_contract() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, b"foo"); // too short - let dest_ptr = create_empty(&mut instance, 70); + let source_ptr = write_data(&mut fe_mut, b"foo"); // too short + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 70); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let res = do_addr_humanize(&env, source_ptr, dest_ptr).unwrap(); + let res = do_addr_humanize(fe_mut.as_mut(), source_ptr, dest_ptr).unwrap(); assert_ne!(res, 0); - let err = String::from_utf8(force_read(&env, res)).unwrap(); + let err = String::from_utf8(force_read(&mut fe_mut, res)).unwrap(); assert_eq!(err, "Invalid input: canonical address length not correct"); } #[test] fn do_addr_humanize_fails_for_broken_backend() { let api = MockApi::new_failing("Temporarily unavailable"); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, b"foo\0\0\0\0\0"); - let dest_ptr = create_empty(&mut instance, 70); + let source_ptr = write_data(&mut fe_mut, b"foo\0\0\0\0\0"); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 70); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_humanize(&env, source_ptr, dest_ptr); + let result = do_addr_humanize(fe_mut, source_ptr, dest_ptr); match result.unwrap_err() { VmError::BackendErr { source: BackendError::Unknown { msg, .. }, .. } => assert_eq!(msg, "Temporarily unavailable"), - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), }; } #[test] fn do_addr_humanize_fails_for_input_too_long() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let source_ptr = write_data(&env, &[61; 65]); - let dest_ptr = create_empty(&mut instance, 70); + let source_ptr = write_data(&mut fe_mut, &[61; 65]); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 70); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_humanize(&env, source_ptr, dest_ptr); + let result = do_addr_humanize(fe_mut, source_ptr, dest_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: @@ -1183,23 +1414,24 @@ mod tests { assert_eq!(length, 65); assert_eq!(max_length, 64); } - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_addr_humanize_fails_for_destination_region_too_small() { let api = MockApi::default(); - let (env, mut instance) = make_instance(api); + let (fe, mut store, mut instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let api = MockApi::default(); let source_data = vec![0x22; api.canonical_length()]; - let source_ptr = write_data(&env, &source_data); - let dest_ptr = create_empty(&mut instance, 2); + let source_ptr = write_data(&mut fe_mut, &source_data); + let dest_ptr = create_empty(&mut instance, &mut fe_mut, 2); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let result = do_addr_humanize(&env, source_ptr, dest_ptr); + let result = do_addr_humanize(fe_mut, source_ptr, dest_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionTooSmall { size, required, .. }, @@ -1208,24 +1440,25 @@ mod tests { assert_eq!(size, 2); assert_eq!(required, api.canonical_length()); } - err => panic!("Incorrect error returned: {:?}", err), + err => panic!("Incorrect error returned: {err:?}"), } } #[test] fn do_secp256k1_verify_works() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 0 ); } @@ -1233,19 +1466,20 @@ mod tests { #[test] fn do_secp256k1_verify_wrong_hash_verify_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let mut hash = hex::decode(ECDSA_HASH_HEX).unwrap(); // alter hash hash[0] ^= 0x01; - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 1 ); } @@ -1253,43 +1487,45 @@ mod tests { #[test] fn do_secp256k1_verify_larger_hash_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let mut hash = hex::decode(ECDSA_HASH_HEX).unwrap(); // extend / break hash hash.push(0x00); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); - let result = do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr); + let result = do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, MESSAGE_HASH_MAX_LEN + 1), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_secp256k1_verify_shorter_hash_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let mut hash = hex::decode(ECDSA_HASH_HEX).unwrap(); // reduce / break hash hash.pop(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 3 // mapped InvalidHashFormat ); } @@ -1297,19 +1533,20 @@ mod tests { #[test] fn do_secp256k1_verify_wrong_sig_verify_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let mut sig = hex::decode(ECDSA_SIG_HEX).unwrap(); // alter sig sig[0] ^= 0x01; - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 1 ); } @@ -1317,43 +1554,45 @@ mod tests { #[test] fn do_secp256k1_verify_larger_sig_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let mut sig = hex::decode(ECDSA_SIG_HEX).unwrap(); // extend / break sig sig.push(0x00); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); - let result = do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr); + let result = do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, ECDSA_SIGNATURE_LEN + 1), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_secp256k1_verify_shorter_sig_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let mut sig = hex::decode(ECDSA_SIG_HEX).unwrap(); // reduce / break sig sig.pop(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 4 // mapped InvalidSignatureFormat ) } @@ -1361,19 +1600,20 @@ mod tests { #[test] fn do_secp256k1_verify_wrong_pubkey_format_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); // alter pubkey format pubkey[0] ^= 0x01; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 5 // mapped InvalidPubkeyFormat ) } @@ -1381,19 +1621,20 @@ mod tests { #[test] fn do_secp256k1_verify_wrong_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); // alter pubkey pubkey[1] ^= 0x01; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 10 // mapped GenericErr ) } @@ -1401,43 +1642,45 @@ mod tests { #[test] fn do_secp256k1_verify_larger_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); // extend / break pubkey pubkey.push(0x00); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); - let result = do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr); + let result = do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, ECDSA_PUBKEY_MAX_LEN + 1), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_secp256k1_verify_shorter_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(ECDSA_PUBKEY_HEX).unwrap(); // reduce / break pubkey pubkey.pop(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 5 // mapped InvalidPubkeyFormat ) } @@ -1445,17 +1688,18 @@ mod tests { #[test] fn do_secp256k1_verify_empty_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = hex::decode(ECDSA_HASH_HEX).unwrap(); - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = hex::decode(ECDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = vec![]; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 5 // mapped InvalidPubkeyFormat ) } @@ -1463,17 +1707,18 @@ mod tests { #[test] fn do_secp256k1_verify_wrong_data_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let hash = vec![0x22; MESSAGE_HASH_MAX_LEN]; - let hash_ptr = write_data(&env, &hash); + let hash_ptr = write_data(&mut fe_mut, &hash); let sig = vec![0x22; ECDSA_SIGNATURE_LEN]; - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = vec![0x04; ECDSA_PUBKEY_MAX_LEN]; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_secp256k1_verify(&env, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_secp256k1_verify(fe_mut, hash_ptr, sig_ptr, pubkey_ptr).unwrap(), 10 // mapped GenericErr ) } @@ -1481,7 +1726,8 @@ mod tests { #[test] fn do_secp256k1_recover_pubkey_works() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); // https://gist.github.com/webmaster128/130b628d83621a33579751846699ed15 let hash = hex!("5ae8317d34d1e595e3fa7247db80c0af4320cce1116de187f8f7e2e099c0d8d0"); @@ -1489,29 +1735,32 @@ mod tests { let recovery_param = 1; let expected = hex!("044a071e8a6e10aada2b8cf39fa3b5fb3400b04e99ea8ae64ceea1a977dbeaf5d5f8c8fbd10b71ab14cd561f7df8eb6da50f8a8d81ba564342244d26d1d4211595"); - let hash_ptr = write_data(&env, &hash); - let sig_ptr = write_data(&env, &sig); - let result = do_secp256k1_recover_pubkey(&env, hash_ptr, sig_ptr, recovery_param).unwrap(); + let hash_ptr = write_data(&mut fe_mut, &hash); + let sig_ptr = write_data(&mut fe_mut, &sig); + let result = + do_secp256k1_recover_pubkey(fe_mut.as_mut(), hash_ptr, sig_ptr, recovery_param) + .unwrap(); let error = result >> 32; let pubkey_ptr: u32 = (result & 0xFFFFFFFF).try_into().unwrap(); assert_eq!(error, 0); - assert_eq!(force_read(&env, pubkey_ptr), expected); + assert_eq!(force_read(&mut fe_mut, pubkey_ptr), expected); } #[test] fn do_ed25519_verify_works() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 0 ); } @@ -1519,19 +1768,20 @@ mod tests { #[test] fn do_ed25519_verify_wrong_msg_verify_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let mut msg = hex::decode(EDDSA_MSG_HEX).unwrap(); // alter msg msg.push(0x01); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 1 ); } @@ -1539,43 +1789,45 @@ mod tests { #[test] fn do_ed25519_verify_larger_msg_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let mut msg = hex::decode(EDDSA_MSG_HEX).unwrap(); // extend / break msg msg.extend_from_slice(&[0x00; MAX_LENGTH_ED25519_MESSAGE + 1]); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); - let result = do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr); + let result = do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, msg.len()), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_ed25519_verify_wrong_sig_verify_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let mut sig = hex::decode(EDDSA_SIG_HEX).unwrap(); // alter sig sig[0] ^= 0x01; - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 1 ); } @@ -1583,43 +1835,45 @@ mod tests { #[test] fn do_ed25519_verify_larger_sig_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let mut sig = hex::decode(EDDSA_SIG_HEX).unwrap(); // extend / break sig sig.push(0x00); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); - let result = do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr); + let result = do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, MAX_LENGTH_ED25519_SIGNATURE + 1), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_ed25519_verify_shorter_sig_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let mut sig = hex::decode(EDDSA_SIG_HEX).unwrap(); // reduce / break sig sig.pop(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 4 // mapped InvalidSignatureFormat ) } @@ -1627,19 +1881,20 @@ mod tests { #[test] fn do_ed25519_verify_wrong_pubkey_verify_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); // alter pubkey pubkey[1] ^= 0x01; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 1 ); } @@ -1647,43 +1902,45 @@ mod tests { #[test] fn do_ed25519_verify_larger_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); // extend / break pubkey pubkey.push(0x00); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); - let result = do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr); + let result = do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::RegionLengthTooBig { length, .. }, .. } => assert_eq!(length, EDDSA_PUBKEY_LEN + 1), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } #[test] fn do_ed25519_verify_shorter_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let mut pubkey = hex::decode(EDDSA_PUBKEY_HEX).unwrap(); // reduce / break pubkey pubkey.pop(); - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 5 // mapped InvalidPubkeyFormat ) } @@ -1691,17 +1948,18 @@ mod tests { #[test] fn do_ed25519_verify_empty_pubkey_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = hex::decode(EDDSA_MSG_HEX).unwrap(); - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = hex::decode(EDDSA_SIG_HEX).unwrap(); - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = vec![]; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 5 // mapped InvalidPubkeyFormat ) } @@ -1709,17 +1967,18 @@ mod tests { #[test] fn do_ed25519_verify_wrong_data_fails() { let api = MockApi::default(); - let (env, mut _instance) = make_instance(api); + let (fe, mut store, mut _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let msg = vec![0x22; MESSAGE_HASH_MAX_LEN]; - let msg_ptr = write_data(&env, &msg); + let msg_ptr = write_data(&mut fe_mut, &msg); let sig = vec![0x22; MAX_LENGTH_ED25519_SIGNATURE]; - let sig_ptr = write_data(&env, &sig); + let sig_ptr = write_data(&mut fe_mut, &sig); let pubkey = vec![0x04; EDDSA_PUBKEY_LEN]; - let pubkey_ptr = write_data(&env, &pubkey); + let pubkey_ptr = write_data(&mut fe_mut, &pubkey); assert_eq!( - do_ed25519_verify(&env, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), + do_ed25519_verify(fe_mut, msg_ptr, sig_ptr, pubkey_ptr).unwrap(), 1 // verification failure ) } @@ -1727,18 +1986,19 @@ mod tests { #[test] fn do_query_chain_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let request: QueryRequest = QueryRequest::Bank(BankQuery::AllBalances { address: INIT_ADDR.to_string(), }); let request_data = cosmwasm_std::to_vec(&request).unwrap(); - let request_ptr = write_data(&env, &request_data); + let request_ptr = write_data(&mut fe_mut, &request_data); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let response_ptr = do_query_chain(&env, request_ptr).unwrap(); - let response = force_read(&env, response_ptr); + let response_ptr = do_query_chain(fe_mut.as_mut(), request_ptr).unwrap(); + let response = force_read(&mut fe_mut, response_ptr); let query_result: cosmwasm_std::QuerierResult = cosmwasm_std::from_slice(&response).unwrap(); @@ -1751,15 +2011,16 @@ mod tests { #[test] fn do_query_chain_fails_for_broken_request() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let request = b"Not valid JSON for sure"; - let request_ptr = write_data(&env, request); + let request_ptr = write_data(&mut fe_mut, request); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let response_ptr = do_query_chain(&env, request_ptr).unwrap(); - let response = force_read(&env, response_ptr); + let response_ptr = do_query_chain(fe_mut.as_mut(), request_ptr).unwrap(); + let response = force_read(&mut fe_mut, response_ptr); let query_result: cosmwasm_std::QuerierResult = cosmwasm_std::from_slice(&response).unwrap(); @@ -1768,26 +2029,27 @@ mod tests { SystemResult::Err(SystemError::InvalidRequest { request: err, .. }) => { assert_eq!(err.as_slice(), request) } - SystemResult::Err(err) => panic!("Unexpected error: {:?}", err), + SystemResult::Err(err) => panic!("Unexpected error: {err:?}"), } } #[test] fn do_query_chain_fails_for_missing_contract() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); let request: QueryRequest = QueryRequest::Wasm(WasmQuery::Smart { contract_addr: String::from("non-existent"), msg: Binary::from(b"{}" as &[u8]), }); let request_data = cosmwasm_std::to_vec(&request).unwrap(); - let request_ptr = write_data(&env, &request_data); + let request_ptr = write_data(&mut fe_mut, &request_data); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let response_ptr = do_query_chain(&env, request_ptr).unwrap(); - let response = force_read(&env, response_ptr); + let response_ptr = do_query_chain(fe_mut.as_mut(), request_ptr).unwrap(); + let response = force_read(&mut fe_mut, response_ptr); let query_result: cosmwasm_std::QuerierResult = cosmwasm_std::from_slice(&response).unwrap(); @@ -1796,7 +2058,7 @@ mod tests { SystemResult::Err(SystemError::NoSuchContract { addr }) => { assert_eq!(addr, "non-existent") } - SystemResult::Err(err) => panic!("Unexpected error: {:?}", err), + SystemResult::Err(err) => panic!("Unexpected error: {err:?}"), } } @@ -1804,24 +2066,28 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_scan_unbound_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); // set up iterator over all space - let id = do_db_scan(&env, 0, 0, Order::Ascending.into()).unwrap(); + let id = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Ascending.into()).unwrap(); assert_eq!(1, id); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY1.to_vec(), VALUE1.to_vec())); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY2.to_vec(), VALUE2.to_vec())); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert!(item.0.unwrap().is_none()); @@ -1831,24 +2097,28 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_scan_unbound_descending_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); // set up iterator over all space - let id = do_db_scan(&env, 0, 0, Order::Descending.into()).unwrap(); + let id = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Descending.into()).unwrap(); assert_eq!(1, id); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY2.to_vec(), VALUE2.to_vec())); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY1.to_vec(), VALUE1.to_vec())); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert!(item.0.unwrap().is_none()); @@ -1858,21 +2128,24 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_scan_bound_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - let start = write_data(&env, b"anna"); - let end = write_data(&env, b"bert"); + let start = write_data(&mut fe_mut, b"anna"); + let end = write_data(&mut fe_mut, b"bert"); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let id = do_db_scan(&env, start, end, Order::Ascending.into()).unwrap(); + let id = do_db_scan(fe_mut.as_mut(), start, end, Order::Ascending.into()).unwrap(); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY1.to_vec(), VALUE1.to_vec())); - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id))) .unwrap(); assert!(item.0.unwrap().is_none()); @@ -1882,41 +2155,47 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_scan_multiple_iterators() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); // unbounded, ascending and descending - let id1 = do_db_scan(&env, 0, 0, Order::Ascending.into()).unwrap(); - let id2 = do_db_scan(&env, 0, 0, Order::Descending.into()).unwrap(); + let id1 = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Ascending.into()).unwrap(); + let id2 = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Descending.into()).unwrap(); assert_eq!(id1, 1); assert_eq!(id2, 2); // first item, first iterator - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id1))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY1.to_vec(), VALUE1.to_vec())); // second item, first iterator - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id1))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY2.to_vec(), VALUE2.to_vec())); // first item, second iterator - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id2))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY2.to_vec(), VALUE2.to_vec())); // end, first iterator - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id1))) .unwrap(); assert!(item.0.unwrap().is_none()); // second item, second iterator - let item = env + let item = fe_mut + .data() .with_storage_from_context::<_, _>(|store| Ok(store.next(id2))) .unwrap(); assert_eq!(item.0.unwrap().unwrap(), (KEY1.to_vec(), VALUE1.to_vec())); @@ -1926,17 +2205,18 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_scan_errors_for_invalid_order_value() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); - leave_default_data(&env); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + leave_default_data(&mut fe_mut); // set up iterator over all space - let result = do_db_scan(&env, 0, 0, 42); + let result = do_db_scan(fe_mut, 0, 0, 42); match result.unwrap_err() { VmError::CommunicationErr { source: CommunicationError::InvalidOrder { .. }, .. } => {} - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } @@ -1944,29 +2224,30 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_next_works() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - leave_default_data(&env); + leave_default_data(&mut fe_mut); - let id = do_db_scan(&env, 0, 0, Order::Ascending.into()).unwrap(); + let id = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Ascending.into()).unwrap(); // Entry 1 - let kv_region_ptr = do_db_next(&env, id).unwrap(); + let kv_region_ptr = do_db_next(fe_mut.as_mut(), id).unwrap(); assert_eq!( - force_read(&env, kv_region_ptr), + force_read(&mut fe_mut, kv_region_ptr), [KEY1, b"\0\0\0\x03", VALUE1, b"\0\0\0\x06"].concat() ); // Entry 2 - let kv_region_ptr = do_db_next(&env, id).unwrap(); + let kv_region_ptr = do_db_next(fe_mut.as_mut(), id).unwrap(); assert_eq!( - force_read(&env, kv_region_ptr), + force_read(&mut fe_mut, kv_region_ptr), [KEY2, b"\0\0\0\x04", VALUE2, b"\0\0\0\x05"].concat() ); // End - let kv_region_ptr = do_db_next(&env, id).unwrap(); - assert_eq!(force_read(&env, kv_region_ptr), b"\0\0\0\0\0\0\0\0"); + let kv_region_ptr = do_db_next(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, kv_region_ptr), b"\0\0\0\0\0\0\0\0"); // API makes no guarantees for value_ptr in this case } @@ -1974,18 +2255,91 @@ mod tests { #[cfg(feature = "iterator")] fn do_db_next_fails_for_non_existent_id() { let api = MockApi::default(); - let (env, _instance) = make_instance(api); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); - leave_default_data(&env); + leave_default_data(&mut fe_mut); let non_existent_id = 42u32; - let result = do_db_next(&env, non_existent_id); + let result = do_db_next(fe_mut.as_mut(), non_existent_id); match result.unwrap_err() { VmError::BackendErr { source: BackendError::IteratorDoesNotExist { id, .. }, .. } => assert_eq!(id, non_existent_id), - e => panic!("Unexpected error: {:?}", e), + e => panic!("Unexpected error: {e:?}"), } } + + #[test] + #[cfg(feature = "iterator")] + fn do_db_next_key_works() { + let api = MockApi::default(); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + + leave_default_data(&mut fe_mut); + + let id = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Ascending.into()).unwrap(); + + // Entry 1 + let key_region_ptr = do_db_next_key(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, key_region_ptr), KEY1); + + // Entry 2 + let key_region_ptr = do_db_next_key(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, key_region_ptr), KEY2); + + // End + let key_region_ptr: u32 = do_db_next_key(fe_mut.as_mut(), id).unwrap(); + assert_eq!(key_region_ptr, 0); + } + + #[test] + #[cfg(feature = "iterator")] + fn do_db_next_value_works() { + let api = MockApi::default(); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + + leave_default_data(&mut fe_mut); + + let id = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Ascending.into()).unwrap(); + + // Entry 1 + let value_region_ptr = do_db_next_value(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, value_region_ptr), VALUE1); + + // Entry 2 + let value_region_ptr = do_db_next_value(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, value_region_ptr), VALUE2); + + // End + let value_region_ptr = do_db_next_value(fe_mut.as_mut(), id).unwrap(); + assert_eq!(value_region_ptr, 0); + } + + #[test] + #[cfg(feature = "iterator")] + fn do_db_next_works_mixed() { + let api = MockApi::default(); + let (fe, mut store, _instance) = make_instance(api); + let mut fe_mut = fe.into_mut(&mut store); + + leave_default_data(&mut fe_mut); + + let id = do_db_scan(fe_mut.as_mut(), 0, 0, Order::Ascending.into()).unwrap(); + + // Key 1 + let key_region_ptr = do_db_next_key(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, key_region_ptr), KEY1); + + // Value 2 + let value_region_ptr = do_db_next_value(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, value_region_ptr), VALUE2); + + // End + let kv_region_ptr = do_db_next(fe_mut.as_mut(), id).unwrap(); + assert_eq!(force_read(&mut fe_mut, kv_region_ptr), b"\0\0\0\0\0\0\0\0"); + } } diff --git a/packages/vm/src/instance.rs b/packages/vm/src/instance.rs index 7656cf02d..a616ee63a 100644 --- a/packages/vm/src/instance.rs +++ b/packages/vm/src/instance.rs @@ -1,8 +1,12 @@ +use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::ptr::NonNull; +use std::rc::Rc; use std::sync::Mutex; -use wasmer::{Exports, Function, ImportObject, Instance as WasmerInstance, Module, Val}; +use wasmer::{ + Exports, Function, FunctionEnv, Imports, Instance as WasmerInstance, Module, Store, Value, +}; use crate::backend::{Backend, BackendApi, Querier, Storage}; use crate::capabilities::required_capabilities_from_module; @@ -15,10 +19,12 @@ use crate::imports::{ do_secp256k1_recover_pubkey, do_secp256k1_verify, do_sha1_calculate, }; #[cfg(feature = "iterator")] -use crate::imports::{do_db_next, do_db_scan}; +use crate::imports::{do_db_next, do_db_next_key, do_db_next_value, do_db_scan}; use crate::memory::{read_region, write_region}; use crate::size::Size; -use crate::wasm_backend::compile; +use crate::wasm_backend::{compile, make_compiling_engine}; + +pub use crate::environment::DebugInfo; // Re-exported as public via to be usable for set_debug_handler #[derive(Copy, Clone, Debug)] pub struct GasReport { @@ -47,7 +53,8 @@ pub struct Instance { /// /// This instance should only be accessed via the Environment, which provides safe access. _inner: Box, - env: Environment, + fe: FunctionEnv>, + store: Store, } impl Instance @@ -64,8 +71,11 @@ where options: InstanceOptions, memory_limit: Option, ) -> VmResult { - let module = compile(code, memory_limit, &[])?; + let engine = make_compiling_engine(memory_limit); + let module = compile(&engine, code)?; + let store = Store::new(engine); Instance::from_module( + store, &module, backend, options.gas_limit, @@ -75,7 +85,9 @@ where ) } + #[allow(clippy::too_many_arguments)] pub(crate) fn from_module( + mut store: Store, module: &Module, backend: Backend, gas_limit: u64, @@ -83,27 +95,35 @@ where extra_imports: Option>, instantiation_lock: Option<&Mutex<()>>, ) -> VmResult { - let store = module.store(); - - let env = Environment::new(backend.api, gas_limit, print_debug); + let fe = FunctionEnv::new(&mut store, { + let e = Environment::new(backend.api, gas_limit); + if print_debug { + e.set_debug_handler(Some(Rc::new(RefCell::new( + |msg: &str, _info: DebugInfo<'_>| { + eprintln!("{msg}"); + }, + )))) + } + e + }); - let mut import_obj = ImportObject::new(); + let mut import_obj = Imports::new(); let mut env_imports = Exports::new(); - // Reads the database entry at the given key into the the value. + // Reads the database entry at the given key into the value. // Returns 0 if key does not exist and pointer to result region otherwise. // Ownership of the key pointer is not transferred to the host. // Ownership of the value pointer is transferred to the contract. env_imports.insert( "db_read", - Function::new_native_with_env(store, env.clone(), do_db_read), + Function::new_typed_with_env(&mut store, &fe, do_db_read), ); // Writes the given value into the database entry at the given key. // Ownership of both input and output pointer is not transferred to the host. env_imports.insert( "db_write", - Function::new_native_with_env(store, env.clone(), do_db_write), + Function::new_typed_with_env(&mut store, &fe, do_db_write), ); // Removes the value at the given key. Different than writing &[] as future @@ -112,7 +132,7 @@ where // Ownership of both key pointer is not transferred to the host. env_imports.insert( "db_remove", - Function::new_native_with_env(store, env.clone(), do_db_remove), + Function::new_typed_with_env(&mut store, &fe, do_db_remove), ); // Reads human address from source_ptr and checks if it is valid. @@ -120,7 +140,7 @@ where // Ownership of the input pointer is not transferred to the host. env_imports.insert( "addr_validate", - Function::new_native_with_env(store, env.clone(), do_addr_validate), + Function::new_typed_with_env(&mut store, &fe, do_addr_validate), ); // Reads human address from source_ptr and writes canonicalized representation to destination_ptr. @@ -129,7 +149,7 @@ where // Ownership of both input and output pointer is not transferred to the host. env_imports.insert( "addr_canonicalize", - Function::new_native_with_env(store, env.clone(), do_addr_canonicalize), + Function::new_typed_with_env(&mut store, &fe, do_addr_canonicalize), ); // Reads canonical address from source_ptr and writes humanized representation to destination_ptr. @@ -138,7 +158,7 @@ where // Ownership of both input and output pointer is not transferred to the host. env_imports.insert( "addr_humanize", - Function::new_native_with_env(store, env.clone(), do_addr_humanize), + Function::new_typed_with_env(&mut store, &fe, do_addr_humanize), ); // Verifies message hashes against a signature with a public key, using the secp256k1 ECDSA parametrization. @@ -146,12 +166,12 @@ where // Ownership of input pointers is not transferred to the host. env_imports.insert( "secp256k1_verify", - Function::new_native_with_env(store, env.clone(), do_secp256k1_verify), + Function::new_typed_with_env(&mut store, &fe, do_secp256k1_verify), ); env_imports.insert( "secp256k1_recover_pubkey", - Function::new_native_with_env(store, env.clone(), do_secp256k1_recover_pubkey), + Function::new_typed_with_env(&mut store, &fe, do_secp256k1_recover_pubkey), ); // Verifies a message against a signature with a public key, using the ed25519 EdDSA scheme. @@ -159,7 +179,7 @@ where // Ownership of input pointers is not transferred to the host. env_imports.insert( "ed25519_verify", - Function::new_native_with_env(store, env.clone(), do_ed25519_verify), + Function::new_typed_with_env(&mut store, &fe, do_ed25519_verify), ); // Verifies a batch of messages against a batch of signatures with a batch of public keys, @@ -169,7 +189,7 @@ where // Ownership of input pointers is not transferred to the host. env_imports.insert( "ed25519_batch_verify", - Function::new_native_with_env(store, env.clone(), do_ed25519_batch_verify), + Function::new_typed_with_env(&mut store, &fe, do_ed25519_batch_verify), ); // Calculates the inputs using the sha1 @@ -178,7 +198,7 @@ where // Ownership of the hash pointer is transferred to the contract. env_imports.insert( "sha1_calculate", - Function::new_native_with_env(store, env.clone(), do_sha1_calculate), + Function::new_typed_with_env(&mut store, &fe, do_sha1_calculate), ); // Allows the contract to emit debug logs that the host can either process or ignore. @@ -187,7 +207,7 @@ where // Ownership of both input and output pointer is not transferred to the host. env_imports.insert( "debug", - Function::new_native_with_env(store, env.clone(), do_debug), + Function::new_typed_with_env(&mut store, &fe, do_debug), ); // Aborts the contract execution with an error message provided by the contract. @@ -195,12 +215,12 @@ where // Ownership of both input and output pointer is not transferred to the host. env_imports.insert( "abort", - Function::new_native_with_env(store, env.clone(), do_abort), + Function::new_typed_with_env(&mut store, &fe, do_abort), ); env_imports.insert( "query_chain", - Function::new_native_with_env(store, env.clone(), do_query_chain), + Function::new_typed_with_env(&mut store, &fe, do_query_chain), ); // Creates an iterator that will go from start to end. @@ -212,7 +232,7 @@ where #[cfg(feature = "iterator")] env_imports.insert( "db_scan", - Function::new_native_with_env(store, env.clone(), do_db_scan), + Function::new_typed_with_env(&mut store, &fe, do_db_scan), ); // Get next element of iterator with ID `iterator_id`. @@ -223,47 +243,87 @@ where #[cfg(feature = "iterator")] env_imports.insert( "db_next", - Function::new_native_with_env(store, env.clone(), do_db_next), + Function::new_typed_with_env(&mut store, &fe, do_db_next), ); - import_obj.register("env", env_imports); + // Get next key of iterator with ID `iterator_id`. + // Returns 0 if there are no more entries and pointer to result region otherwise. + // Ownership of the result region is transferred to the contract. + #[cfg(feature = "iterator")] + env_imports.insert( + "db_next_key", + Function::new_typed_with_env(&mut store, &fe, do_db_next_key), + ); + + // Get next value of iterator with ID `iterator_id`. + // Returns 0 if there are no more entries and pointer to result region otherwise. + // Ownership of the result region is transferred to the contract. + #[cfg(feature = "iterator")] + env_imports.insert( + "db_next_value", + Function::new_typed_with_env(&mut store, &fe, do_db_next_value), + ); + + import_obj.register_namespace("env", env_imports); if let Some(extra_imports) = extra_imports { for (namespace, exports_obj) in extra_imports { - import_obj.register(namespace, exports_obj); + import_obj.register_namespace(namespace, exports_obj); } } let wasmer_instance = Box::from( { let _lock = instantiation_lock.map(|l| l.lock().unwrap()); - WasmerInstance::new(module, &import_obj) + WasmerInstance::new(&mut store, module, &import_obj) } .map_err(|original| { - VmError::instantiation_err(format!("Error instantiating module: {:?}", original)) + VmError::instantiation_err(format!("Error instantiating module: {original}")) })?, ); + let memory = wasmer_instance + .exports + .get_memory("memory") + .map_err(|original| { + VmError::instantiation_err(format!("Could not get memory 'memory': {original}")) + })? + .clone(); + let instance_ptr = NonNull::from(wasmer_instance.as_ref()); - env.set_wasmer_instance(Some(instance_ptr)); - env.set_gas_left(gas_limit); - env.move_in(backend.storage, backend.querier); - let instance = Instance { + + { + let mut fe_mut = fe.clone().into_mut(&mut store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + env.memory = Some(memory); + env.set_wasmer_instance(Some(instance_ptr)); + env.set_gas_left(&mut store, gas_limit); + env.move_in(backend.storage, backend.querier); + } + + Ok(Instance { _inner: wasmer_instance, - env, - }; - Ok(instance) + fe, + store, + }) } pub fn api(&self) -> &A { - &self.env.api + &self.fe.as_ref(&self.store).api } /// Decomposes this instance into its components. /// External dependencies are returned for reuse, the rest is dropped. + #[must_use = "Calling ::recycle() without reusing the returned backend just drops the instance"] pub fn recycle(self) -> Option> { - if let (Some(storage), Some(querier)) = self.env.move_out() { - let api = self.env.api; + let Instance { + _inner, fe, store, .. + } = self; + + let env = fe.as_ref(&store); + if let (Some(storage), Some(querier)) = env.move_out() { + let api = env.api; Some(Backend { api, storage, @@ -274,6 +334,19 @@ where } } + pub fn set_debug_handler(&mut self, debug_handler: H) + where + H: for<'a, 'b> FnMut(/* msg */ &'a str, DebugInfo<'b>) + 'static, + { + self.fe + .as_ref(&self.store) + .set_debug_handler(Some(Rc::new(RefCell::new(debug_handler)))); + } + + pub fn unset_debug_handler(&mut self) { + self.fe.as_ref(&self.store).set_debug_handler(None); + } + /// Returns the features required by this contract. /// /// This is not needed for production because we can do static analysis @@ -287,21 +360,30 @@ where /// This provides a rough idea of the peak memory consumption. Note that /// Wasm memory always grows in 64 KiB steps (pages) and can never shrink /// (https://github.com/WebAssembly/design/issues/1300#issuecomment-573867836). - pub fn memory_pages(&self) -> usize { - self.env.memory().size().0 as _ + pub fn memory_pages(&mut self) -> usize { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + env.memory(&mut store).size().0 as _ } /// Returns the currently remaining gas. - pub fn get_gas_left(&self) -> u64 { - self.env.get_gas_left() + pub fn get_gas_left(&mut self) -> u64 { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + env.get_gas_left(&mut store) } /// Creates and returns a gas report. /// This is a snapshot and multiple reports can be created during the lifetime of /// an instance. - pub fn create_gas_report(&self) -> GasReport { - let state = self.env.with_gas_state(|gas_state| gas_state.clone()); - let gas_left = self.env.get_gas_left(); + pub fn create_gas_report(&mut self) -> GasReport { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + let state = env.with_gas_state(|gas_state| gas_state.clone()); + let gas_left = env.get_gas_left(&mut store); GasReport { limit: state.gas_limit, remaining: gas_left, @@ -316,19 +398,33 @@ where } } + pub fn is_storage_readonly(&mut self) -> bool { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, _) = fe_mut.data_and_store_mut(); + + env.is_storage_readonly() + } + /// Sets the readonly storage flag on this instance. Since one instance can be used /// for multiple calls in integration tests, this should be set to the desired value /// right before every call. pub fn set_storage_readonly(&mut self, new_value: bool) { - self.env.set_storage_readonly(new_value); + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, _) = fe_mut.data_and_store_mut(); + + env.set_storage_readonly(new_value); } pub fn with_storage VmResult, T>(&mut self, func: F) -> VmResult { - self.env.with_storage_from_context::(func) + self.fe + .as_ref(&self.store) + .with_storage_from_context::(func) } pub fn with_querier VmResult, T>(&mut self, func: F) -> VmResult { - self.env.with_querier_from_context::(func) + self.fe + .as_ref(&self.store) + .with_querier_from_context::(func) } /// Requests memory allocation by the instance and returns a pointer @@ -351,32 +447,45 @@ where } /// Copies all data described by the Region at the given pointer from Wasm to the caller. - pub(crate) fn read_memory(&self, region_ptr: u32, max_length: usize) -> VmResult> { - read_region(&self.env.memory(), region_ptr, max_length) + pub(crate) fn read_memory(&mut self, region_ptr: u32, max_length: usize) -> VmResult> { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + read_region(&env.memory(&mut store), region_ptr, max_length) } /// Copies data to the memory region that was created before using allocate. pub(crate) fn write_memory(&mut self, region_ptr: u32, data: &[u8]) -> VmResult<()> { - write_region(&self.env.memory(), region_ptr, data)?; + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + write_region(&env.memory(&mut store), region_ptr, data)?; Ok(()) } /// Calls a function exported by the instance. /// The function is expected to return no value. Otherwise this calls errors. - pub(crate) fn call_function0(&self, name: &str, args: &[Val]) -> VmResult<()> { - self.env.call_function0(name, args) + pub(crate) fn call_function0(&mut self, name: &str, args: &[Value]) -> VmResult<()> { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + env.call_function0(&mut store, name, args) } /// Calls a function exported by the instance. /// The function is expected to return one value. Otherwise this calls errors. - pub(crate) fn call_function1(&self, name: &str, args: &[Val]) -> VmResult { - self.env.call_function1(name, args) + pub(crate) fn call_function1(&mut self, name: &str, args: &[Value]) -> VmResult { + let mut fe_mut = self.fe.clone().into_mut(&mut self.store); + let (env, mut store) = fe_mut.data_and_store_mut(); + + env.call_function1(&mut store, name, args) } } /// This exists only to be exported through `internals` for use by crates that are /// part of Cosmwasm. pub fn instance_from_module( + store: Store, module: &Module, backend: Backend, gas_limit: u64, @@ -388,13 +497,22 @@ where S: Storage + 'static, // 'static is needed here to allow using this in an Environment that is cloned into closures Q: Querier + 'static, { - Instance::from_module(module, backend, gas_limit, print_debug, extra_imports, None) + Instance::from_module( + store, + module, + backend, + gas_limit, + print_debug, + extra_imports, + None, + ) } #[cfg(test)] mod tests { use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; + use std::time::SystemTime; use super::*; use crate::backend::Storage; @@ -409,11 +527,58 @@ mod tests { coin, coins, from_binary, AllBalanceResponse, BalanceResponse, BankQuery, Empty, QueryRequest, }; + use wasmer::{FunctionEnv, FunctionEnvMut}; const KIB: usize = 1024; const MIB: usize = 1024 * 1024; const DEFAULT_QUERY_GAS_LIMIT: u64 = 300_000; static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); + static CYBERPUNK: &[u8] = include_bytes!("../testdata/cyberpunk.wasm"); + + #[test] + fn from_code_works() { + let backend = mock_backend(&[]); + let (instance_options, memory_limit) = mock_instance_options(); + let _instance = + Instance::from_code(CONTRACT, backend, instance_options, memory_limit).unwrap(); + } + + #[test] + fn set_debug_handler_and_unset_debug_handler_work() { + const LIMIT: u64 = 70_000_000_000_000; + let mut instance = mock_instance_with_gas_limit(CYBERPUNK, LIMIT); + + // init contract + let info = mock_info("creator", &coins(1000, "earth")); + call_instantiate::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{}"#) + .unwrap() + .unwrap(); + + let info = mock_info("caller", &[]); + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{"debug":{}}"#) + .unwrap() + .unwrap(); + + let start = SystemTime::now(); + instance.set_debug_handler(move |msg, info| { + let gas = info.gas_remaining; + let runtime = SystemTime::now().duration_since(start).unwrap().as_micros(); + eprintln!("{msg} (gas: {gas}, runtime: {runtime}µs)"); + }); + + let info = mock_info("caller", &[]); + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{"debug":{}}"#) + .unwrap() + .unwrap(); + + eprintln!("Unsetting debug handler. From here nothing is printed anymore."); + instance.unset_debug_handler(); + + let info = mock_info("caller", &[]); + call_execute::<_, _, _, Empty>(&mut instance, &mock_env(), &info, br#"{"debug":{}}"#) + .unwrap() + .unwrap(); + } #[test] fn required_capabilities_works() { @@ -428,6 +593,9 @@ mod tests { fn required_capabilities_works_for_many_exports() { let wasm = wat::parse_str( r#"(module + (memory 3) + (export "memory" (memory 0)) + (type (func)) (func (type 0) nop) (export "requires_water" (func 0)) @@ -451,37 +619,49 @@ mod tests { #[test] fn extra_imports_get_added() { + let (instance_options, memory_limit) = mock_instance_options(); + let wasm = wat::parse_str( r#"(module (import "foo" "bar" (func $bar)) + (memory 3) + (export "memory" (memory 0)) (func (export "main") (call $bar)) )"#, ) .unwrap(); let backend = mock_backend(&[]); - let (instance_options, memory_limit) = mock_instance_options(); - let module = compile(&wasm, memory_limit, &[]).unwrap(); + let engine = make_compiling_engine(memory_limit); + let module = compile(&engine, &wasm).unwrap(); + let mut store = Store::new(engine); + + let called = Arc::new(AtomicBool::new(false)); - #[derive(wasmer::WasmerEnv, Clone)] + #[derive(Clone)] struct MyEnv { // This can be mutated across threads safely. We initialize it as `false` // and let our imported fn switch it to `true` to confirm it works. called: Arc, } - let my_env = MyEnv { - called: Arc::new(AtomicBool::new(false)), - }; + let fe = FunctionEnv::new( + &mut store, + MyEnv { + called: called.clone(), + }, + ); - let fun = Function::new_native_with_env(module.store(), my_env.clone(), |env: &MyEnv| { - env.called.store(true, Ordering::Relaxed); - }); + let fun = + Function::new_typed_with_env(&mut store, &fe, move |fe_mut: FunctionEnvMut| { + fe_mut.data().called.store(true, Ordering::Relaxed); + }); let mut exports = Exports::new(); exports.insert("bar", fun); let mut extra_imports = HashMap::new(); extra_imports.insert("foo", exports); - let instance = Instance::from_module( + let mut instance = Instance::from_module( + store, &module, backend, instance_options.gas_limit, @@ -491,15 +671,14 @@ mod tests { ) .unwrap(); - let main = instance._inner.exports.get_function("main").unwrap(); - main.call(&[]).unwrap(); + instance.call_function0("main", &[]).unwrap(); - assert!(my_env.called.load(Ordering::Relaxed)); + assert!(called.load(Ordering::Relaxed)); } #[test] fn call_function0_works() { - let instance = mock_instance(CONTRACT, &[]); + let mut instance = mock_instance(CONTRACT, &[]); instance .call_function0("interface_version_8", &[]) @@ -508,7 +687,7 @@ mod tests { #[test] fn call_function1_works() { - let instance = mock_instance(CONTRACT, &[]); + let mut instance = mock_instance(CONTRACT, &[]); // can call function few times let result = instance @@ -600,7 +779,7 @@ mod tests { match init_result.unwrap_err() { VmError::RuntimeErr { msg, .. } => assert!(msg.contains(error_message)), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -629,7 +808,7 @@ mod tests { assert_eq!(length, 6); assert_eq!(max_length, 5); } - err => panic!("unexpected error: {:?}", err), + err => panic!("unexpected error: {err:?}"), }; instance.deallocate(region_ptr).expect("error deallocating"); @@ -652,7 +831,7 @@ mod tests { )"#, ) .unwrap(); - let instance = mock_instance(&wasm, &[]); + let mut instance = mock_instance(&wasm, &[]); assert_eq!(instance.memory_pages(), 0); // min: 3 pages, max: none @@ -670,7 +849,7 @@ mod tests { )"#, ) .unwrap(); - let instance = mock_instance(&wasm, &[]); + let mut instance = mock_instance(&wasm, &[]); assert_eq!(instance.memory_pages(), 3); } @@ -692,7 +871,7 @@ mod tests { #[test] fn get_gas_left_works() { - let instance = mock_instance_with_gas_limit(CONTRACT, 123321); + let mut instance = mock_instance_with_gas_limit(CONTRACT, 123321); let orig_gas = instance.get_gas_left(); assert_eq!(orig_gas, 123321); } @@ -717,7 +896,7 @@ mod tests { let report2 = instance.create_gas_report(); assert_eq!(report2.used_externally, 73); - assert_eq!(report2.used_internally, 5775750198); + assert_eq!(report2.used_internally, 5764950198); assert_eq!(report2.limit, LIMIT); assert_eq!( report2.remaining, @@ -729,16 +908,16 @@ mod tests { fn set_storage_readonly_works() { let mut instance = mock_instance(CONTRACT, &[]); - assert!(instance.env.is_storage_readonly()); + assert!(instance.is_storage_readonly()); instance.set_storage_readonly(false); - assert!(!instance.env.is_storage_readonly()); + assert!(!instance.is_storage_readonly()); instance.set_storage_readonly(false); - assert!(!instance.env.is_storage_readonly()); + assert!(!instance.is_storage_readonly()); instance.set_storage_readonly(true); - assert!(instance.env.is_storage_readonly()); + assert!(instance.is_storage_readonly()); } #[test] @@ -906,7 +1085,7 @@ mod tests { .unwrap(); let init_used = orig_gas - instance.get_gas_left(); - assert_eq!(init_used, 5775750271); + assert_eq!(init_used, 5764950271); } #[test] @@ -929,7 +1108,7 @@ mod tests { .unwrap(); let execute_used = gas_before_execute - instance.get_gas_left(); - assert_eq!(execute_used, 8627053606); + assert_eq!(execute_used, 8548903606); } #[test] @@ -963,6 +1142,6 @@ mod tests { assert_eq!(answer.as_slice(), b"{\"verifier\":\"verifies\"}"); let query_used = gas_before_query - instance.get_gas_left(); - assert_eq!(query_used, 4438350006); + assert_eq!(query_used, 4493700006); } } diff --git a/packages/vm/src/lib.rs b/packages/vm/src/lib.rs index 37713763f..05987bac7 100644 --- a/packages/vm/src/lib.rs +++ b/packages/vm/src/lib.rs @@ -1,4 +1,5 @@ -#![cfg_attr(feature = "backtraces", feature(backtrace))] +#![cfg_attr(feature = "backtraces", feature(error_generic_member_access))] +#![cfg_attr(feature = "backtraces", feature(provide_any))] mod backend; mod cache; @@ -9,11 +10,13 @@ mod compatibility; mod conversion; mod environment; mod errors; +mod filesystem; mod imports; mod instance; mod limited; mod memory; mod modules; +mod parsed_wasm; mod sections; mod serde; mod size; @@ -43,7 +46,7 @@ pub use crate::errors::{ CommunicationError, CommunicationResult, RegionValidationError, RegionValidationResult, VmError, VmResult, }; -pub use crate::instance::{GasReport, Instance, InstanceOptions}; +pub use crate::instance::{DebugInfo, GasReport, Instance, InstanceOptions}; pub use crate::serde::{from_slice, to_vec}; pub use crate::size::Size; @@ -56,5 +59,5 @@ pub mod internals { pub use crate::compatibility::check_wasm; pub use crate::instance::instance_from_module; - pub use crate::wasm_backend::{compile, make_runtime_store}; + pub use crate::wasm_backend::{compile, make_compiling_engine, make_runtime_engine}; } diff --git a/packages/vm/src/limited.rs b/packages/vm/src/limited.rs index 1475dc471..61bac32f8 100644 --- a/packages/vm/src/limited.rs +++ b/packages/vm/src/limited.rs @@ -73,9 +73,9 @@ fn collection_to_string_limited, I: ExactSizeIterator>( let skipped = elements_count - lengths_stack.len(); let remaining = elements_count - skipped; let skipped_text = if remaining == 0 { - format!("... {} elements", skipped) + format!("... {skipped} elements") } else { - format!(", ... {} more", skipped) + format!(", ... {skipped} more") }; if previous_length + skipped_text.len() + closing.len() <= max_length { out.truncate(previous_length); diff --git a/packages/vm/src/memory.rs b/packages/vm/src/memory.rs index d5048d26c..5143de0bd 100644 --- a/packages/vm/src/memory.rs +++ b/packages/vm/src/memory.rs @@ -1,4 +1,6 @@ -use wasmer::{Array, ValueType, WasmPtr}; +use std::mem::MaybeUninit; + +use wasmer::{ValueType, WasmPtr}; use crate::conversion::to_u32; use crate::errors::{ @@ -15,7 +17,7 @@ use crate::errors::{ /// but defined here to allow Wasmer specific implementation. #[repr(C)] #[derive(Default, Clone, Copy, Debug)] -struct Region { +pub struct Region { /// The beginning of the region expressed as bytes from the beginning of the linear memory pub offset: u32, /// The number of bytes available in this region @@ -24,12 +26,18 @@ struct Region { pub length: u32, } -unsafe impl ValueType for Region {} +unsafe impl ValueType for Region { + fn zero_padding_bytes(&self, _bytes: &mut [MaybeUninit]) { + // The size of Region is exactly 3x4=12 bytes with no padding. + // The `size_of::()` test below ensures that. + // So we do not need to zero any bytes here. + } +} /// Expects a (fixed size) Region struct at ptr, which is read. This links to the /// memory region, which is copied in the second step. /// Errors if the length of the region exceeds `max_length`. -pub fn read_region(memory: &wasmer::Memory, ptr: u32, max_length: usize) -> VmResult> { +pub fn read_region(memory: &wasmer::MemoryView, ptr: u32, max_length: usize) -> VmResult> { let region = get_region(memory, ptr)?; if region.length > to_u32(max_length)? { @@ -38,30 +46,18 @@ pub fn read_region(memory: &wasmer::Memory, ptr: u32, max_length: usize) -> VmRe ); } - match WasmPtr::::new(region.offset).deref(memory, 0, region.length) { - Some(cells) => { - // In case you want to do some premature optimization, this shows how to cast a `&'mut [Cell]` to `&mut [u8]`: - // https://github.com/wasmerio/wasmer/blob/0.13.1/lib/wasi/src/syscalls/mod.rs#L79-L81 - let len = region.length as usize; - let mut result = vec![0u8; len]; - for i in 0..len { - result[i] = cells[i].get(); - } - Ok(result) - } - None => Err(CommunicationError::deref_err(region.offset, format!( - "Tried to access memory of region {:?} in wasm memory of size {} bytes. This typically happens when the given Region pointer does not point to a proper Region struct.", - region, - memory.size().bytes().0 - )).into()), - } + let mut result = vec![0u8; region.length as usize]; + memory + .read(region.offset as u64, &mut result) + .map_err(|_err| CommunicationError::region_access_err(region, memory.size().bytes().0))?; + Ok(result) } /// maybe_read_region is like read_region, but gracefully handles null pointer (0) by returning None /// meant to be used where the argument is optional (like scan) #[cfg(feature = "iterator")] pub fn maybe_read_region( - memory: &wasmer::Memory, + memory: &wasmer::MemoryView, ptr: u32, max_length: usize, ) -> VmResult>> { @@ -75,46 +71,32 @@ pub fn maybe_read_region( /// A prepared and sufficiently large memory Region is expected at ptr that points to pre-allocated memory. /// /// Returns number of bytes written on success. -pub fn write_region(memory: &wasmer::Memory, ptr: u32, data: &[u8]) -> VmResult<()> { +pub fn write_region(memory: &wasmer::MemoryView, ptr: u32, data: &[u8]) -> VmResult<()> { let mut region = get_region(memory, ptr)?; let region_capacity = region.capacity as usize; if data.len() > region_capacity { return Err(CommunicationError::region_too_small(region_capacity, data.len()).into()); } - match WasmPtr::::new(region.offset).deref(memory, 0, region.capacity) { - Some(cells) => { - // In case you want to do some premature optimization, this shows how to cast a `&'mut [Cell]` to `&mut [u8]`: - // https://github.com/wasmerio/wasmer/blob/0.13.1/lib/wasi/src/syscalls/mod.rs#L79-L81 - for i in 0..data.len() { - cells[i].set(data[i]) - } - region.length = data.len() as u32; - set_region(memory, ptr, region)?; - Ok(()) - }, - None => Err(CommunicationError::deref_err(region.offset, format!( - "Tried to access memory of region {:?} in wasm memory of size {} bytes. This typically happens when the given Region pointer does not point to a proper Region struct.", - region, - memory.size().bytes().0 - )).into()), - } + + memory + .write(region.offset as u64, data) + .map_err(|_err| CommunicationError::region_access_err(region, memory.size().bytes().0))?; + + region.length = data.len() as u32; + set_region(memory, ptr, region)?; + + Ok(()) } -/// Reads in a Region at ptr in wasm memory and returns a copy of it -fn get_region(memory: &wasmer::Memory, ptr: u32) -> CommunicationResult { - let wptr = WasmPtr::::new(ptr); - match wptr.deref(memory) { - Some(cell) => { - let region = cell.get(); - validate_region(®ion)?; - Ok(region) - } - None => Err(CommunicationError::deref_err( - ptr, - "Could not dereference this pointer to a Region", - )), - } +/// Reads in a Region at offset in Wasm memory and returns a copy of it +fn get_region(memory: &wasmer::MemoryView, offset: u32) -> CommunicationResult { + let wptr = WasmPtr::::new(offset); + let region = wptr.deref(memory).read().map_err(|_err| { + CommunicationError::deref_err(offset, "Could not dereference this pointer to a Region") + })?; + validate_region(®ion)?; + Ok(region) } /// Performs plausibility checks in the given Region. Regions are always created by the @@ -138,26 +120,27 @@ fn validate_region(region: &Region) -> RegionValidationResult<()> { Ok(()) } -/// Overrides a Region at ptr in wasm memory with data -fn set_region(memory: &wasmer::Memory, ptr: u32, data: Region) -> CommunicationResult<()> { - let wptr = WasmPtr::::new(ptr); - - match wptr.deref(memory) { - Some(cell) => { - cell.set(data); - Ok(()) - } - None => Err(CommunicationError::deref_err( - ptr, - "Could not dereference this pointer to a Region", - )), - } +/// Overrides a Region at offset in Wasm memory +fn set_region(memory: &wasmer::MemoryView, offset: u32, data: Region) -> CommunicationResult<()> { + let wptr = WasmPtr::::new(offset); + wptr.deref(memory).write(data).map_err(|_err| { + CommunicationError::deref_err(offset, "Could not dereference this pointer to a Region") + })?; + Ok(()) } #[cfg(test)] mod tests { + use std::mem; + use super::*; + #[test] + fn region_has_known_size() { + // 3x4 bytes with no padding + assert_eq!(mem::size_of::(), 12); + } + #[test] fn validate_region_passes_for_valid_region() { // empty @@ -211,7 +194,7 @@ mod tests { let result = validate_region(®ion); match result.unwrap_err() { RegionValidationError::ZeroOffset { .. } => {} - e => panic!("Got unexpected error: {:?}", e), + e => panic!("Got unexpected error: {e:?}"), } } @@ -230,7 +213,7 @@ mod tests { assert_eq!(length, 501); assert_eq!(capacity, 500); } - e => panic!("Got unexpected error: {:?}", e), + e => panic!("Got unexpected error: {e:?}"), } } @@ -249,7 +232,7 @@ mod tests { assert_eq!(offset, 23); assert_eq!(capacity, u32::MAX); } - e => panic!("Got unexpected error: {:?}", e), + e => panic!("Got unexpected error: {e:?}"), } let region = Region { @@ -265,7 +248,7 @@ mod tests { assert_eq!(offset, u32::MAX); assert_eq!(capacity, 1); } - e => panic!("Got unexpected error: {:?}", e), + e => panic!("Got unexpected error: {e:?}"), } } } diff --git a/packages/vm/src/modules/cached_module.rs b/packages/vm/src/modules/cached_module.rs new file mode 100644 index 000000000..6f9a157a9 --- /dev/null +++ b/packages/vm/src/modules/cached_module.rs @@ -0,0 +1,13 @@ +use wasmer::Module; + +#[derive(Debug, Clone)] +pub struct CachedModule { + pub module: Module, + /// The estimated size of this element in memory. + /// Since the cached modules are just [rkyv](https://rkyv.org/) dumps of the Module + /// instances, we use the file size of the module on disk (not the Wasm!) + /// as an estimate for this. + /// Note: Since CosmWasm 1.4 (Wasmer 4), Store/Engine are not cached anymore. + /// The majority of the Module size is the Artifact. + pub size_estimate: usize, +} diff --git a/packages/vm/src/modules/file_system_cache.rs b/packages/vm/src/modules/file_system_cache.rs index 0488ca763..12c84a0ae 100644 --- a/packages/vm/src/modules/file_system_cache.rs +++ b/packages/vm/src/modules/file_system_cache.rs @@ -1,12 +1,15 @@ use std::fs; +use std::hash::Hash; use std::io; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use thiserror::Error; -use wasmer::{DeserializeError, Module, Store}; +use wasmer::{AsEngineRef, DeserializeError, Module, Target}; use crate::checksum::Checksum; use crate::errors::{VmError, VmResult}; +use crate::filesystem::mkdir_p; use crate::modules::current_wasmer_module_version; /// Bump this version whenever the module system changes in a way @@ -37,116 +40,187 @@ use crate::modules::current_wasmer_module_version; /// the module header version (). In cosmwasm-vm 1.1.0-1.1.1 /// the old value "v3" is still used along with Wasmer 2.3.0 (bug). From cosmwasm 1.1.2 onwards, this is /// fixed by bumping to "v4". -const MODULE_SERIALIZATION_VERSION: &str = "v4"; +/// - **v5**:
+/// A change in memory layout of some types in Rust [std] caused +/// [issues with module deserialization](https://github.com/CosmWasm/wasmvm/issues/426). +/// To work around this, the version was bumped to "v5" here to invalidate these corrupt caches. +/// - **v6**:
+/// Version for cosmwasm_vm 1.3+ which adds a sub-folder with the target identier for the modules. +/// - **v7**:
+/// New version because of Wasmer 2.3.0 -> 4 upgrade. +/// This internally changes how rkyv is used for module serialization, making compatibility unlikely. +const MODULE_SERIALIZATION_VERSION: &str = "v7"; /// Representation of a directory that contains compiled Wasm artifacts. pub struct FileSystemCache { - /// The base path this cache operates in. Within this path, versioned directories are created. - /// A sophisticated version of this cache might be able to read multiple input versions in the future. - base_path: PathBuf, - wasmer_module_version: u32, + modules_path: PathBuf, + /// If true, the cache uses the `*_unchecked` wasmer functions for loading modules from disk. + unchecked_modules: bool, +} + +/// An error type that hides system specific error information +/// to ensure deterministic errors across operating systems. +#[derive(Error, Debug)] +pub enum NewFileSystemCacheError { + #[error("Could not get metadata of cache path")] + CouldntGetMetadata, + #[error("The supplied path is readonly")] + ReadonlyPath, + #[error("The supplied path already exists but is no directory")] + ExistsButNoDirectory, + #[error("Could not create cache path")] + CouldntCreatePath, } impl FileSystemCache { /// Construct a new `FileSystemCache` around the specified directory. /// The contents of the cache are stored in sub-versioned directories. + /// If `unchecked_modules` is set to true, it uses the `*_unchecked` + /// wasmer functions for loading modules from disk (no validity checks). /// /// # Safety /// /// This method is unsafe because there's no way to ensure the artifacts /// stored in this cache haven't been corrupted or tampered with. - pub unsafe fn new(path: impl Into) -> io::Result { - let wasmer_module_version = current_wasmer_module_version(); - - let path: PathBuf = path.into(); - if path.exists() { - let metadata = path.metadata()?; - if metadata.is_dir() { - if !metadata.permissions().readonly() { - Ok(Self { - base_path: path, - wasmer_module_version, - }) - } else { - // This directory is readonly. - Err(io::Error::new( - io::ErrorKind::PermissionDenied, - format!("the supplied path is readonly: {}", path.display()), - )) - } - } else { - // This path points to a file. - Err(io::Error::new( - io::ErrorKind::PermissionDenied, - format!( - "the supplied path already points to a file: {}", - path.display() - ), - )) + pub unsafe fn new( + base_path: impl Into, + unchecked_modules: bool, + ) -> Result { + let base_path: PathBuf = base_path.into(); + if base_path.exists() { + let metadata = base_path + .metadata() + .map_err(|_e| NewFileSystemCacheError::CouldntGetMetadata)?; + if !metadata.is_dir() { + return Err(NewFileSystemCacheError::ExistsButNoDirectory); + } + if metadata.permissions().readonly() { + return Err(NewFileSystemCacheError::ReadonlyPath); } } else { // Create the directory and any parent directories if they don't yet exist. - fs::create_dir_all(&path)?; - Ok(Self { - base_path: path, - wasmer_module_version, - }) + mkdir_p(&base_path).map_err(|_e| NewFileSystemCacheError::CouldntCreatePath)?; } + + Ok(Self { + modules_path: modules_path( + &base_path, + current_wasmer_module_version(), + &Target::default(), + ), + unchecked_modules, + }) + } + + /// If `unchecked` is true, the cache will use the `*_unchecked` wasmer functions for + /// loading modules from disk. + pub fn set_module_unchecked(&mut self, unchecked: bool) { + self.unchecked_modules = unchecked; } /// Loads a serialized module from the file system and returns a module (i.e. artifact + store), /// along with the size of the serialized module. - pub fn load(&self, checksum: &Checksum, store: &Store) -> VmResult> { + pub fn load( + &self, + checksum: &Checksum, + engine: &impl AsEngineRef, + ) -> VmResult> { let filename = checksum.to_hex(); - let file_path = self.latest_modules_path().join(filename); + let file_path = self.modules_path.join(filename); - let result = unsafe { Module::deserialize_from_file(store, &file_path) }; + let result = if self.unchecked_modules { + unsafe { Module::deserialize_from_file_unchecked(engine, &file_path) } + } else { + unsafe { Module::deserialize_from_file(engine, &file_path) } + }; match result { - Ok(module) => Ok(Some(module)), + Ok(module) => { + let module_size = module_size(&file_path)?; + Ok(Some((module, module_size))) + } Err(DeserializeError::Io(err)) => match err.kind() { io::ErrorKind::NotFound => Ok(None), _ => Err(VmError::cache_err(format!( - "Error opening module file: {}", - err + "Error opening module file: {err}" ))), }, Err(err) => Err(VmError::cache_err(format!( - "Error deserializing module: {}", - err + "Error deserializing module: {err}" ))), } } /// Stores a serialized module to the file system. Returns the size of the serialized module. - pub fn store(&mut self, checksum: &Checksum, module: &Module) -> VmResult<()> { - let modules_dir = self.latest_modules_path(); - fs::create_dir_all(&modules_dir) - .map_err(|e| VmError::cache_err(format!("Error creating directory: {}", e)))?; + pub fn store(&mut self, checksum: &Checksum, module: &Module) -> VmResult { + mkdir_p(&self.modules_path) + .map_err(|_e| VmError::cache_err("Error creating modules directory"))?; + let filename = checksum.to_hex(); - let path = modules_dir.join(filename); + let path = self.modules_path.join(filename); module - .serialize_to_file(path) - .map_err(|e| VmError::cache_err(format!("Error writing module to disk: {}", e)))?; - Ok(()) + .serialize_to_file(&path) + .map_err(|e| VmError::cache_err(format!("Error writing module to disk: {e}")))?; + let module_size = module_size(&path)?; + Ok(module_size) } - /// The path to the latest version of the modules. - fn latest_modules_path(&self) -> PathBuf { - let version = format!( - "{}-wasmer{}", - MODULE_SERIALIZATION_VERSION, self.wasmer_module_version - ); - self.base_path.join(version) + /// Removes a serialized module from the file system. + /// + /// Returns true if the file existed and false if the file did not exist. + pub fn remove(&mut self, checksum: &Checksum) -> VmResult { + let filename = checksum.to_hex(); + let file_path = self.modules_path.join(filename); + + if file_path.exists() { + fs::remove_file(file_path) + .map_err(|_e| VmError::cache_err("Error deleting module from disk"))?; + Ok(true) + } else { + Ok(false) + } } } +/// Returns the size of the module stored on disk +fn module_size(module_path: &Path) -> VmResult { + let module_size: usize = module_path + .metadata() + .map_err(|_e| VmError::cache_err("Error getting file metadata"))? // ensure error message is not system specific + .len() + .try_into() + .expect("Could not convert file size to usize"); + Ok(module_size) +} + +/// Creates an identifier for the Wasmer `Target` that is used for +/// cache invalidation. The output is reasonable human friendly to be useable +/// in file path component. +fn target_id(target: &Target) -> String { + // Use a custom Hasher implementation to avoid randomization. + let mut deterministic_hasher = crc32fast::Hasher::new(); + target.hash(&mut deterministic_hasher); + let hash = deterministic_hasher.finalize(); + format!("{}-{:08X}", target.triple(), hash) // print 4 byte hash as 8 hex characters +} + +/// The path to the latest version of the modules. +fn modules_path(base_path: &Path, wasmer_module_version: u32, target: &Target) -> PathBuf { + let version_dir = format!("{MODULE_SERIALIZATION_VERSION}-wasmer{wasmer_module_version}"); + let target_dir = target_id(target); + base_path.join(version_dir).join(target_dir) +} + #[cfg(test)] mod tests { + use std::fs; + use super::*; - use crate::size::Size; - use crate::wasm_backend::{compile, make_runtime_store}; + use crate::{ + size::Size, + wasm_backend::{compile, make_compiling_engine, make_runtime_engine}, + }; use tempfile::TempDir; - use wasmer::{imports, Instance as WasmerInstance}; + use wasmer::{imports, Instance as WasmerInstance, Store}; use wasmer_middlewares::metering::set_remaining_points; const TESTING_MEMORY_LIMIT: Option = Some(Size::mebi(16)); @@ -155,7 +229,7 @@ mod tests { const SOME_WAT: &str = r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add)) "#; @@ -163,35 +237,37 @@ mod tests { #[test] fn file_system_cache_run() { let tmp_dir = TempDir::new().unwrap(); - let mut cache = unsafe { FileSystemCache::new(tmp_dir.path()).unwrap() }; + let mut cache = unsafe { FileSystemCache::new(tmp_dir.path(), false).unwrap() }; // Create module let wasm = wat::parse_str(SOME_WAT).unwrap(); let checksum = Checksum::generate(&wasm); // Module does not exist - let store = make_runtime_store(TESTING_MEMORY_LIMIT); - let cached = cache.load(&checksum, &store).unwrap(); + let runtime_engine = make_runtime_engine(TESTING_MEMORY_LIMIT); + let cached = cache.load(&checksum, &runtime_engine).unwrap(); assert!(cached.is_none()); // Store module - let module = compile(&wasm, None, &[]).unwrap(); + let compiling_engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&compiling_engine, &wasm).unwrap(); cache.store(&checksum, &module).unwrap(); // Load module - let store = make_runtime_store(TESTING_MEMORY_LIMIT); - let cached = cache.load(&checksum, &store).unwrap(); + let cached = cache.load(&checksum, &runtime_engine).unwrap(); assert!(cached.is_some()); // Check the returned module is functional. // This is not really testing the cache API but better safe than sorry. { - let cached_module = cached.unwrap(); + let (cached_module, module_size) = cached.unwrap(); + assert_eq!(module_size, module.serialize().unwrap().len()); let import_object = imports! {}; - let instance = WasmerInstance::new(&cached_module, &import_object).unwrap(); - set_remaining_points(&instance, TESTING_GAS_LIMIT); + let mut store = Store::new(runtime_engine); + let instance = WasmerInstance::new(&mut store, &cached_module, &import_object).unwrap(); + set_remaining_points(&mut store, &instance, TESTING_GAS_LIMIT); let add_one = instance.exports.get_function("add_one").unwrap(); - let result = add_one.call(&[42.into()]).unwrap(); + let result = add_one.call(&mut store, &[42.into()]).unwrap(); assert_eq!(result[0].unwrap_i32(), 43); } } @@ -199,21 +275,100 @@ mod tests { #[test] fn file_system_cache_store_uses_expected_path() { let tmp_dir = TempDir::new().unwrap(); - let mut cache = unsafe { FileSystemCache::new(tmp_dir.path()).unwrap() }; + let mut cache = unsafe { FileSystemCache::new(tmp_dir.path(), false).unwrap() }; // Create module let wasm = wat::parse_str(SOME_WAT).unwrap(); let checksum = Checksum::generate(&wasm); // Store module - let module = compile(&wasm, None, &[]).unwrap(); + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine, &wasm).unwrap(); cache.store(&checksum, &module).unwrap(); - let file_path = format!( - "{}/v4-wasmer1/{}", + let mut globber = glob::glob(&format!( + "{}/v7-wasmer4/**/{}", tmp_dir.path().to_string_lossy(), checksum - ); + )) + .expect("Failed to read glob pattern"); + let file_path = globber.next().unwrap().unwrap(); let _serialized_module = fs::read(file_path).unwrap(); } + + #[test] + fn file_system_cache_remove_works() { + let tmp_dir = TempDir::new().unwrap(); + let mut cache = unsafe { FileSystemCache::new(tmp_dir.path(), false).unwrap() }; + + // Create module + let wasm = wat::parse_str(SOME_WAT).unwrap(); + let checksum = Checksum::generate(&wasm); + + // Store module + let engine1 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine1, &wasm).unwrap(); + cache.store(&checksum, &module).unwrap(); + + // It's there + let engine2 = make_runtime_engine(TESTING_MEMORY_LIMIT); + assert!(cache.load(&checksum, &engine2).unwrap().is_some()); + + // Remove module + let existed = cache.remove(&checksum).unwrap(); + assert!(existed); + + // it's gone now + assert!(cache.load(&checksum, &engine2).unwrap().is_none()); + + // Remove again + let existed = cache.remove(&checksum).unwrap(); + assert!(!existed); + } + + #[test] + fn target_id_works() { + let triple = wasmer::Triple { + architecture: wasmer::Architecture::X86_64, + vendor: target_lexicon::Vendor::Nintendo, + operating_system: target_lexicon::OperatingSystem::Fuchsia, + environment: target_lexicon::Environment::Gnu, + binary_format: target_lexicon::BinaryFormat::Coff, + }; + let target = Target::new(triple.clone(), wasmer::CpuFeature::POPCNT.into()); + let id = target_id(&target); + assert_eq!(id, "x86_64-nintendo-fuchsia-gnu-coff-01E9F9FE"); + // Changing CPU features changes the hash part + let target = Target::new(triple, wasmer::CpuFeature::AVX512DQ.into()); + let id = target_id(&target); + assert_eq!(id, "x86_64-nintendo-fuchsia-gnu-coff-93001945"); + + // Works for durrect target (hashing is deterministic); + let target = Target::default(); + let id1 = target_id(&target); + let id2 = target_id(&target); + assert_eq!(id1, id2); + } + + #[test] + fn modules_path_works() { + let base = PathBuf::from("modules"); + let triple = wasmer::Triple { + architecture: wasmer::Architecture::X86_64, + vendor: target_lexicon::Vendor::Nintendo, + operating_system: target_lexicon::OperatingSystem::Fuchsia, + environment: target_lexicon::Environment::Gnu, + binary_format: target_lexicon::BinaryFormat::Coff, + }; + let target = Target::new(triple, wasmer::CpuFeature::POPCNT.into()); + let p = modules_path(&base, 17, &target); + assert_eq!( + p.as_os_str(), + if cfg!(windows) { + "modules\\v7-wasmer17\\x86_64-nintendo-fuchsia-gnu-coff-01E9F9FE" + } else { + "modules/v7-wasmer17/x86_64-nintendo-fuchsia-gnu-coff-01E9F9FE" + } + ); + } } diff --git a/packages/vm/src/modules/in_memory_cache.rs b/packages/vm/src/modules/in_memory_cache.rs index 9a14ac996..14d8f971a 100644 --- a/packages/vm/src/modules/in_memory_cache.rs +++ b/packages/vm/src/modules/in_memory_cache.rs @@ -3,7 +3,7 @@ use std::collections::hash_map::RandomState; use std::num::NonZeroUsize; use wasmer::Module; -use super::sized_module::SizedModule; +use super::cached_module::CachedModule; use crate::{Checksum, Size, VmError, VmResult}; // Minimum module size. @@ -18,16 +18,16 @@ const MINIMUM_MODULE_SIZE: Size = Size::kibi(250); #[derive(Debug)] struct SizeScale; -impl WeightScale for SizeScale { +impl WeightScale for SizeScale { #[inline] - fn weight(&self, _key: &Checksum, value: &SizedModule) -> usize { - value.size + fn weight(&self, key: &Checksum, value: &CachedModule) -> usize { + std::mem::size_of_val(key) + value.size_estimate } } /// An in-memory module cache pub struct InMemoryCache { - modules: Option>, + modules: Option>, } impl InMemoryCache { @@ -49,20 +49,31 @@ impl InMemoryCache { } } - pub fn store(&mut self, checksum: &Checksum, module: Module, size: usize) -> VmResult<()> { + pub fn store( + &mut self, + checksum: &Checksum, + entry: Module, + module_size: usize, + ) -> VmResult<()> { if let Some(modules) = &mut self.modules { modules - .put_with_weight(*checksum, SizedModule { module, size }) - .map_err(|e| VmError::cache_err(format!("{:?}", e)))?; + .put_with_weight( + *checksum, + CachedModule { + module: entry, + size_estimate: module_size, + }, + ) + .map_err(|e| VmError::cache_err(format!("{e:?}")))?; } Ok(()) } /// Looks up a module in the cache and creates a new module - pub fn load(&mut self, checksum: &Checksum) -> VmResult> { + pub fn load(&mut self, checksum: &Checksum) -> VmResult> { if let Some(modules) = &mut self.modules { match modules.get(checksum) { - Some(module) => Ok(Some(module.clone())), + Some(cached) => Ok(Some(cached.clone())), None => Ok(None), } } else { @@ -93,12 +104,15 @@ impl InMemoryCache { #[cfg(test)] mod tests { use super::*; - use crate::size::Size; - use crate::wasm_backend::compile; + use crate::{ + size::Size, + wasm_backend::{compile, make_compiling_engine}, + }; use std::mem; - use wasmer::{imports, Instance as WasmerInstance}; + use wasmer::{imports, Instance as WasmerInstance, Store}; use wasmer_middlewares::metering::set_remaining_points; + const TESTING_MEMORY_LIMIT: Option = Some(Size::mebi(16)); const TESTING_GAS_LIMIT: u64 = 500_000_000; // Based on `examples/module_size.sh` const TESTING_WASM_SIZE_FACTOR: usize = 18; @@ -108,12 +122,8 @@ mod tests { let key_size = mem::size_of::(); assert_eq!(key_size, 32); - // A Module consists of a Store (3 Arcs) and an Arc to the Engine. - // This is 3 * 64bit of data, but we don't get any guarantee how the Rust structs - // Module and Store are aligned (https://doc.rust-lang.org/reference/type-layout.html#the-default-representation). - // So we get this value by trial and error. It can change over time and across platforms. let value_size = mem::size_of::(); - assert_eq!(value_size, 56); + assert_eq!(value_size, 8); // Just in case we want to go that route let boxed_value_size = mem::size_of::>(); @@ -129,7 +139,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -142,14 +152,16 @@ mod tests { assert!(cache_entry.is_none()); // Compile module - let original = compile(&wasm, None, &[]).unwrap(); + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let original = compile(&engine, &wasm).unwrap(); // Ensure original module can be executed { - let instance = WasmerInstance::new(&original, &imports! {}).unwrap(); - set_remaining_points(&instance, TESTING_GAS_LIMIT); + let mut store = Store::new(engine.clone()); + let instance = WasmerInstance::new(&mut store, &original, &imports! {}).unwrap(); + set_remaining_points(&mut store, &instance, TESTING_GAS_LIMIT); let add_one = instance.exports.get_function("add_one").unwrap(); - let result = add_one.call(&[42.into()]).unwrap(); + let result = add_one.call(&mut store, &[42.into()]).unwrap(); assert_eq!(result[0].unwrap_i32(), 43); } @@ -162,10 +174,11 @@ mod tests { // Ensure cached module can be executed { - let instance = WasmerInstance::new(&cached.module, &imports! {}).unwrap(); - set_remaining_points(&instance, TESTING_GAS_LIMIT); + let mut store = Store::new(engine); + let instance = WasmerInstance::new(&mut store, &cached.module, &imports! {}).unwrap(); + set_remaining_points(&mut store, &instance, TESTING_GAS_LIMIT); let add_one = instance.exports.get_function("add_one").unwrap(); - let result = add_one.call(&[42.into()]).unwrap(); + let result = add_one.call(&mut store, &[42.into()]).unwrap(); assert_eq!(result[0].unwrap_i32(), 43); } } @@ -179,7 +192,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -190,7 +203,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_two") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 2 i32.add) )"#, @@ -201,7 +214,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_three") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 3 i32.add) )"#, @@ -212,21 +225,21 @@ mod tests { assert_eq!(cache.len(), 0); // Add 1 - cache - .store(&checksum1, compile(&wasm1, None, &[]).unwrap(), 900_000) - .unwrap(); + let engine1 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine1, &wasm1).unwrap(); + cache.store(&checksum1, module, 900_000).unwrap(); assert_eq!(cache.len(), 1); // Add 2 - cache - .store(&checksum2, compile(&wasm2, None, &[]).unwrap(), 900_000) - .unwrap(); + let engine2 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine2, &wasm2).unwrap(); + cache.store(&checksum2, module, 900_000).unwrap(); assert_eq!(cache.len(), 2); // Add 3 (pushes out the previous two) - cache - .store(&checksum3, compile(&wasm3, None, &[]).unwrap(), 1_500_000) - .unwrap(); + let engine3 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine3, &wasm3).unwrap(); + cache.store(&checksum3, module, 1_500_000).unwrap(); assert_eq!(cache.len(), 1); } @@ -239,7 +252,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -250,7 +263,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_two") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 2 i32.add) )"#, @@ -261,7 +274,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_three") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 3 i32.add) )"#, @@ -272,21 +285,21 @@ mod tests { assert_eq!(cache.size(), 0); // Add 1 - cache - .store(&checksum1, compile(&wasm1, None, &[]).unwrap(), 900_000) - .unwrap(); - assert_eq!(cache.size(), 900_000); + let engine1 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine1, &wasm1).unwrap(); + cache.store(&checksum1, module, 900_000).unwrap(); + assert_eq!(cache.size(), 900_032); // Add 2 - cache - .store(&checksum2, compile(&wasm2, None, &[]).unwrap(), 800_000) - .unwrap(); - assert_eq!(cache.size(), 1_700_000); + let engine2 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine2, &wasm2).unwrap(); + cache.store(&checksum2, module, 800_000).unwrap(); + assert_eq!(cache.size(), 900_032 + 800_032); // Add 3 (pushes out the previous two) - cache - .store(&checksum3, compile(&wasm3, None, &[]).unwrap(), 1_500_000) - .unwrap(); - assert_eq!(cache.size(), 1_500_000); + let engine3 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine3, &wasm3).unwrap(); + cache.store(&checksum3, module, 1_500_000).unwrap(); + assert_eq!(cache.size(), 1_500_032); } } diff --git a/packages/vm/src/modules/mod.rs b/packages/vm/src/modules/mod.rs index c00ebae12..c871963e8 100644 --- a/packages/vm/src/modules/mod.rs +++ b/packages/vm/src/modules/mod.rs @@ -1,10 +1,11 @@ +mod cached_module; mod file_system_cache; mod in_memory_cache; mod pinned_memory_cache; -mod sized_module; mod versioning; -pub use file_system_cache::FileSystemCache; +pub use cached_module::CachedModule; +pub use file_system_cache::{FileSystemCache, NewFileSystemCacheError}; pub use in_memory_cache::InMemoryCache; pub use pinned_memory_cache::PinnedMemoryCache; pub use versioning::current_wasmer_module_version; diff --git a/packages/vm/src/modules/pinned_memory_cache.rs b/packages/vm/src/modules/pinned_memory_cache.rs index 61ef8cc74..f8fe04869 100644 --- a/packages/vm/src/modules/pinned_memory_cache.rs +++ b/packages/vm/src/modules/pinned_memory_cache.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; use wasmer::Module; -use super::sized_module::SizedModule; +use super::cached_module::CachedModule; use crate::{Checksum, VmResult}; /// An pinned in memory module cache pub struct PinnedMemoryCache { - modules: HashMap, + modules: HashMap, } impl PinnedMemoryCache { @@ -17,8 +17,19 @@ impl PinnedMemoryCache { } } - pub fn store(&mut self, checksum: &Checksum, module: Module, size: usize) -> VmResult<()> { - self.modules.insert(*checksum, SizedModule { module, size }); + pub fn store( + &mut self, + checksum: &Checksum, + element: Module, + module_size: usize, + ) -> VmResult<()> { + self.modules.insert( + *checksum, + CachedModule { + module: element, + size_estimate: module_size, + }, + ); Ok(()) } @@ -30,9 +41,9 @@ impl PinnedMemoryCache { } /// Looks up a module in the cache and creates a new module - pub fn load(&mut self, checksum: &Checksum) -> VmResult> { + pub fn load(&mut self, checksum: &Checksum) -> VmResult> { match self.modules.get(checksum) { - Some(module) => Ok(Some(module.module.clone())), + Some(cached) => Ok(Some(cached.clone())), None => Ok(None), } } @@ -52,17 +63,24 @@ impl PinnedMemoryCache { /// This is based on the values provided with `store`. No actual /// memory size is measured here. pub fn size(&self) -> usize { - self.modules.iter().map(|(_, module)| module.size).sum() + self.modules + .iter() + .map(|(key, module)| std::mem::size_of_val(key) + module.size_estimate) + .sum() } } #[cfg(test)] mod tests { use super::*; - use crate::wasm_backend::compile; - use wasmer::{imports, Instance as WasmerInstance}; + use crate::{ + wasm_backend::{compile, make_compiling_engine}, + Size, + }; + use wasmer::{imports, Instance as WasmerInstance, Store}; use wasmer_middlewares::metering::set_remaining_points; + const TESTING_MEMORY_LIMIT: Option = Some(Size::mebi(16)); const TESTING_GAS_LIMIT: u64 = 500_000_000; #[test] @@ -74,7 +92,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -87,14 +105,16 @@ mod tests { assert!(cache_entry.is_none()); // Compile module - let original = compile(&wasm, None, &[]).unwrap(); + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let original = compile(&engine, &wasm).unwrap(); // Ensure original module can be executed { - let instance = WasmerInstance::new(&original, &imports! {}).unwrap(); - set_remaining_points(&instance, TESTING_GAS_LIMIT); + let mut store = Store::new(engine.clone()); + let instance = WasmerInstance::new(&mut store, &original, &imports! {}).unwrap(); + set_remaining_points(&mut store, &instance, TESTING_GAS_LIMIT); let add_one = instance.exports.get_function("add_one").unwrap(); - let result = add_one.call(&[42.into()]).unwrap(); + let result = add_one.call(&mut store, &[42.into()]).unwrap(); assert_eq!(result[0].unwrap_i32(), 43); } @@ -106,10 +126,11 @@ mod tests { // Ensure cached module can be executed { - let instance = WasmerInstance::new(&cached, &imports! {}).unwrap(); - set_remaining_points(&instance, TESTING_GAS_LIMIT); + let mut store = Store::new(engine); + let instance = WasmerInstance::new(&mut store, &cached.module, &imports! {}).unwrap(); + set_remaining_points(&mut store, &instance, TESTING_GAS_LIMIT); let add_one = instance.exports.get_function("add_one").unwrap(); - let result = add_one.call(&[42.into()]).unwrap(); + let result = add_one.call(&mut store, &[42.into()]).unwrap(); assert_eq!(result[0].unwrap_i32(), 43); } } @@ -123,7 +144,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -134,7 +155,8 @@ mod tests { assert!(!cache.has(&checksum)); // Add - let original = compile(&wasm, None, &[]).unwrap(); + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let original = compile(&engine, &wasm).unwrap(); cache.store(&checksum, original, 0).unwrap(); assert!(cache.has(&checksum)); @@ -154,7 +176,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -165,7 +187,8 @@ mod tests { assert_eq!(cache.len(), 0); // Add - let original = compile(&wasm, None, &[]).unwrap(); + let engine = make_compiling_engine(TESTING_MEMORY_LIMIT); + let original = compile(&engine, &wasm).unwrap(); cache.store(&checksum, original, 0).unwrap(); assert_eq!(cache.len(), 1); @@ -185,7 +208,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_one") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 1 i32.add) )"#, @@ -196,7 +219,7 @@ mod tests { r#"(module (type $t0 (func (param i32) (result i32))) (func $add_one (export "add_two") (type $t0) (param $p0 i32) (result i32) - get_local $p0 + local.get $p0 i32.const 2 i32.add) )"#, @@ -207,18 +230,20 @@ mod tests { assert_eq!(cache.size(), 0); // Add 1 - let original = compile(&wasm1, None, &[]).unwrap(); - cache.store(&checksum1, original, 500).unwrap(); - assert_eq!(cache.size(), 500); + let engine1 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine1, &wasm1).unwrap(); + cache.store(&checksum1, module, 500).unwrap(); + assert_eq!(cache.size(), 532); // Add 2 - let original = compile(&wasm2, None, &[]).unwrap(); - cache.store(&checksum2, original, 300).unwrap(); - assert_eq!(cache.size(), 800); + let engine2 = make_compiling_engine(TESTING_MEMORY_LIMIT); + let module = compile(&engine2, &wasm2).unwrap(); + cache.store(&checksum2, module, 300).unwrap(); + assert_eq!(cache.size(), 532 + 332); // Remove 1 cache.remove(&checksum1).unwrap(); - assert_eq!(cache.size(), 300); + assert_eq!(cache.size(), 332); // Remove 2 cache.remove(&checksum2).unwrap(); diff --git a/packages/vm/src/modules/sized_module.rs b/packages/vm/src/modules/sized_module.rs deleted file mode 100644 index 3ca9da739..000000000 --- a/packages/vm/src/modules/sized_module.rs +++ /dev/null @@ -1,7 +0,0 @@ -use wasmer::Module; - -#[derive(Debug, Clone)] -pub struct SizedModule { - pub module: Module, - pub size: usize, -} diff --git a/packages/vm/src/modules/versioning.rs b/packages/vm/src/modules/versioning.rs index 86ce486f8..1911852b3 100644 --- a/packages/vm/src/modules/versioning.rs +++ b/packages/vm/src/modules/versioning.rs @@ -1,4 +1,4 @@ -use crate::wasm_backend::compile; +use crate::wasm_backend::{compile, make_compiling_engine}; /// This header prefix contains the module type (wasmer-universal) and /// the magic value WASMER\0\0. @@ -12,11 +12,13 @@ const METADATA_HEADER_LEN: usize = 16; // https://github.com/wasmerio/wasmer/blo fn current_wasmer_module_header() -> Vec { // echo "(module)" > my.wat && wat2wasm my.wat && hexdump -C my.wasm const WASM: &[u8] = b"\x00\x61\x73\x6d\x01\x00\x00\x00"; - let module = compile(WASM, None, &[]).unwrap(); + let engine = make_compiling_engine(None); + let module = compile(&engine, WASM).unwrap(); + let mut bytes = module.serialize().unwrap_or_default(); bytes.truncate(ENGINE_TYPE_LEN + METADATA_HEADER_LEN); - bytes + bytes.into() } /// Obtains the module version from Wasmer that is currently used. @@ -49,6 +51,6 @@ mod tests { #[test] fn current_wasmer_module_version_works() { let version = current_wasmer_module_version(); - assert_eq!(version, 1); + assert_eq!(version, 4); } } diff --git a/packages/vm/src/parsed_wasm.rs b/packages/vm/src/parsed_wasm.rs new file mode 100644 index 000000000..6de9fbaed --- /dev/null +++ b/packages/vm/src/parsed_wasm.rs @@ -0,0 +1,70 @@ +use wasmer::wasmparser::{ + Export, Import, MemoryType, Parser, TableType, ValidPayload, Validator, WasmFeatures, +}; + +use crate::VmResult; + +/// A parsed and validated wasm module. +/// It keeps track of the parts that are important for our static analysis and compatibility checks. +#[derive(Debug)] +pub struct ParsedWasm<'a> { + pub version: u32, + pub exports: Vec>, + pub imports: Vec>, + pub tables: Vec, + pub memories: Vec, +} + +impl<'a> ParsedWasm<'a> { + pub fn parse(wasm: &'a [u8]) -> VmResult { + let mut validator = Validator::new_with_features(WasmFeatures { + deterministic_only: true, + component_model: false, + simd: false, + relaxed_simd: false, + threads: false, + multi_memory: false, + memory64: false, + ..Default::default() + }); + + let mut this = Self { + version: 0, + exports: vec![], + imports: vec![], + tables: vec![], + memories: vec![], + }; + + let mut fun_allocations = Default::default(); + for p in Parser::new(0).parse_all(wasm) { + let p = p?; + // validate the payload + if let ValidPayload::Func(fv, body) = validator.payload(&p)? { + // also validate function bodies + let mut fun_validator = fv.into_validator(fun_allocations); + fun_validator.validate(&body)?; + fun_allocations = fun_validator.into_allocations(); + } + + match p { + wasmer::wasmparser::Payload::Version { num, .. } => this.version = num, + wasmer::wasmparser::Payload::ImportSection(i) => { + this.imports = i.into_iter().collect::, _>>()?; + } + wasmer::wasmparser::Payload::TableSection(t) => { + this.tables = t.into_iter().collect::, _>>()?; + } + wasmer::wasmparser::Payload::MemorySection(m) => { + this.memories = m.into_iter().collect::, _>>()?; + } + wasmer::wasmparser::Payload::ExportSection(e) => { + this.exports = e.into_iter().collect::, _>>()?; + } + _ => {} // ignore everything else + } + } + + Ok(this) + } +} diff --git a/packages/vm/src/serde.rs b/packages/vm/src/serde.rs index c884dd1b8..ce6c9e0f8 100644 --- a/packages/vm/src/serde.rs +++ b/packages/vm/src/serde.rs @@ -95,7 +95,7 @@ mod tests { assert_eq!(length, 13); assert_eq!(max_length, 5); } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/packages/vm/src/static_analysis.rs b/packages/vm/src/static_analysis.rs index 9db720db9..7e20fb95f 100644 --- a/packages/vm/src/static_analysis.rs +++ b/packages/vm/src/static_analysis.rs @@ -1,7 +1,8 @@ -use parity_wasm::elements::{deserialize_buffer, Internal, Module}; use std::collections::HashSet; -use crate::errors::{VmError, VmResult}; +use wasmer::wasmparser::ExternalKind; + +use crate::parsed_wasm::ParsedWasm; pub const REQUIRED_IBC_EXPORTS: &[&str] = &[ "ibc_channel_open", @@ -12,48 +13,35 @@ pub const REQUIRED_IBC_EXPORTS: &[&str] = &[ "ibc_packet_timeout", ]; -pub fn deserialize_wasm(wasm_code: &[u8]) -> VmResult { - deserialize_buffer(wasm_code).map_err(|err| { - VmError::static_validation_err(format!( - "Wasm bytecode could not be deserialized. Deserialization error: \"{}\"", - err - )) - }) -} - /// A trait that allows accessing shared functionality of `parity_wasm::elements::Module` /// and `wasmer::Module` in a shared fashion. pub trait ExportInfo { /// Returns all exported function names with the given prefix - fn exported_function_names(&self, prefix: Option<&str>) -> HashSet; + fn exported_function_names(self, prefix: Option<&str>) -> HashSet; } -impl ExportInfo for Module { - fn exported_function_names(&self, prefix: Option<&str>) -> HashSet { - self.export_section() - .map_or(HashSet::default(), |export_section| { - export_section - .entries() - .iter() - .filter_map(|entry| match entry.internal() { - Internal::Function(_) => Some(entry.field()), - _ => None, - }) - .filter(|name| { - if let Some(required_prefix) = prefix { - name.starts_with(required_prefix) - } else { - true - } - }) - .map(|name| name.to_string()) - .collect() +impl ExportInfo for &ParsedWasm<'_> { + fn exported_function_names(self, prefix: Option<&str>) -> HashSet { + self.exports + .iter() + .filter_map(|export| match export.kind { + ExternalKind::Func => Some(export.name), + _ => None, + }) + .filter(|name| { + if let Some(required_prefix) = prefix { + name.starts_with(required_prefix) + } else { + true + } }) + .map(|name| name.to_string()) + .collect() } } -impl ExportInfo for wasmer::Module { - fn exported_function_names(&self, prefix: Option<&str>) -> HashSet { +impl ExportInfo for &wasmer::Module { + fn exported_function_names(self, prefix: Option<&str>) -> HashSet { self.exports() .functions() .filter_map(|function_export| { @@ -75,7 +63,7 @@ impl ExportInfo for wasmer::Module { /// Returns true if and only if all IBC entry points ([`REQUIRED_IBC_EXPORTS`]) /// exist as exported functions. This does not guarantee the entry points /// are functional and for simplicity does not even check their signatures. -pub fn has_ibc_entry_points(module: &impl ExportInfo) -> bool { +pub fn has_ibc_entry_points(module: impl ExportInfo) -> bool { let available_exports = module.exported_function_names(None); REQUIRED_IBC_EXPORTS .iter() @@ -84,49 +72,46 @@ pub fn has_ibc_entry_points(module: &impl ExportInfo) -> bool { #[cfg(test)] mod tests { + use crate::VmError; + use super::*; - use parity_wasm::elements::Internal; - use wasmer::{Cranelift, Store, Universal}; + use wasmer::{Cranelift, Store}; static CONTRACT: &[u8] = include_bytes!("../testdata/hackatom.wasm"); static CORRUPTED: &[u8] = include_bytes!("../testdata/corrupted.wasm"); #[test] - fn deserialize_wasm_works() { - let module = deserialize_wasm(CONTRACT).unwrap(); - assert_eq!(module.version(), 1); + fn deserialize_exports_works() { + let module = ParsedWasm::parse(CONTRACT).unwrap(); + assert_eq!(module.version, 1); let exported_functions = module - .export_section() - .unwrap() - .entries() + .exports .iter() - .filter(|entry| matches!(entry.internal(), Internal::Function(_))); + .filter(|entry| matches!(entry.kind, ExternalKind::Func)); assert_eq!(exported_functions.count(), 8); // 4 required exports plus "execute", "migrate", "query" and "sudo" let exported_memories = module - .export_section() - .unwrap() - .entries() + .exports .iter() - .filter(|entry| matches!(entry.internal(), Internal::Memory(_))); + .filter(|entry| matches!(entry.kind, ExternalKind::Memory)); assert_eq!(exported_memories.count(), 1); } #[test] fn deserialize_wasm_corrupted_data() { - match deserialize_wasm(CORRUPTED).unwrap_err() { + match ParsedWasm::parse(CORRUPTED).unwrap_err() { VmError::StaticValidationErr { msg, .. } => { assert!(msg.starts_with("Wasm bytecode could not be deserialized.")) } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } #[test] fn exported_function_names_works_for_parity_with_no_prefix() { let wasm = wat::parse_str(r#"(module)"#).unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); let exports = module.exported_function_names(None); assert_eq!(exports, HashSet::new()); @@ -142,7 +127,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); let exports = module.exported_function_names(None); assert_eq!( exports, @@ -153,7 +138,7 @@ mod tests { #[test] fn exported_function_names_works_for_parity_with_prefix() { let wasm = wat::parse_str(r#"(module)"#).unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); let exports = module.exported_function_names(Some("b")); assert_eq!(exports, HashSet::new()); @@ -170,7 +155,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); let exports = module.exported_function_names(Some("b")); assert_eq!( exports, @@ -181,7 +166,8 @@ mod tests { #[test] fn exported_function_names_works_for_wasmer_with_no_prefix() { let wasm = wat::parse_str(r#"(module)"#).unwrap(); - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let compiler = Cranelift::default(); + let store = Store::new(compiler); let module = wasmer::Module::new(&store, wasm).unwrap(); let exports = module.exported_function_names(None); assert_eq!(exports, HashSet::new()); @@ -198,7 +184,8 @@ mod tests { )"#, ) .unwrap(); - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let compiler = Cranelift::default(); + let store = Store::new(compiler); let module = wasmer::Module::new(&store, wasm).unwrap(); let exports = module.exported_function_names(None); assert_eq!( @@ -210,7 +197,8 @@ mod tests { #[test] fn exported_function_names_works_for_wasmer_with_prefix() { let wasm = wat::parse_str(r#"(module)"#).unwrap(); - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let compiler = Cranelift::default(); + let store = Store::new(compiler); let module = wasmer::Module::new(&store, wasm).unwrap(); let exports = module.exported_function_names(Some("b")); assert_eq!(exports, HashSet::new()); @@ -228,7 +216,8 @@ mod tests { )"#, ) .unwrap(); - let store = Store::new(&Universal::new(Cranelift::default()).engine()); + let compiler = Cranelift::default(); + let store = Store::new(compiler); let module = wasmer::Module::new(&store, wasm).unwrap(); let exports = module.exported_function_names(Some("b")); assert_eq!( @@ -254,7 +243,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); assert!(!has_ibc_entry_points(&module)); // IBC contract @@ -279,7 +268,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); assert!(has_ibc_entry_points(&module)); // Missing packet ack @@ -303,7 +292,7 @@ mod tests { )"#, ) .unwrap(); - let module = deserialize_wasm(&wasm).unwrap(); + let module = ParsedWasm::parse(&wasm).unwrap(); assert!(!has_ibc_entry_points(&module)); } } diff --git a/packages/vm/src/testing/contract.rs b/packages/vm/src/testing/contract.rs index 3117a405d..f80c3585c 100644 --- a/packages/vm/src/testing/contract.rs +++ b/packages/vm/src/testing/contract.rs @@ -1,10 +1,10 @@ -use wasmer::Module; +use wasmer::{Engine, Module, Store}; use crate::backend::{Backend, Storage}; use crate::compatibility::check_wasm; use crate::instance::Instance; use crate::size::Size; -use crate::wasm_backend::compile; +use crate::wasm_backend::{compile, make_compiling_engine}; use super::instance::MockInstanceOptions; use super::mock::MockApi; @@ -12,15 +12,22 @@ use super::querier::MockQuerier; use super::result::{TestingError, TestingResult}; use super::storage::MockStorage; +/// This is Contract type for testing. +/// +/// the engine and module need to correspond one-to-one. +/// See: https://github.com/CosmWasm/cosmwasm/pull/1753 #[derive(Clone)] pub struct Contract { + engine: Engine, module: Module, storage: MockStorage, } /// representing a contract in integration test /// -/// This enables tests instantiate a new instance every time testing call_(instantiate/execute/query/migrate) like actual wasmd's behavior. +/// This enables tests to instantiate a new instance every time, +/// they test call_(instantiate/execute/query/migrate), +/// similar to the actual behavior of wasmd. /// This is like Cache but it is for single contract and cannot save data in disk. impl Contract { pub fn from_code( @@ -29,15 +36,23 @@ impl Contract { memory_limit: Option, ) -> TestingResult { check_wasm(wasm, &options.available_capabilities)?; - let module = compile(wasm, memory_limit, &[])?; + let engine = make_compiling_engine(memory_limit); + let module = compile(&engine, wasm)?; let storage = MockStorage::new(); - let contract = Self { module, storage }; + let contract = Self { + engine, + module, + storage, + }; Ok(contract) } /// change the wasm code for testing migrate /// /// call this before `generate_instance` for testing `call_migrate`. + /// + /// the engine and module need to correspond one-to-one, + /// and with changes in WASM, both the engine and module are being updated. pub fn change_wasm( &mut self, wasm: &[u8], @@ -45,7 +60,9 @@ impl Contract { memory_limit: Option, ) -> TestingResult<()> { check_wasm(wasm, &options.available_capabilities)?; - let module = compile(wasm, memory_limit, &[])?; + let engine = make_compiling_engine(memory_limit); + let module = compile(&engine, wasm)?; + self.engine = engine; self.module = module; Ok(()) } @@ -63,7 +80,9 @@ impl Contract { storage, querier, }; + let store = Store::new(self.engine.clone()); let instance = Instance::from_module( + store, &self.module, backend, options.gas_limit, @@ -103,9 +122,9 @@ mod test { use cosmwasm_std::{QueryResponse, Response}; static CONTRACT_WITHOUT_MIGRATE: &[u8] = - include_bytes!("../../testdata/queue_1.0.0_without_migrate.wasm"); + include_bytes!("../../testdata/queue_1.4.0_without_migrate.wasm"); static CONTRACT_WITH_MIGRATE: &[u8] = - include_bytes!("../../testdata/queue_1.0.0_with_migrate.wasm"); + include_bytes!("../../testdata/queue_1.4.0_with_migrate.wasm"); #[test] fn test_sanity_integration_test_flow() { diff --git a/packages/vm/src/testing/instance.rs b/packages/vm/src/testing/instance.rs index 6311c10a6..ce1ba84c0 100644 --- a/packages/vm/src/testing/instance.rs +++ b/packages/vm/src/testing/instance.rs @@ -98,7 +98,9 @@ pub struct MockInstanceOptions<'a> { impl MockInstanceOptions<'_> { fn default_capabilities() -> HashSet { #[allow(unused_mut)] - let mut out = capabilities_from_csv("iterator,staking,cosmwasm_1_1"); + let mut out = capabilities_from_csv( + "iterator,staking,cosmwasm_1_1,cosmwasm_1_2,cosmwasm_1_3,cosmwasm_1_4", + ); #[cfg(feature = "stargate")] out.insert("stargate".to_string()); out @@ -192,8 +194,7 @@ where let wasm_data = instance.read_memory(wasm_ptr, size).expect("error reading"); assert_eq!( original, wasm_data, - "failed for size {}; expected: {:?}; actual: {:?}", - size, original, wasm_data + "failed for size {size}; expected: {original:?}; actual: {wasm_data:?}" ); instance .deallocate(wasm_ptr) diff --git a/packages/vm/src/testing/mock.rs b/packages/vm/src/testing/mock.rs index 3f329fb17..295ca8a60 100644 --- a/packages/vm/src/testing/mock.rs +++ b/packages/vm/src/testing/mock.rs @@ -33,12 +33,14 @@ pub fn mock_backend_with_balances( } } -/// Length of canonical addresses created with this API. Contracts should not make any assumtions +/// Length of canonical addresses created with this API. Contracts should not make any assumptions /// what this value is. +/// /// The value here must be restorable with `SHUFFLES_ENCODE` + `SHUFFLES_DECODE` in-shuffles. -const CANONICAL_LENGTH: usize = 54; +/// See for a table of those values. +const CANONICAL_LENGTH: usize = 64; // n = 32 -const SHUFFLES_ENCODE: usize = 18; +const SHUFFLES_ENCODE: usize = 10; const SHUFFLES_DECODE: usize = 2; /// Zero-pads all human addresses to make them fit the canonical_length and @@ -46,7 +48,7 @@ const SHUFFLES_DECODE: usize = 2; /// This is not really smart, but allows us to see a difference (and consistent length for canonical adddresses). #[derive(Copy, Clone)] pub struct MockApi { - /// Length of canonical addresses created with this API. Contracts should not make any assumtions + /// Length of canonical addresses created with this API. Contracts should not make any assumptions /// what this value is. canonical_length: usize, /// `canonicalize_cost` is consumed gas value when the contract all api `canonical_address` @@ -113,18 +115,20 @@ impl BackendApi for MockApi { } // Dummy input validation. This is more sophisticated for formats like bech32, where format and checksum are validated. - if normalized.len() < 3 { + let min_length = 3; + let max_length = self.canonical_length; + if normalized.len() < min_length { return ( Err(BackendError::user_err( - "Invalid input: human address too short", + format!("Invalid input: human address too short for this mock implementation (must be >= {min_length})."), )), gas_info, ); } - if normalized.len() > self.canonical_length { + if normalized.len() > max_length { return ( Err(BackendError::user_err( - "Invalid input: human address too long", + format!("Invalid input: human address too long for this mock implementation (must be <= {max_length})."), )), gas_info, ); @@ -254,6 +258,13 @@ mod test { let canonical = api.canonical_address(&original).0.unwrap(); let recovered = api.human_address(&canonical).0.unwrap(); assert_eq!(recovered, "cosmwasmchef"); + + // Long input (Juno contract address) + let original = + String::from("juno1v82su97skv6ucfqvuvswe0t5fph7pfsrtraxf0x33d8ylj5qnrysdvkc95"); + let canonical = api.canonical_address(&original).0.unwrap(); + let recovered = api.human_address(&canonical).0.unwrap(); + assert_eq!(recovered, original); } #[test] @@ -263,7 +274,7 @@ mod test { let (result, _gas_info) = api.human_address(&input); match result.unwrap_err() { BackendError::UserErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } @@ -272,8 +283,8 @@ mod test { let api = MockApi::default(); let human = "1"; match api.canonical_address(human).0.unwrap_err() { - BackendError::UserErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + BackendError::UserErr { msg } => assert!(msg.contains("too short")), + err => panic!("Unexpected error: {err:?}"), } } @@ -282,8 +293,8 @@ mod test { let api = MockApi::default(); let human = "longer-than-the-address-length-supported-by-this-api-longer-than-54"; match api.canonical_address(human).0.unwrap_err() { - BackendError::UserErr { .. } => {} - err => panic!("Unexpected error: {:?}", err), + BackendError::UserErr { msg } => assert!(msg.contains("too long")), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/packages/vm/src/testing/querier.rs b/packages/vm/src/testing/querier.rs index fafc202bd..e35217862 100644 --- a/packages/vm/src/testing/querier.rs +++ b/packages/vm/src/testing/querier.rs @@ -26,7 +26,7 @@ impl MockQuerier { } } - // set a new balance for the given address and return the old balance + /// Set a new balance for the given address and return the old balance pub fn update_balance( &mut self, addr: impl Into, @@ -100,7 +100,7 @@ impl MockQuerier { let gas_info = GasInfo::with_externally_used(err.to_string().len() as u64); return ( Ok(SystemResult::Err(SystemError::InvalidRequest { - error: format!("Serializing query request: {}", err), + error: format!("Serializing query request: {err}"), request: b"N/A".into(), })), gas_info, @@ -128,7 +128,7 @@ mod tests { let (result, _gas_info) = querier.query_raw(b"broken request", gas_limit); match result.unwrap_err() { BackendError::OutOfGas {} => {} - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } diff --git a/packages/vm/src/wasm_backend/compile.rs b/packages/vm/src/wasm_backend/compile.rs index a75099767..38fd4966d 100644 --- a/packages/vm/src/wasm_backend/compile.rs +++ b/packages/vm/src/wasm_backend/compile.rs @@ -1,35 +1,24 @@ -use std::sync::Arc; - -use wasmer::{Module, ModuleMiddleware}; +use wasmer::{Engine, Module}; use crate::errors::VmResult; -use crate::size::Size; - -use super::store::make_compile_time_store; /// Compiles a given Wasm bytecode into a module. -/// The given memory limit (in bytes) is used when memories are created. -/// If no memory limit is passed, the resulting compiled module should -/// not be used for execution. -pub fn compile( - code: &[u8], - memory_limit: Option, - middlewares: &[Arc], -) -> VmResult { - let store = make_compile_time_store(memory_limit, middlewares); - let module = Module::new(&store, code)?; +pub fn compile(engine: &Engine, code: &[u8]) -> VmResult { + let module = Module::new(&engine, code)?; Ok(module) } #[cfg(test)] mod tests { use super::*; + use crate::wasm_backend::make_compiling_engine; static CONTRACT: &[u8] = include_bytes!("../../testdata/floaty.wasm"); #[test] fn contract_with_floats_fails_check() { - let err = compile(CONTRACT, None, &[]).unwrap_err(); + let engine = make_compiling_engine(None); + let err = compile(&engine, CONTRACT).unwrap_err(); assert!(err.to_string().contains("Float operator detected:")); } } diff --git a/packages/vm/src/wasm_backend/engine.rs b/packages/vm/src/wasm_backend/engine.rs new file mode 100644 index 000000000..0761e5968 --- /dev/null +++ b/packages/vm/src/wasm_backend/engine.rs @@ -0,0 +1,101 @@ +use std::sync::Arc; +#[cfg(feature = "cranelift")] +use wasmer::Cranelift; +use wasmer::NativeEngineExt; +#[cfg(not(feature = "cranelift"))] +use wasmer::Singlepass; +use wasmer::{ + wasmparser::Operator, BaseTunables, CompilerConfig, Engine, Pages, Target, WASM_PAGE_SIZE, +}; +use wasmer_middlewares::Metering; + +use crate::size::Size; + +use super::gatekeeper::Gatekeeper; +use super::limiting_tunables::LimitingTunables; + +/// WebAssembly linear memory objects have sizes measured in pages. Each page +/// is 65536 (2^16) bytes. In WebAssembly version 1, a linear memory can have at +/// most 65536 pages, for a total of 2^32 bytes (4 gibibytes). +/// https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md +const MAX_WASM_PAGES: u32 = 65536; + +fn cost(_operator: &Operator) -> u64 { + // A flat fee for each operation + // The target is 1 Teragas per millisecond (see GAS.md). + // + // In https://github.com/CosmWasm/cosmwasm/pull/1042 a profiler is developed to + // identify runtime differences between different Wasm operation, but this is not yet + // precise enough to derive insights from it. + 150_000 +} + +/// Creates an engine without a compiler. +/// This is used to run modules compiled before. +pub fn make_runtime_engine(memory_limit: Option) -> Engine { + let mut engine = Engine::headless(); + if let Some(limit) = memory_limit { + let base = BaseTunables::for_target(&Target::default()); + let tunables = LimitingTunables::new(base, limit_to_pages(limit)); + engine.set_tunables(tunables); + } + engine +} + +/// Creates an Engine with a compiler attached. Use this when compiling Wasm to a module. +pub fn make_compiling_engine(memory_limit: Option) -> Engine { + let gas_limit = 0; + let deterministic = Arc::new(Gatekeeper::default()); + let metering = Arc::new(Metering::new(gas_limit, cost)); + + #[cfg(feature = "cranelift")] + let mut compiler = Cranelift::default(); + + #[cfg(not(feature = "cranelift"))] + let mut compiler = Singlepass::default(); + + compiler.push_middleware(deterministic); + compiler.push_middleware(metering); + let mut engine = Engine::from(compiler); + if let Some(limit) = memory_limit { + let base = BaseTunables::for_target(&Target::default()); + let tunables = LimitingTunables::new(base, limit_to_pages(limit)); + engine.set_tunables(tunables); + } + engine +} + +fn limit_to_pages(limit: Size) -> Pages { + // round down to ensure the limit is less than or equal to the config + let limit_in_pages: usize = limit.0 / WASM_PAGE_SIZE; + + let capped = match u32::try_from(limit_in_pages) { + Ok(x) => std::cmp::min(x, MAX_WASM_PAGES), + // The only case where TryFromIntError can happen is when + // limit_in_pages exceeds the u32 range. In this case it is way + // larger than MAX_WASM_PAGES and needs to be capped. + Err(_too_large) => MAX_WASM_PAGES, + }; + Pages(capped) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn limit_to_pages_works() { + // rounds down + assert_eq!(limit_to_pages(Size(0)), Pages(0)); + assert_eq!(limit_to_pages(Size(1)), Pages(0)); + assert_eq!(limit_to_pages(Size::kibi(63)), Pages(0)); + assert_eq!(limit_to_pages(Size::kibi(64)), Pages(1)); + assert_eq!(limit_to_pages(Size::kibi(65)), Pages(1)); + assert_eq!(limit_to_pages(Size(u32::MAX as usize)), Pages(65535)); + // caps at 4 GiB + assert_eq!(limit_to_pages(Size::gibi(3)), Pages(49152)); + assert_eq!(limit_to_pages(Size::gibi(4)), Pages(65536)); + assert_eq!(limit_to_pages(Size::gibi(5)), Pages(65536)); + assert_eq!(limit_to_pages(Size(usize::MAX)), Pages(65536)); + } +} diff --git a/packages/vm/src/wasm_backend/gatekeeper.rs b/packages/vm/src/wasm_backend/gatekeeper.rs index c5c82efaf..42cbc4b3f 100644 --- a/packages/vm/src/wasm_backend/gatekeeper.rs +++ b/packages/vm/src/wasm_backend/gatekeeper.rs @@ -1,11 +1,10 @@ -use loupe::MemoryUsage; use wasmer::wasmparser::Operator; use wasmer::{ FunctionMiddleware, LocalFunctionIndex, MiddlewareError, MiddlewareReaderState, ModuleMiddleware, }; -#[derive(Debug, MemoryUsage, Clone, Copy)] +#[derive(Debug, Clone, Copy)] struct GatekeeperConfig { /// True iff float operations are allowed. /// @@ -39,7 +38,7 @@ struct GatekeeperConfig { /// A middleware that ensures only deterministic operations are used (i.e. no floats). /// It also disallows the use of Wasm features that are not explicitly enabled. -#[derive(Debug, MemoryUsage)] +#[derive(Debug)] #[non_exhaustive] pub struct Gatekeeper { config: GatekeeperConfig, @@ -199,13 +198,17 @@ impl FunctionMiddleware for FunctionGatekeeper { | Operator::I64Rotl | Operator::I64Rotr | Operator::I32WrapI64 + // Those are part of the MVP + // https://github.com/bytecodealliance/wasm-tools/blob/wasmparser-0.107.0/crates/wasmparser/src/lib.rs#L287-L288 + | Operator::I64ExtendI32S + | Operator::I64ExtendI32U + // Sign-extension + // https://github.com/bytecodealliance/wasm-tools/blob/wasmparser-0.107.0/crates/wasmparser/src/lib.rs#L307-L311 | Operator::I32Extend8S | Operator::I32Extend16S | Operator::I64Extend8S | Operator::I64Extend16S - | Operator::I64ExtendI32S - | Operator::I64Extend32S - | Operator::I64ExtendI32U => { + | Operator::I64Extend32S => { state.push_operator(operator); Ok(()) } @@ -223,7 +226,7 @@ impl FunctionMiddleware for FunctionGatekeeper { state.push_operator(operator); Ok(()) } else { - let msg = format!("Reference type operation detected: {:?}. Reference types are not supported.", operator); + let msg = format!("Reference type operation detected: {operator:?}. Reference types are not supported."); Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) } } @@ -298,7 +301,7 @@ impl FunctionMiddleware for FunctionGatekeeper { state.push_operator(operator); Ok(()) } else { - let msg = format!("Threads operator detected: {:?}. The Wasm Threads extension is not supported.", operator); + let msg = format!("Threads operator detected: {operator:?}. The Wasm Threads extension is not supported."); Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) } } @@ -439,8 +442,6 @@ impl FunctionMiddleware for FunctionGatekeeper { | Operator::V128Load16x4U { .. } | Operator::V128Load32x2S { .. } | Operator::V128Load32x2U { .. } - | Operator::I8x16RoundingAverageU - | Operator::I16x8RoundingAverageU | Operator::V128Load8Lane { .. } | Operator::V128Load16Lane { .. } | Operator::V128Load32Lane { .. } @@ -456,6 +457,7 @@ impl FunctionMiddleware for FunctionGatekeeper { | Operator::I64x2LeS | Operator::I64x2GeS | Operator::I8x16Popcnt + | Operator::I16x8AvgrU | Operator::I16x8ExtAddPairwiseI8x16S | Operator::I16x8ExtAddPairwiseI8x16U | Operator::I16x8Q15MulrSatS @@ -486,26 +488,44 @@ impl FunctionMiddleware for FunctionGatekeeper { | Operator::F64x2ConvertLowI32x4U | Operator::F32x4DemoteF64x2Zero | Operator::F64x2PromoteLowF32x4 - | Operator::I8x16RelaxedSwizzle - | Operator::I32x4RelaxedTruncSatF32x4S - | Operator::I32x4RelaxedTruncSatF32x4U - | Operator::I32x4RelaxedTruncSatF64x2SZero - | Operator::I32x4RelaxedTruncSatF64x2UZero - | Operator::I8x16LaneSelect - | Operator::I16x8LaneSelect - | Operator::I32x4LaneSelect - | Operator::I64x2LaneSelect => { + | Operator::I8x16AvgrU => { if self.config.allow_feature_simd { state.push_operator(operator); Ok(()) } else { let msg = format!( - "SIMD operator detected: {:?}. The Wasm SIMD extension is not supported.", - operator + "SIMD operator detected: {operator:?}. The Wasm SIMD extension is not supported." ); Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) } } + // Relaxed SIMD operators + Operator::I8x16RelaxedSwizzle + | Operator::I32x4RelaxedTruncSatF32x4S + | Operator::I32x4RelaxedTruncSatF32x4U + | Operator::I32x4RelaxedTruncSatF64x2SZero + | Operator::I32x4RelaxedTruncSatF64x2UZero + | Operator::F32x4RelaxedFma + | Operator::F32x4RelaxedFnma + | Operator::F64x2RelaxedFma + | Operator::F64x2RelaxedFnma + | Operator::I8x16RelaxedLaneselect + | Operator::I16x8RelaxedLaneselect + | Operator::I32x4RelaxedLaneselect + | Operator::I64x2RelaxedLaneselect + | Operator::F32x4RelaxedMin + | Operator::F32x4RelaxedMax + | Operator::F64x2RelaxedMin + | Operator::F64x2RelaxedMax + | Operator::I16x8RelaxedQ15mulrS + | Operator::I16x8DotI8x16I7x16S + | Operator::I32x4DotI8x16I7x16AddS + | Operator::F32x4RelaxedDotBf16x8AddF32x4 => { + let msg = format!( + "Relaxed SIMD operator detected: {operator:?}. The Wasm Relaxed SIMD extension is not supported." + ); + Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) + } Operator::F32Load { .. } | Operator::F64Load { .. } | Operator::F32Store { .. } @@ -633,22 +653,13 @@ impl FunctionMiddleware for FunctionGatekeeper { | Operator::I32x4TruncSatF32x4S | Operator::I32x4TruncSatF32x4U | Operator::F32x4ConvertI32x4S - | Operator::F32x4ConvertI32x4U - | Operator::F32x4RelaxedMin - | Operator::F32x4RelaxedMax - | Operator::F64x2RelaxedMin - | Operator::F64x2RelaxedMax - | Operator::F32x4Fma - | Operator::F32x4Fms - | Operator::F64x2Fma - | Operator::F64x2Fms => { + | Operator::F32x4ConvertI32x4U => { if self.config.allow_floats { state.push_operator(operator); Ok(()) } else { let msg = format!( - "Float operator detected: {:?}. The use of floats is not supported.", - operator + "Float operator detected: {operator:?}. The use of floats is not supported." ); Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) } @@ -665,7 +676,7 @@ impl FunctionMiddleware for FunctionGatekeeper { state.push_operator(operator); Ok(()) } else { - let msg = format!("Bulk memory operation detected: {:?}. Bulk memory operations are not supported.", operator); + let msg = format!("Bulk memory operation detected: {operator:?}. Bulk memory operations are not supported."); Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) } } @@ -679,7 +690,7 @@ impl FunctionMiddleware for FunctionGatekeeper { state.push_operator(operator); Ok(()) } else { - let msg = format!("Exception handling operation detected: {:?}. Exception handling is not supported.", operator); + let msg = format!("Exception handling operation detected: {operator:?}. Exception handling is not supported."); Err(MiddlewareError::new(MIDDLEWARE_NAME, msg)) } } @@ -691,7 +702,7 @@ impl FunctionMiddleware for FunctionGatekeeper { mod tests { use super::*; use std::sync::Arc; - use wasmer::{CompilerConfig, Cranelift, Module, Store, Universal}; + use wasmer::{CompilerConfig, Cranelift, Module, Store}; #[test] fn valid_wasm_instance_sanity() { @@ -699,8 +710,8 @@ mod tests { r#" (module (func (export "sum") (param i32 i32) (result i32) - get_local 0 - get_local 1 + local.get 0 + local.get 1 i32.add )) "#, @@ -708,10 +719,10 @@ mod tests { .unwrap(); let deterministic = Arc::new(Gatekeeper::default()); - let mut compiler_config = Cranelift::default(); - compiler_config.push_middleware(deterministic); - let store = Store::new(&Universal::new(compiler_config).engine()); - let result = Module::new(&store, &wasm); + let mut compiler = Cranelift::default(); + compiler.push_middleware(deterministic); + let store = Store::new(compiler); + let result = Module::new(&store, wasm); assert!(result.is_ok()); } @@ -721,18 +732,18 @@ mod tests { r#" (module (func $to_float (param i32) (result f32) - get_local 0 - f32.convert_u/i32 + local.get 0 + f32.convert_i32_u )) "#, ) .unwrap(); let deterministic = Arc::new(Gatekeeper::default()); - let mut compiler_config = Cranelift::default(); - compiler_config.push_middleware(deterministic); - let store = Store::new(&Universal::new(compiler_config).engine()); - let result = Module::new(&store, &wasm); + let mut compiler = Cranelift::default(); + compiler.push_middleware(deterministic); + let store = Store::new(compiler); + let result = Module::new(&store, wasm); assert!(result .unwrap_err() .to_string() @@ -756,10 +767,10 @@ mod tests { .unwrap(); let deterministic = Arc::new(Gatekeeper::default()); - let mut compiler_config = Cranelift::default(); - compiler_config.push_middleware(deterministic); - let store = Store::new(&Universal::new(compiler_config).engine()); - let result = Module::new(&store, &wasm); + let mut compiler = Cranelift::default(); + compiler.push_middleware(deterministic); + let store = Store::new(compiler); + let result = Module::new(&store, wasm); assert!(result .unwrap_err() .to_string() diff --git a/packages/vm/src/wasm_backend/limiting_tunables.rs b/packages/vm/src/wasm_backend/limiting_tunables.rs index 007bc34a4..cc476930a 100644 --- a/packages/vm/src/wasm_backend/limiting_tunables.rs +++ b/packages/vm/src/wasm_backend/limiting_tunables.rs @@ -1,9 +1,10 @@ use std::ptr::NonNull; -use std::sync::Arc; -use loupe::MemoryUsage; use wasmer::{ - vm::{self, MemoryError, MemoryStyle, TableStyle, VMMemoryDefinition, VMTableDefinition}, + vm::{ + MemoryError, MemoryStyle, TableStyle, VMMemory, VMMemoryDefinition, VMTable, + VMTableDefinition, + }, MemoryType, Pages, TableType, Tunables, }; @@ -11,7 +12,6 @@ use wasmer::{ /// /// After adjusting the memory limits, it delegates all other logic /// to the base tunables. -#[derive(MemoryUsage)] pub struct LimitingTunables { /// The maxium a linear memory is allowed to be (in Wasm pages, 65 KiB each). /// Since Wasmer ensures there is only none or one memory, this is practically @@ -84,7 +84,7 @@ impl Tunables for LimitingTunables { &self, ty: &MemoryType, style: &MemoryStyle, - ) -> Result, MemoryError> { + ) -> Result { let adjusted = self.adjust_memory(ty); self.validate_memory(&adjusted)?; self.base.create_host_memory(&adjusted, style) @@ -98,7 +98,7 @@ impl Tunables for LimitingTunables { ty: &MemoryType, style: &MemoryStyle, vm_definition_location: NonNull, - ) -> Result, MemoryError> { + ) -> Result { let adjusted = self.adjust_memory(ty); self.validate_memory(&adjusted)?; self.base @@ -108,11 +108,7 @@ impl Tunables for LimitingTunables { /// Create a table owned by the host given a [`TableType`] and a [`TableStyle`]. /// /// Delegated to base. - fn create_host_table( - &self, - ty: &TableType, - style: &TableStyle, - ) -> Result, String> { + fn create_host_table(&self, ty: &TableType, style: &TableStyle) -> Result { self.base.create_host_table(ty, style) } @@ -124,7 +120,7 @@ impl Tunables for LimitingTunables { ty: &TableType, style: &TableStyle, vm_definition_location: NonNull, - ) -> Result, String> { + ) -> Result { self.base.create_vm_table(ty, style, vm_definition_location) } } @@ -190,7 +186,7 @@ mod tests { MemoryError::Generic(msg) => { assert_eq!(msg, "Maximum exceeds the allowed memory limit") } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } // Maximum not set @@ -198,7 +194,7 @@ mod tests { let result = limiting.validate_memory(&memory); match result.unwrap_err() { MemoryError::Generic(msg) => assert_eq!(msg, "Maximum unset"), - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } // Minimum greater than maximum (not our problem) @@ -212,7 +208,7 @@ mod tests { MemoryError::Generic(msg) => { assert_eq!(msg, "Minimum exceeds the allowed memory limit") } - err => panic!("Unexpected error: {:?}", err), + err => panic!("Unexpected error: {err:?}"), } } } diff --git a/packages/vm/src/wasm_backend/mod.rs b/packages/vm/src/wasm_backend/mod.rs index 3e503c1da..59707b8d2 100644 --- a/packages/vm/src/wasm_backend/mod.rs +++ b/packages/vm/src/wasm_backend/mod.rs @@ -1,8 +1,8 @@ mod compile; +mod engine; mod gatekeeper; mod limiting_tunables; -mod store; pub use compile::compile; +pub use engine::{make_compiling_engine, make_runtime_engine}; pub use limiting_tunables::LimitingTunables; -pub use store::make_runtime_store; diff --git a/packages/vm/src/wasm_backend/store.rs b/packages/vm/src/wasm_backend/store.rs deleted file mode 100644 index 570692b59..000000000 --- a/packages/vm/src/wasm_backend/store.rs +++ /dev/null @@ -1,212 +0,0 @@ -use std::sync::Arc; -#[cfg(feature = "cranelift")] -use wasmer::Cranelift; -#[cfg(not(feature = "cranelift"))] -use wasmer::Singlepass; -use wasmer::{ - wasmparser::Operator, BaseTunables, CompilerConfig, Engine, ModuleMiddleware, Pages, Store, - Target, Universal, WASM_PAGE_SIZE, -}; -use wasmer_middlewares::Metering; - -use crate::size::Size; - -use super::gatekeeper::Gatekeeper; -use super::limiting_tunables::LimitingTunables; - -/// WebAssembly linear memory objects have sizes measured in pages. Each page -/// is 65536 (2^16) bytes. In WebAssembly version 1, a linear memory can have at -/// most 65536 pages, for a total of 2^32 bytes (4 gibibytes). -/// https://github.com/WebAssembly/memory64/blob/master/proposals/memory64/Overview.md -const MAX_WASM_PAGES: u32 = 65536; - -fn cost(_operator: &Operator) -> u64 { - // A flat fee for each operation - // The target is 1 Teragas per millisecond (see GAS.md). - // - // In https://github.com/CosmWasm/cosmwasm/pull/1042 a profiler is developed to - // identify runtime differences between different Wasm operation, but this is not yet - // precise enough to derive insights from it. - 150_000 -} - -/// Created a store with the default compiler and the given memory limit (in bytes). -/// If memory_limit is None, no limit is applied. -pub fn make_compile_time_store( - memory_limit: Option, - middlewares: &[Arc], -) -> Store { - let gas_limit = 0; - let deterministic = Arc::new(Gatekeeper::default()); - let metering = Arc::new(Metering::new(gas_limit, cost)); - - #[cfg(feature = "cranelift")] - { - let mut config = Cranelift::default(); - for middleware in middlewares { - config.push_middleware(middleware.clone()); - } - config.push_middleware(deterministic); - config.push_middleware(metering); - let engine = Universal::new(config).engine(); - make_store_with_engine(&engine, memory_limit) - } - - #[cfg(not(feature = "cranelift"))] - { - let mut config = Singlepass::default(); - for middleware in middlewares { - config.push_middleware(middleware.clone()); - } - config.push_middleware(deterministic); - config.push_middleware(metering); - let engine = Universal::new(config).engine(); - make_store_with_engine(&engine, memory_limit) - } -} - -/// Created a store with no compiler and the given memory limit (in bytes) -/// If memory_limit is None, no limit is applied. -pub fn make_runtime_store(memory_limit: Option) -> Store { - let engine = Universal::headless().engine(); - make_store_with_engine(&engine, memory_limit) -} - -/// Creates a store from an engine and an optional memory limit. -/// If no limit is set, the no custom tunables will be used. -fn make_store_with_engine(engine: &dyn Engine, memory_limit: Option) -> Store { - match memory_limit { - Some(limit) => { - let base = BaseTunables::for_target(&Target::default()); - let tunables = LimitingTunables::new(base, limit_to_pages(limit)); - Store::new_with_tunables(engine, tunables) - } - None => Store::new(engine), - } -} - -fn limit_to_pages(limit: Size) -> Pages { - // round down to ensure the limit is less than or equal to the config - let limit_in_pages: usize = limit.0 / WASM_PAGE_SIZE; - - let capped = match u32::try_from(limit_in_pages) { - Ok(x) => std::cmp::min(x, MAX_WASM_PAGES), - // The only case where TryFromIntError can happen is when - // limit_in_pages exceeds the u32 range. In this case it is way - // larger than MAX_WASM_PAGES and needs to be capped. - Err(_too_large) => MAX_WASM_PAGES, - }; - Pages(capped) -} - -#[cfg(test)] -mod tests { - use super::*; - use wasmer::{ImportObject, Instance, Memory, Module}; - - /// A Wasm module with an exported memory (min: 4 pages, max: none) - const EXPORTED_MEMORY_WAT: &str = r#"(module - (memory 4) - (export "memory" (memory 0)) - )"#; - - #[test] - fn limit_to_pages_works() { - // rounds down - assert_eq!(limit_to_pages(Size(0)), Pages(0)); - assert_eq!(limit_to_pages(Size(1)), Pages(0)); - assert_eq!(limit_to_pages(Size::kibi(63)), Pages(0)); - assert_eq!(limit_to_pages(Size::kibi(64)), Pages(1)); - assert_eq!(limit_to_pages(Size::kibi(65)), Pages(1)); - assert_eq!(limit_to_pages(Size(u32::MAX as usize)), Pages(65535)); - // caps at 4 GiB - assert_eq!(limit_to_pages(Size::gibi(3)), Pages(49152)); - assert_eq!(limit_to_pages(Size::gibi(4)), Pages(65536)); - assert_eq!(limit_to_pages(Size::gibi(5)), Pages(65536)); - assert_eq!(limit_to_pages(Size(usize::MAX)), Pages(65536)); - } - - #[test] - fn make_compile_time_store_applies_memory_limit() { - let wasm = wat::parse_str(EXPORTED_MEMORY_WAT).unwrap(); - - // No limit - let store = make_compile_time_store(None, &[]); - let module = Module::new(&store, &wasm).unwrap(); - let module_memory = module.info().memories.last().unwrap(); - assert_eq!(module_memory.minimum, Pages(4)); - assert_eq!(module_memory.maximum, None); - let instance = Instance::new(&module, &ImportObject::new()).unwrap(); - let instance_memory: Memory = instance - .exports - .iter() - .memories() - .map(|pair| pair.1.clone()) - .next() - .unwrap(); - assert_eq!(instance_memory.ty().minimum, Pages(4)); - assert_eq!(instance_memory.ty().maximum, None); - - // Set limit - let store = make_compile_time_store(Some(Size::kibi(23 * 64)), &[]); - let module = Module::new(&store, &wasm).unwrap(); - let module_memory = module.info().memories.last().unwrap(); - assert_eq!(module_memory.minimum, Pages(4)); - assert_eq!(module_memory.maximum, None); - let instance = Instance::new(&module, &ImportObject::new()).unwrap(); - let instance_memory: Memory = instance - .exports - .iter() - .memories() - .map(|pair| pair.1.clone()) - .next() - .unwrap(); - assert_eq!(instance_memory.ty().minimum, Pages(4)); - assert_eq!(instance_memory.ty().maximum, Some(Pages(23))); - } - - #[test] - fn make_runtime_store_applies_memory_limit() { - // Compile - let serialized = { - let wasm = wat::parse_str(EXPORTED_MEMORY_WAT).unwrap(); - let store = make_compile_time_store(None, &[]); - let module = Module::new(&store, &wasm).unwrap(); - module.serialize().unwrap() - }; - - // No limit - let store = make_runtime_store(None); - let module = unsafe { Module::deserialize(&store, &serialized) }.unwrap(); - let module_memory = module.info().memories.last().unwrap(); - assert_eq!(module_memory.minimum, Pages(4)); - assert_eq!(module_memory.maximum, None); - let instance = Instance::new(&module, &ImportObject::new()).unwrap(); - let instance_memory: Memory = instance - .exports - .iter() - .memories() - .map(|pair| pair.1.clone()) - .next() - .unwrap(); - assert_eq!(instance_memory.ty().minimum, Pages(4)); - assert_eq!(instance_memory.ty().maximum, None); - - // Instantiate with limit - let store = make_runtime_store(Some(Size::kibi(23 * 64))); - let module = unsafe { Module::deserialize(&store, &serialized) }.unwrap(); - let module_memory = module.info().memories.last().unwrap(); - assert_eq!(module_memory.minimum, Pages(4)); - assert_eq!(module_memory.maximum, None); - let instance = Instance::new(&module, &ImportObject::new()).unwrap(); - let instance_memory: Memory = instance - .exports - .iter() - .memories() - .map(|pair| pair.1.clone()) - .next() - .unwrap(); - assert_eq!(instance_memory.ty().minimum, Pages(4)); - assert_eq!(instance_memory.ty().maximum, Some(Pages(23))); - } -} diff --git a/packages/vm/testdata/cyberpunk.wasm b/packages/vm/testdata/cyberpunk.wasm new file mode 100644 index 000000000..68aa44257 Binary files /dev/null and b/packages/vm/testdata/cyberpunk.wasm differ diff --git a/packages/vm/testdata/cyberpunk_rust170.wasm b/packages/vm/testdata/cyberpunk_rust170.wasm new file mode 100755 index 000000000..3bd0b471c Binary files /dev/null and b/packages/vm/testdata/cyberpunk_rust170.wasm differ diff --git a/packages/vm/testdata/floaty.wasm b/packages/vm/testdata/floaty.wasm index 8ae4d6a31..76b5ee18c 120000 --- a/packages/vm/testdata/floaty.wasm +++ b/packages/vm/testdata/floaty.wasm @@ -1 +1 @@ -floaty_1.0.wasm \ No newline at end of file +floaty_1.2.wasm \ No newline at end of file diff --git a/packages/vm/testdata/floaty_1.2.wasm b/packages/vm/testdata/floaty_1.2.wasm new file mode 100644 index 000000000..653c3e884 Binary files /dev/null and b/packages/vm/testdata/floaty_1.2.wasm differ diff --git a/packages/vm/testdata/hackatom.wasm b/packages/vm/testdata/hackatom.wasm index 76495bcd7..c7941a1a8 120000 --- a/packages/vm/testdata/hackatom.wasm +++ b/packages/vm/testdata/hackatom.wasm @@ -1 +1 @@ -hackatom_1.0.wasm \ No newline at end of file +hackatom_1.2.wasm \ No newline at end of file diff --git a/packages/vm/testdata/hackatom_1.2.wasm b/packages/vm/testdata/hackatom_1.2.wasm new file mode 100644 index 000000000..f15360139 Binary files /dev/null and b/packages/vm/testdata/hackatom_1.2.wasm differ diff --git a/packages/vm/testdata/ibc_reflect.wasm b/packages/vm/testdata/ibc_reflect.wasm index c5b6708f3..b2876f314 120000 --- a/packages/vm/testdata/ibc_reflect.wasm +++ b/packages/vm/testdata/ibc_reflect.wasm @@ -1 +1 @@ -ibc_reflect_1.0.wasm \ No newline at end of file +ibc_reflect_1.2.wasm \ No newline at end of file diff --git a/packages/vm/testdata/ibc_reflect_1.2.wasm b/packages/vm/testdata/ibc_reflect_1.2.wasm new file mode 100644 index 000000000..228bdfbff Binary files /dev/null and b/packages/vm/testdata/ibc_reflect_1.2.wasm differ diff --git a/packages/vm/testdata/queue_1.4.0_with_migrate.wasm b/packages/vm/testdata/queue_1.4.0_with_migrate.wasm new file mode 100644 index 000000000..f18edc7c5 Binary files /dev/null and b/packages/vm/testdata/queue_1.4.0_with_migrate.wasm differ diff --git a/packages/vm/testdata/queue_1.4.0_without_migrate.wasm b/packages/vm/testdata/queue_1.4.0_without_migrate.wasm new file mode 100644 index 000000000..f18edc7c5 Binary files /dev/null and b/packages/vm/testdata/queue_1.4.0_without_migrate.wasm differ